From f10c85fbc336f6908a4f1ecae9fb5ab52984f636 Mon Sep 17 00:00:00 2001 From: Saint Wesonga Date: Tue, 9 Sep 2025 13:13:08 +0000 Subject: [PATCH 001/120] 8367027: java/lang/ProcessBuilder/Basic.java fails on Windows AArch64 Reviewed-by: rriggs --- test/jdk/java/lang/ProcessBuilder/Basic.java | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/lang/ProcessBuilder/Basic.java b/test/jdk/java/lang/ProcessBuilder/Basic.java index c06ecbdb871..551a4869e86 100644 --- a/test/jdk/java/lang/ProcessBuilder/Basic.java +++ b/test/jdk/java/lang/ProcessBuilder/Basic.java @@ -212,7 +212,7 @@ public class Basic { private static String winEnvFilter(String env) { return env.replaceAll("\r", "") - .replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT)=.*\n",""); + .replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT|PROCESSOR_ARCHITECTURE)=.*\n",""); } private static String unixEnvProg() { @@ -811,6 +811,14 @@ public class Basic { return vars.replace("AIXTHREAD_GUARDPAGES=0,", ""); } + /* Only used for Windows AArch64 -- + * Windows AArch64 adds the variable PROCESSOR_ARCHITECTURE=ARM64 to the environment. + * Remove it from the list of env variables + */ + private static String removeWindowsAArch64ExpectedVars(String vars) { + return vars.replace("PROCESSOR_ARCHITECTURE=ARM64,", ""); + } + private static String sortByLinesWindowsly(String text) { String[] lines = text.split("\n"); Arrays.sort(lines, new WindowsComparator()); @@ -1321,6 +1329,9 @@ public class Basic { if (AIX.is()) { result = removeAixExpectedVars(result); } + if (Windows.is() && Platform.isAArch64()) { + result = removeWindowsAArch64ExpectedVars(result); + } equal(result, expected); } catch (Throwable t) { unexpected(t); } @@ -1833,6 +1844,9 @@ public class Basic { if (AIX.is()) { commandOutput = removeAixExpectedVars(commandOutput); } + if (Windows.is() && Platform.isAArch64()) { + commandOutput = removeWindowsAArch64ExpectedVars(commandOutput); + } equal(commandOutput, expected); if (Windows.is()) { ProcessBuilder pb = new ProcessBuilder(childArgs); @@ -1840,7 +1854,11 @@ public class Basic { pb.environment().put("SystemRoot", systemRoot); pb.environment().put("=ExitValue", "3"); pb.environment().put("=C:", "\\"); - equal(commandOutput(pb), expected); + commandOutput = commandOutput(pb); + if (Platform.isAArch64()) { + commandOutput = removeWindowsAArch64ExpectedVars(commandOutput); + } + equal(commandOutput, expected); } } catch (Throwable t) { unexpected(t); } @@ -1892,6 +1910,9 @@ public class Basic { if (AIX.is()) { commandOutput = removeAixExpectedVars(commandOutput); } + if (Windows.is() && Platform.isAArch64()) { + commandOutput = removeWindowsAArch64ExpectedVars(commandOutput); + } check(commandOutput.equals(Windows.is() ? "LC_ALL=C,SystemRoot="+systemRoot+"," : AIX.is() From b653ae92d5941202780873fad1a7cefd51e4e7a8 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 9 Sep 2025 15:02:54 +0000 Subject: [PATCH 002/120] 8367051: Build failure with clang on linux and AIX after switch to C++17 Reviewed-by: dholmes, ayang, mbaesken, mdoerr --- src/hotspot/share/utilities/forbiddenFunctions.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hotspot/share/utilities/forbiddenFunctions.hpp b/src/hotspot/share/utilities/forbiddenFunctions.hpp index a8dcba95a6d..871fff5b727 100644 --- a/src/hotspot/share/utilities/forbiddenFunctions.hpp +++ b/src/hotspot/share/utilities/forbiddenFunctions.hpp @@ -38,6 +38,15 @@ #include #endif +// Workaround for noexcept functions in glibc when using clang. +// clang errors if declaration without exception specification preceeds +// noexcept declaration, but not the other way around. +#ifdef __clang__ +#include +#include +#include +#endif + #ifdef _WINDOWS #include "forbiddenFunctions_windows.hpp" #else From cc6d34b2fa299a68a05e65e25c1f41dffa67c118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Tue, 9 Sep 2025 15:08:30 +0000 Subject: [PATCH 003/120] 8366971: C2: Remove unused nop_list from PhaseOutput::init_buffer Reviewed-by: epeter, dlong --- src/hotspot/cpu/aarch64/aarch64.ad | 3 --- src/hotspot/cpu/arm/arm.ad | 3 --- src/hotspot/cpu/ppc/ppc.ad | 4 ---- src/hotspot/cpu/riscv/riscv.ad | 3 --- src/hotspot/cpu/x86/x86_64.ad | 3 --- src/hotspot/share/adlc/adlparse.cpp | 32 ++--------------------------- src/hotspot/share/adlc/formsopt.cpp | 8 +------- src/hotspot/share/adlc/formsopt.hpp | 5 +---- src/hotspot/share/adlc/output_c.cpp | 14 +------------ src/hotspot/share/adlc/output_h.cpp | 6 ------ src/hotspot/share/opto/output.cpp | 7 +------ 11 files changed, 6 insertions(+), 82 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 33466453b76..e0459716122 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -5965,9 +5965,6 @@ attributes %{ instruction_unit_size = 4; // An instruction is 4 bytes long instruction_fetch_unit_size = 64; // The processor fetches one line instruction_fetch_units = 1; // of 64 bytes - - // List of nop instructions - nops( MachNop ); %} // We don't use an actual pipeline model so don't care about resources diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 3b6faa6c81a..45d51aaac57 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -2638,9 +2638,6 @@ attributes %{ instruction_unit_size = 4; // An instruction is 4 bytes long instruction_fetch_unit_size = 16; // The processor fetches one line instruction_fetch_units = 1; // of 16 bytes - - // List of nop instructions - nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR ); %} //----------RESOURCES---------------------------------------------------------- diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index cd71e298b7d..290369360fc 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -4920,10 +4920,6 @@ attributes %{ // ...in one line instruction_fetch_units = 1 - - // Unused, list one so that array generated by adlc is not empty. - // Aix compiler chokes if _nop_count = 0. - nops(fxNop); %} //----------RESOURCES---------------------------------------------------------- diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index eab19e74f93..0c4dd7b71e2 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -3845,9 +3845,6 @@ attributes %{ // ...in one line. instruction_fetch_units = 1; - - // List of nop instructions - nops( MachNop ); %} // We don't use an actual pipeline model so don't care about resources diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 932dc9e1ca7..0914bea82a1 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -3429,9 +3429,6 @@ attributes %{ instruction_unit_size = 1; // An instruction is 1 bytes long instruction_fetch_unit_size = 16; // The processor fetches one line instruction_fetch_units = 1; // of 16 bytes - - // List of nop instructions - nops( MachNop ); %} //----------RESOURCES---------------------------------------------------------- diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index 033e8d26ca7..15dbf070674 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, 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 @@ -1507,36 +1507,8 @@ void ADLParser::pipe_parse(void) { } if (!strcmp(ident, "nops")) { + parse_err(WARN, "Using obsolete token, nops"); skipws(); - if (_curchar != '(') { - parse_err(SYNERR, "expected `(`, found '%c'\n", _curchar); - break; - } - - next_char(); skipws(); - - while (_curchar != ')') { - ident = get_ident(); - if (ident == nullptr) { - parse_err(SYNERR, "expected identifier for nop instruction, found '%c'\n", _curchar); - break; - } - - pipeline->_noplist.addName(ident); - pipeline->_nopcnt++; - skipws(); - - if (_curchar == ',') { - next_char(); skipws(); - } - } - - next_char(); skipws(); - - if (_curchar == ';') { - next_char(); skipws(); - } - continue; } diff --git a/src/hotspot/share/adlc/formsopt.cpp b/src/hotspot/share/adlc/formsopt.cpp index 5de8974e2c0..01fe6288c53 100644 --- a/src/hotspot/share/adlc/formsopt.cpp +++ b/src/hotspot/share/adlc/formsopt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -511,8 +511,6 @@ PipelineForm::PipelineForm() , _stagecnt (0) , _classlist () , _classcnt (0) - , _noplist () - , _nopcnt (0) , _variableSizeInstrs (false) , _branchHasDelaySlot (false) , _maxInstrsPerBundle (0) @@ -533,7 +531,6 @@ void PipelineForm::output(FILE *fp) { // Write info to output files const char *res; const char *stage; const char *cls; - const char *nop; int count = 0; fprintf(fp,"\nPipeline:"); @@ -574,9 +571,6 @@ void PipelineForm::output(FILE *fp) { // Write info to output files for ( _classlist.reset(); (cls = _classlist.iter()) != nullptr; ) _classdict[cls]->is_pipeclass()->output(fp); - fprintf(fp,"\nNop Instructions:"); - for ( _noplist.reset(); (nop = _noplist.iter()) != nullptr; ) - fprintf(fp, " \"%s\"", nop); fprintf(fp,"\n"); } diff --git a/src/hotspot/share/adlc/formsopt.hpp b/src/hotspot/share/adlc/formsopt.hpp index d183a46b875..db7b9dbd8d8 100644 --- a/src/hotspot/share/adlc/formsopt.hpp +++ b/src/hotspot/share/adlc/formsopt.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -386,9 +386,6 @@ public: FormDict _classdict; // Class Name -> PipeClassForm mapping int _classcnt; // Number of classes - NameList _noplist; // List of NOP instructions - int _nopcnt; // Number of nop instructions - bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index 0620f2f4496..abebf39a2b2 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp @@ -977,18 +977,6 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) { } fprintf(fp_cpp, "}\n\n"); - // Output the list of nop nodes - fprintf(fp_cpp, "// Descriptions for emitting different functional unit nops\n"); - const char *nop; - int nopcnt = 0; - for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != nullptr; nopcnt++ ); - - fprintf(fp_cpp, "void Bundle::initialize_nops(MachNode * nop_list[%d]) {\n", nopcnt); - int i = 0; - for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != nullptr; i++ ) { - fprintf(fp_cpp, " nop_list[%d] = (MachNode *) new %sNode();\n", i, nop); - } - fprintf(fp_cpp, "};\n\n"); fprintf(fp_cpp, "#ifndef PRODUCT\n"); fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n"); fprintf(fp_cpp, " static const char * bundle_flags[] = {\n"); @@ -1004,7 +992,7 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) { fprintf(fp_cpp, " static const char *resource_names[%d] = {", _pipeline->_rescount); // Don't add compound resources to the list of resource names const char* resource; - i = 0; + int i = 0; for (_pipeline->_reslist.reset(); (resource = _pipeline->_reslist.iter()) != nullptr;) { if (_pipeline->_resdict[resource]->is_resource()->is_discrete()) { fprintf(fp_cpp, " \"%s\"%c", resource, i < _pipeline->_rescount - 1 ? ',' : ' '); diff --git a/src/hotspot/share/adlc/output_h.cpp b/src/hotspot/share/adlc/output_h.cpp index cbcc00efa3b..78cf5ea7988 100644 --- a/src/hotspot/share/adlc/output_h.cpp +++ b/src/hotspot/share/adlc/output_h.cpp @@ -1115,12 +1115,6 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { fprintf(fp_hpp, " bool use_delay() { return ((_flags & _use_delay) != 0); }\n"); fprintf(fp_hpp, " bool used_in_delay() { return ((_flags & _used_in_delay) != 0); }\n\n"); - fprintf(fp_hpp, " enum {\n"); - fprintf(fp_hpp, " _nop_count = %d\n", - _pipeline->_nopcnt); - fprintf(fp_hpp, " };\n\n"); - fprintf(fp_hpp, " static void initialize_nops(MachNode *nop_list[%d]);\n\n", - _pipeline->_nopcnt); fprintf(fp_hpp, "#ifndef PRODUCT\n"); fprintf(fp_hpp, " void dump(outputStream *st = tty) const;\n"); fprintf(fp_hpp, "#endif\n"); diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 124b00a6549..9a6970ebf20 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -1399,10 +1399,6 @@ CodeBuffer* PhaseOutput::init_buffer() { cb->initialize_stubs_size(stub_req); cb->initialize_oop_recorder(C->env()->oop_recorder()); - // fill in the nop array for bundling computations - MachNode *_nop_list[Bundle::_nop_count]; - Bundle::initialize_nops(_nop_list); - return cb; } @@ -2062,8 +2058,7 @@ Scheduling::Scheduling(Arena *arena, Compile &compile) // Create a MachNopNode _nop = new MachNopNode(); - // Now that the nops are in the array, save the count - // (but allow entries for the nops) + // Save the count _node_bundling_limit = compile.unique(); uint node_max = _regalloc->node_regs_max_index(); From a12e9fcebda1d7b75cb892e7920333d73fb5de9c Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Tue, 9 Sep 2025 19:37:57 +0000 Subject: [PATCH 004/120] 8366261: Provide utility methods for sun.security.util.Password Reviewed-by: smarks, weijun --- .../share/classes/java/io/Console.java | 26 +++++++++-- .../jdk/internal/access/JavaIOAccess.java | 3 +- .../jdk/internal/io/JdkConsoleImpl.java | 43 ++++++++++++++++++- .../unix/native/libjava/Console_md.c | 19 ++++++-- .../windows/native/libjava/Console_md.c | 27 +++++++----- .../java/io/Console/ModuleSelectionTest.java | 13 +++--- 6 files changed, 106 insertions(+), 25 deletions(-) diff --git a/src/java.base/share/classes/java/io/Console.java b/src/java.base/share/classes/java/io/Console.java index 2878de79718..96df4c5fd24 100644 --- a/src/java.base/share/classes/java/io/Console.java +++ b/src/java.base/share/classes/java/io/Console.java @@ -25,6 +25,7 @@ package java.io; +import java.lang.annotation.Native; import java.util.*; import java.nio.charset.Charset; import jdk.internal.access.JavaIOAccess; @@ -550,7 +551,12 @@ public sealed class Console implements Flushable permits ProxyingConsole { "Console class itself does not provide implementation"); } - private static final boolean istty = istty(); + @Native static final int TTY_STDIN_MASK = 0x00000001; + @Native static final int TTY_STDOUT_MASK = 0x00000002; + @Native static final int TTY_STDERR_MASK = 0x00000004; + // ttyStatus() returns bit patterns above, a bit is set if the corresponding file + // descriptor is a character device + private static final int ttyStatus = ttyStatus(); private static final Charset STDIN_CHARSET = Charset.forName(StaticProperty.stdinEncoding(), UTF_8.INSTANCE); private static final Charset STDOUT_CHARSET = @@ -562,6 +568,9 @@ public sealed class Console implements Flushable permits ProxyingConsole { public Console console() { return cons; } + public boolean isStdinTty() { + return Console.isStdinTty(); + } }); } @@ -583,7 +592,7 @@ public sealed class Console implements Flushable permits ProxyingConsole { for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) { if (consModName.equals(jcp.getClass().getModule().getName())) { - var jc = jcp.console(istty, STDIN_CHARSET, STDOUT_CHARSET); + var jc = jcp.console(isStdinTty() && isStdoutTty(), STDIN_CHARSET, STDOUT_CHARSET); if (jc != null) { c = new ProxyingConsole(jc); } @@ -594,12 +603,21 @@ public sealed class Console implements Flushable permits ProxyingConsole { } // If not found, default to built-in Console - if (istty && c == null) { + if (isStdinTty() && isStdoutTty() && c == null) { c = new ProxyingConsole(new JdkConsoleImpl(STDIN_CHARSET, STDOUT_CHARSET)); } return c; } - private static native boolean istty(); + private static boolean isStdinTty() { + return (ttyStatus & TTY_STDIN_MASK) != 0; + } + private static boolean isStdoutTty() { + return (ttyStatus & TTY_STDOUT_MASK) != 0; + } + private static boolean isStderrTty() { + return (ttyStatus & TTY_STDERR_MASK) != 0; + } + private static native int ttyStatus(); } diff --git a/src/java.base/share/classes/jdk/internal/access/JavaIOAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaIOAccess.java index 532c1f259d4..bdeb2282a02 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaIOAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaIOAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -29,4 +29,5 @@ import java.io.Console; public interface JavaIOAccess { Console console(); + boolean isStdinTty(); } diff --git a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java index ec94d4ec4d6..c9c6b53fcda 100644 --- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java +++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java @@ -38,10 +38,13 @@ import java.util.Arrays; import java.util.Formatter; import java.util.Locale; import java.util.Objects; +import java.util.Optional; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.StaticProperty; import sun.nio.cs.StreamDecoder; import sun.nio.cs.StreamEncoder; +import sun.nio.cs.UTF_8; /** * JdkConsole implementation based on the platform's TTY. @@ -103,6 +106,42 @@ public final class JdkConsoleImpl implements JdkConsole { @Override public char[] readPassword(Locale locale, String format, Object ... args) { + return readPassword0(false, locale, format, args); + } + + // These two methods are intended for sun.security.util.Password, so tools like keytool can + // use JdkConsoleImpl even when standard output is redirected. The Password class should first + // check if `System.console()` returns a Console instance and use it if available. Otherwise, + // it should call this method to obtain a JdkConsoleImpl. This ensures only one Console + // instance exists in the Java runtime. + private static final StableValue> INSTANCE = StableValue.of(); + public static Optional passwordConsole() { + return INSTANCE.orElseSet(() -> { + // If there's already a proper console, throw an exception + if (System.console() != null) { + throw new IllegalStateException("Can’t create a dedicated password " + + "console since a real console already exists"); + } + + // If stdin is NOT redirected, return an Optional containing a JdkConsoleImpl + // instance, otherwise an empty Optional. + return SharedSecrets.getJavaIOAccess().isStdinTty() ? + Optional.of( + new JdkConsoleImpl( + Charset.forName(StaticProperty.stdinEncoding(), UTF_8.INSTANCE), + Charset.forName(StaticProperty.stdoutEncoding(), UTF_8.INSTANCE))) : + Optional.empty(); + }); + } + + // Dedicated entry for sun.security.util.Password when stdout is redirected. + // This method strictly avoids producing any output by using noNewLine = true + // and an empty format string. + public char[] readPasswordNoNewLine() { + return readPassword0(true, Locale.getDefault(Locale.Category.FORMAT), ""); + } + + private char[] readPassword0(boolean noNewLine, Locale locale, String format, Object ... args) { char[] passwd = null; synchronized (writeLock) { synchronized(readLock) { @@ -146,7 +185,9 @@ public final class JdkConsoleImpl implements JdkConsole { throw ioe; } } - pw.println(); + if (!noNewLine) { + pw.println(); + } } } return passwd; diff --git a/src/java.base/unix/native/libjava/Console_md.c b/src/java.base/unix/native/libjava/Console_md.c index 1e71ab3a6b2..17643779b31 100644 --- a/src/java.base/unix/native/libjava/Console_md.c +++ b/src/java.base/unix/native/libjava/Console_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -31,8 +31,19 @@ #include #include -JNIEXPORT jboolean JNICALL -Java_java_io_Console_istty(JNIEnv *env, jclass cls) +JNIEXPORT jint JNICALL +Java_java_io_Console_ttyStatus(JNIEnv *env, jclass cls) { - return isatty(fileno(stdin)) && isatty(fileno(stdout)); + jint ret = 0; + + if (isatty(fileno(stdin))) { + ret |= java_io_Console_TTY_STDIN_MASK; + } + if (isatty(fileno(stdout))) { + ret |= java_io_Console_TTY_STDOUT_MASK; + } + if (isatty(fileno(stderr))) { + ret |= java_io_Console_TTY_STDERR_MASK; + } + return ret; } diff --git a/src/java.base/windows/native/libjava/Console_md.c b/src/java.base/windows/native/libjava/Console_md.c index f73e62f8e26..07749f2775a 100644 --- a/src/java.base/windows/native/libjava/Console_md.c +++ b/src/java.base/windows/native/libjava/Console_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -31,21 +31,28 @@ #include #include -JNIEXPORT jboolean JNICALL -Java_java_io_Console_istty(JNIEnv *env, jclass cls) +JNIEXPORT jint JNICALL +Java_java_io_Console_ttyStatus(JNIEnv *env, jclass cls) { + jint ret = 0; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE); - if (hStdIn == INVALID_HANDLE_VALUE || - hStdOut == INVALID_HANDLE_VALUE) { - return JNI_FALSE; + if (hStdIn != INVALID_HANDLE_VALUE && + GetFileType(hStdIn) == FILE_TYPE_CHAR) { + ret |= java_io_Console_TTY_STDIN_MASK; } - if (GetFileType(hStdIn) != FILE_TYPE_CHAR || - GetFileType(hStdOut) != FILE_TYPE_CHAR) { - return JNI_FALSE; + if (hStdOut != INVALID_HANDLE_VALUE && + GetFileType(hStdOut) == FILE_TYPE_CHAR) { + ret |= java_io_Console_TTY_STDOUT_MASK; } - return JNI_TRUE; + if (hStdErr != INVALID_HANDLE_VALUE && + GetFileType(hStdErr) == FILE_TYPE_CHAR) { + ret |= java_io_Console_TTY_STDERR_MASK; + } + + return ret; } diff --git a/test/jdk/java/io/Console/ModuleSelectionTest.java b/test/jdk/java/io/Console/ModuleSelectionTest.java index 332acf83fbd..f5f02ae13f4 100644 --- a/test/jdk/java/io/Console/ModuleSelectionTest.java +++ b/test/jdk/java/io/Console/ModuleSelectionTest.java @@ -21,9 +21,9 @@ * questions. */ -/** +/* * @test - * @bug 8295803 8299689 8351435 8361613 + * @bug 8295803 8299689 8351435 8361613 8366261 * @summary Tests System.console() returns correct Console (or null) from the expected * module. * @library /test/lib @@ -92,9 +92,12 @@ public class ModuleSelectionTest { var con = System.console(); var pc = Class.forName("java.io.ProxyingConsole"); var jdkc = Class.forName("jdk.internal.io.JdkConsole"); - var istty = (boolean)MethodHandles.privateLookupIn(Console.class, MethodHandles.lookup()) - .findStatic(Console.class, "istty", MethodType.methodType(boolean.class)) - .invoke(); + var lookup = MethodHandles.privateLookupIn(Console.class, MethodHandles.lookup()); + var istty = (boolean)lookup.findStatic(Console.class, "isStdinTty", MethodType.methodType(boolean.class)) + .invoke() && + (boolean)lookup.findStatic(Console.class, "isStdoutTty", MethodType.methodType(boolean.class)) + .invoke(); + var impl = con != null ? MethodHandles.privateLookupIn(pc, MethodHandles.lookup()) .findGetter(pc, "delegate", jdkc) .invoke(con) : null; From 24a734938e555882857cf0b06ea693ec6f18085f Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Tue, 9 Sep 2025 22:03:25 +0000 Subject: [PATCH 005/120] 8366733: Re-examine older java.text NF, DF, and DFS serialization tests Reviewed-by: naoto --- .../DecimalFormat/DFSSerializationTest.java | 90 ++++- .../DecimalFormat.114.txt | 0 .../DecimalFormatSymbols.114.txt | 0 .../DecimalFormatSymbols.142.txt | 0 .../NumberFormat4185761a.ser.txt | 0 .../NumberFormat4185761b.ser.txt | 0 .../DecimalFormat/SerializationTest.java | 355 ++++++++++++++++-- .../NumberFormat/DFSDeserialization142.java | 56 --- .../Format/NumberFormat/DFSSerialization.java | 162 -------- .../NumberFormat/DFSSerialization142.java | 54 --- .../Format/NumberFormat/NumberRegression.java | 101 +---- .../NumberFormat/SerializationLoadTest.java | 89 ----- .../NumberFormat/SerializationSaveTest.java | 81 ---- 13 files changed, 397 insertions(+), 591 deletions(-) rename test/jdk/java/text/Format/{NumberFormat => DecimalFormat}/DecimalFormat.114.txt (100%) rename test/jdk/java/text/Format/{NumberFormat => DecimalFormat}/DecimalFormatSymbols.114.txt (100%) rename test/jdk/java/text/Format/{NumberFormat => DecimalFormat}/DecimalFormatSymbols.142.txt (100%) rename test/jdk/java/text/Format/{NumberFormat => DecimalFormat}/NumberFormat4185761a.ser.txt (100%) rename test/jdk/java/text/Format/{NumberFormat => DecimalFormat}/NumberFormat4185761b.ser.txt (100%) delete mode 100644 test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java delete mode 100644 test/jdk/java/text/Format/NumberFormat/DFSSerialization.java delete mode 100644 test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java delete mode 100644 test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java delete mode 100644 test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java diff --git a/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java b/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java index 9e875e851c8..d4ccb77c137 100644 --- a/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java +++ b/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java @@ -23,7 +23,9 @@ /* * @test - * @bug 8366401 + * @bug 4068067 4101150 8366401 + * @library /java/text/testlib + * @build HexDumpReader * @summary Check serialization of DecimalFormatSymbols. That is, ensure the * behavior for each stream version is correct during de-serialization. * @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED DFSSerializationTest @@ -35,9 +37,11 @@ import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serializable; import java.lang.reflect.Field; import java.text.DecimalFormatSymbols; import java.util.Currency; @@ -51,13 +55,36 @@ import static org.junit.jupiter.api.Assertions.assertThrows; public class DFSSerializationTest { + // Test that rely on hex dump files that were written from older JDK versions @Nested - class VersionTests { + class HexDumpTests { + + @Test // See 4068067 and CDFS which is the class in the serialized hex dump + void JDK1_1_4Test() { + // Reconstruct a class serialized during 1.1.4 which has a DFS holder + var cdfs = (CheckDecimalFormatSymbols) assertDoesNotThrow( + () -> deSer("DecimalFormatSymbols.114.txt")); + assertDoesNotThrow(cdfs::Update); // Checks getDigit call succeeds + } + + @Test // See 4068067 + void JDK1_4_2Test() { + // Reconstruct a 1.4.2 DFS + var dfs = (DecimalFormatSymbols) assertDoesNotThrow( + () -> deSer("DecimalFormatSymbols.142.txt")); + // Checks curr symbol is saved, and exponent separator default set + assertEquals("E", dfs.getExponentSeparator()); + assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol()); + } + } + + @Nested + class StreamVersionTests { // Ensure correct monetarySeparator and exponential field defaults // Reads monetary from decimal, and sets exponential to 'E' @Test - public void version0Test() { + void version0Test() { var crafted = new DFSBuilder() .setVer(0) .set("monetarySeparator", '~') @@ -76,7 +103,7 @@ public class DFSSerializationTest { // Note that other versions did allow a locale field, which was nullable. // E.g. see nullableLocaleTest which does not set locale when it is `null` @Test - public void version1Test() { + void version1Test() { var crafted = new DFSBuilder() .setVer(1) .set("locale", null) @@ -89,7 +116,7 @@ public class DFSSerializationTest { // Version 2 did not have an exponential separator, and created it via exponent // char field. @Test - public void version2Test() { + void version2Test() { var crafted = new DFSBuilder() .setVer(2) .set("exponentialSeparator", null) @@ -103,7 +130,7 @@ public class DFSSerializationTest { // Version 3 didn't have perMillText, percentText, and minusSignText. // These were created from the corresponding char equivalents. @Test - public void version3Test() { + void version3Test() { var crafted = new DFSBuilder() .setVer(3) .set("perMillText", null) @@ -125,7 +152,7 @@ public class DFSSerializationTest { // Version 4 did not have monetaryGroupingSeparator. It should be based // off of groupingSeparator. @Test - public void version4Test() { + void version4Test() { var crafted = new DFSBuilder() .setVer(4) .set("monetaryGroupingSeparator", 'Z') @@ -142,7 +169,7 @@ public class DFSSerializationTest { // the case and previous stream versions can contain a null locale. Thus, // ensure that a null locale does not cause number data loading to fail. @Test - public void nullableLocaleTest() { + void nullableLocaleTest() { var bytes = ser(new DFSBuilder() .set("locale", null) .set("minusSignText", "zFoo") @@ -157,7 +184,7 @@ public class DFSSerializationTest { // readObject fails when the {@code char} and {@code String} representations // of percent, per mille, and/or minus sign disagree. @Test - public void disagreeingTextTest() { + void disagreeingTextTest() { var expected = "'char' and 'String' representations of either percent, " + "per mille, and/or minus sign disagree."; assertEquals(expected, assertThrows(InvalidObjectException.class, () -> @@ -179,7 +206,7 @@ public class DFSSerializationTest { // Ensure the serial version is updated to the current after de-serialization. @Test - public void updatedVersionTest() { + void updatedVersionTest() { var bytes = ser(new DFSBuilder().setVer(-25).build()); var dfs = assertDoesNotThrow(() -> deSer(bytes)); assertEquals(5, readField(dfs, "serialVersionOnStream")); @@ -187,7 +214,7 @@ public class DFSSerializationTest { // Should set currency from 4217 code when it is valid. @Test - public void validIntlCurrencyTest() { + void validIntlCurrencyTest() { var bytes = ser(new DFSBuilder().set("intlCurrencySymbol", "JPY").build()); var dfs = assertDoesNotThrow(() -> deSer(bytes)); assertEquals(Currency.getInstance("JPY"), dfs.getCurrency()); @@ -195,7 +222,7 @@ public class DFSSerializationTest { // Should not set currency when 4217 code is invalid, it remains null. @Test - public void invalidIntlCurrencyTest() { + void invalidIntlCurrencyTest() { var bytes = ser(new DFSBuilder() .set("intlCurrencySymbol", ">.,") .set("locale", Locale.JAPAN) @@ -205,6 +232,26 @@ public class DFSSerializationTest { assertNull(dfs.getCurrency()); } + // Ensure the currency symbol is read properly + @Test + void currencySymbolTest() { + var crafted = new DecimalFormatSymbols(); + crafted.setCurrencySymbol("*SpecialCurrencySymbol*"); + var bytes = ser(crafted); + var dfs = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol()); + } + + // Ensure the exponent separator is read properly + @Test + void exponentSeparatorTest() { + var crafted = new DecimalFormatSymbols(); + crafted.setExponentSeparator("*SpecialExponentSeparator*"); + var bytes = ser(crafted); + var dfs = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals("*SpecialExponentSeparator*", dfs.getExponentSeparator()); + } + // Utilities ---- // Utility to serialize @@ -218,7 +265,7 @@ public class DFSSerializationTest { }, "Unexpected error during serialization"); } - // Utility to deserialize + // Utility to deserialize from byte array private static DecimalFormatSymbols deSer(byte[] bytes) throws IOException, ClassNotFoundException { try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) { @@ -226,6 +273,14 @@ public class DFSSerializationTest { } } + // Utility to deserialize from file in hex format + private static Object deSer(String file) throws IOException, ClassNotFoundException { + try (InputStream stream = HexDumpReader.getStreamFromHexDump(file); + ObjectInputStream ois = new ObjectInputStream(stream)) { + return ois.readObject(); + } + } + // Utility to read a private field private static Object readField(DecimalFormatSymbols dfs, String name) { return assertDoesNotThrow(() -> { @@ -262,3 +317,12 @@ public class DFSSerializationTest { } } } + +// Not nested, so that it can be cast correctly for the 1.1.4 test +class CheckDecimalFormatSymbols implements Serializable { + DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols(); + public char Update() + { + return _decFormatSymbols.getDigit(); + } +} diff --git a/test/jdk/java/text/Format/NumberFormat/DecimalFormat.114.txt b/test/jdk/java/text/Format/DecimalFormat/DecimalFormat.114.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/DecimalFormat.114.txt rename to test/jdk/java/text/Format/DecimalFormat/DecimalFormat.114.txt diff --git a/test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt b/test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.114.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt rename to test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.114.txt diff --git a/test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt b/test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.142.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt rename to test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.142.txt diff --git a/test/jdk/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt b/test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761a.ser.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt rename to test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761a.ser.txt diff --git a/test/jdk/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt b/test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761b.ser.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt rename to test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761b.ser.txt diff --git a/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java b/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java index 09e3f6cf809..6a639b8fea1 100644 --- a/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java +++ b/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 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 @@ -22,65 +22,344 @@ */ /* * @test - * @bug 8327640 - * @summary Check parseStrict correctness for DecimalFormat serialization - * @run junit/othervm SerializationTest + * @bug 4069754 4067878 4101150 4185761 8327640 + * @library /java/text/testlib + * @build HexDumpReader + * @summary Check de-serialization correctness for DecimalFormat. That is, ensure the + * behavior for each stream version is correct during de-serialization. + * @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED SerializationTest */ -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import java.io.FileInputStream; -import java.io.FileOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.math.RoundingMode; +import java.text.DateFormat; +import java.text.DecimalFormat; import java.text.NumberFormat; -import java.text.ParseException; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Random; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class SerializationTest { - private static final NumberFormat FORMAT = NumberFormat.getInstance(); + @Nested // Test that rely on hex dump files that were written from older JDK versions + class HexDumpTests { - @BeforeAll - public static void mutateFormat() { - FORMAT.setStrict(true); - } + @Test // See 4101150 and CDF which is the serialized hex dump + void JDK1_1_4Test() { + // Reconstruct a 1.1.4 serializable class which has a DF holder + var cdf = (CheckDecimalFormat) assertDoesNotThrow( + () -> deSer("DecimalFormat.114.txt")); + assertDoesNotThrow(cdf::Update); // Checks format call succeeds + } - @Test - public void testSerialization() throws IOException, ClassNotFoundException { - // Serialize - serialize("fmt.ser", FORMAT); - // Deserialize - deserialize("fmt.ser", FORMAT); - } + @Test // See 4185761 + void minMaxDigitsTest() { + // Reconstructing a DFS stream from an older JDK version + // The min digits are smaller than the max digits and should fail + // minint maxint minfrac maxfrac + // 0x122 0x121 0x124 0x123 + assertEquals("Digit count range invalid", + assertThrows(InvalidObjectException.class, + () -> deSer("NumberFormat4185761a.ser.txt")).getMessage()); + } - private void serialize(String fileName, NumberFormat... formats) - throws IOException { - try (ObjectOutputStream os = new ObjectOutputStream( - new FileOutputStream(fileName))) { - for (NumberFormat fmt : formats) { - os.writeObject(fmt); - } + @Test // See 4185761 + void digitLimitTest() { + // Reconstructing a DFS stream from an older JDK version + // The digit values exceed the class invariant limits + // minint maxint minfrac maxfrac + // 0x311 0x312 0x313 0x314 + assertEquals("Digit count out of range", + assertThrows(InvalidObjectException.class, + () -> deSer("NumberFormat4185761b.ser.txt")).getMessage()); } } - private static void deserialize(String fileName, NumberFormat... formats) - throws IOException, ClassNotFoundException { - try (ObjectInputStream os = new ObjectInputStream( - new FileInputStream(fileName))) { - for (NumberFormat fmt : formats) { - NumberFormat obj = (NumberFormat) os.readObject(); - assertEquals(fmt, obj, "Serialized and deserialized" - + " objects do not match"); + @Nested + class VersionTests { - String badNumber = "fooofooo23foo"; - assertThrows(ParseException.class, () -> fmt.parse(badNumber)); - assertThrows(ParseException.class, () -> obj.parse(badNumber)); + // Version 0 did not have exponential fields and defaulted the value to false + @Test + void version0Test() { + var crafted = new DFBuilder() + .setVer(0) + .set("useExponentialNotation", true) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + // Ensure we do not observe exponential notation form + assertFalse(df.format(0).contains("E")); + } + + // Version 1 did not support the affix pattern Strings. Ensure when they + // are read in from the stream they are not defaulted and remain null. + @Test + void version1Test() { + var crafted = new DFBuilder() + .setVer(1) + .set("posPrefixPattern", null) + .set("posSuffixPattern", null) + .set("negPrefixPattern", null) + .set("negSuffixPattern", null) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertNull(readField(df, "posPrefixPattern")); + assertNull(readField(df, "posSuffixPattern")); + assertNull(readField(df, "negPrefixPattern")); + assertNull(readField(df, "negSuffixPattern")); + } + + // Version 2 did not support the min/max int and frac digits. + // Ensure the proper defaults are set. + @Test + void version2Test() { + var crafted = new DFBuilder() + .setVer(2) + .set("maximumIntegerDigits", -1) + .set("maximumFractionDigits", -1) + .set("minimumIntegerDigits", -1) + .set("minimumFractionDigits", -1) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(1, df.getMinimumIntegerDigits()); + assertEquals(3, df.getMaximumFractionDigits()); + assertEquals(309, df.getMaximumIntegerDigits()); + assertEquals(0, df.getMinimumFractionDigits()); + } + + // Version 3 did not support rounding mode. Should default to HALF_EVEN + @Test + void version3Test() { + var crafted = new DFBuilder() + .setVer(3) + .set("roundingMode", RoundingMode.UNNECESSARY) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(RoundingMode.HALF_EVEN, df.getRoundingMode()); + } + } + + // Some invariant checking in DF relies on checking NF fields. + // Either via NF.readObject() or through super calls in DF.readObject + @Nested // For all these nested tests, see 4185761 + class NumberFormatTests { + + // Ensure the max integer value invariant is not exceeded + @Test + void integerTest() { + var crafted = new DFBuilder() + .setSuper("maximumIntegerDigits", 786) + .setSuper("minimumIntegerDigits", 785) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count out of range", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + + // Ensure the max fraction value invariant is not exceeded + @Test + void fractionTest() { + var crafted = new DFBuilder() + .setSuper("maximumFractionDigits", 788) + .setSuper("minimumFractionDigits", 787) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count out of range", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + + // Ensure the minimum integer digits cannot be greater than the max + @Test + void maxMinIntegerTest() { + var crafted = new DFBuilder() + .setSuper("maximumIntegerDigits", 5) + .setSuper("minimumIntegerDigits", 6) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count range invalid", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + + // Ensure the minimum fraction digits cannot be greater than the max + @Test + void maxMinFractionTest() { + var crafted = new DFBuilder() + .setSuper("maximumFractionDigits", 5) + .setSuper("minimumFractionDigits", 6) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count range invalid", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + } + + // Ensure the serial version is updated to the current after de-serialization. + @Test + void versionTest() { + var bytes = ser(new DFBuilder().setVer(-25).build()); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(4, readField(df, "serialVersionOnStream")); + } + + // Ensure strictness value is read properly when it is set. + @Test + void strictnessTest() { + var crafted = new DecimalFormat(); + crafted.setStrict(true); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertTrue(df.isStrict()); + } + + // Ensure invalid grouping sizes are corrected to the default invariant. + @Test + void groupingSizeTest() { + var crafted = new DFBuilder() + .set("groupingSize", (byte) -5) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(3, df.getGroupingSize()); + } + + // Ensure a de-serialized dFmt does not throw NPE from missing digitList + // later when formatting. i.e. re-construct the transient digitList field + @Test // See 4069754, 4067878 + void digitListTest() { + var crafted = new DecimalFormat(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertDoesNotThrow(() -> df.format(1)); + assertNotNull(readField(df, "digitList")); + } + + // Similar to the previous test, but the original regression test + // which was a failure in DateFormat due to DecimalFormat NPE + @Test // See 4069754 and 4067878 + void digitListDateFormatTest() { + var fmt = new FooFormat(); + fmt.now(); + var bytes = ser(fmt); + var ff = (FooFormat) assertDoesNotThrow(() -> deSer0(bytes)); + assertDoesNotThrow(ff::now); + } + + static class FooFormat implements Serializable { + DateFormat dateFormat = DateFormat.getDateInstance(); + + public String now() { + GregorianCalendar calendar = new GregorianCalendar(); + Date t = calendar.getTime(); + return dateFormat.format(t); + } + } + +// Utilities ---- + + // Utility to serialize + private static byte[] ser(Object obj) { + return assertDoesNotThrow(() -> { + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream)) { + oos.writeObject(obj); + return byteArrayOutputStream.toByteArray(); } + }, "Unexpected error during serialization"); + } + + // Utility to deserialize + private static Object deSer0(byte[] bytes) throws IOException, ClassNotFoundException { + try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) { + return ois.readObject(); + } + } + + // Convenience cast to DF + private static DecimalFormat deSer(byte[] bytes) throws IOException, ClassNotFoundException { + return (DecimalFormat) deSer0(bytes); + } + + // Utility to deserialize from file in hex format + private static Object deSer(String file) throws IOException, ClassNotFoundException { + try (InputStream stream = HexDumpReader.getStreamFromHexDump(file); + ObjectInputStream ois = new ObjectInputStream(stream)) { + return ois.readObject(); + } + } + + // Utility to read a private field + private static Object readField(DecimalFormat df, String name) { + return assertDoesNotThrow(() -> { + var field = DecimalFormat.class.getDeclaredField(name); + field.setAccessible(true); + return field.get(df); + }, "Unexpected error during field reading"); + } + + // Utility class to build instances of DF via reflection + private static class DFBuilder { + + private final DecimalFormat df; + + private DFBuilder() { + df = new DecimalFormat(); + } + + private DFBuilder setVer(Object value) { + return set("serialVersionOnStream", value); + } + + private DFBuilder setSuper(String field, Object value) { + return set(df.getClass().getSuperclass(), field, value); + } + + private DFBuilder set(String field, Object value) { + return set(df.getClass(), field, value); + } + + private DFBuilder set(Class clzz, String field, Object value) { + return assertDoesNotThrow(() -> { + Field f = clzz.getDeclaredField(field); + f.setAccessible(true); + f.set(df, value); + return this; + }, "Unexpected error during reflection setting"); + } + + private DecimalFormat build() { + return df; } } } + +// Not nested, so that it can be recognized and cast correctly for the 1.1.4 test +class CheckDecimalFormat implements Serializable { + DecimalFormat _decFormat = (DecimalFormat) NumberFormat.getInstance(); + public String Update() { + Random r = new Random(); + return _decFormat.format(r.nextDouble()); + } +} diff --git a/test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java b/test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java deleted file mode 100644 index 2927f4e2c3b..00000000000 --- a/test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * No at-test for this test, because it needs to be run on older version JDK than 1.6 to test. - * It was tested using 1.4.2. The file object was created using JDK1.6. - */ - - - -import java.awt.*; -import java.text.*; -import java.util.*; -import java.io.*; - -public class DFSDeserialization142{ - - public static void main(String[] args) - { - try { - - File file = new File("DecimalFormatSymbols.current"); - FileInputStream istream = new FileInputStream(file); - ObjectInputStream p = new ObjectInputStream(istream); - DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject(); - if (dfs.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ - System.out.println("Serialization/Deserialization Test Passed."); - }else{ - throw new Exception("Serialization/Deserialization Test Failed:"+dfs.getCurrencySymbol()); - } - istream.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java b/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java deleted file mode 100644 index dea1d68ff6e..00000000000 --- a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2005, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4068067 - * @library /java/text/testlib - * @build DFSSerialization HexDumpReader - * @run junit DFSSerialization - * @summary Three different tests are done. - * 1. read from the object created using jdk1.4.2 - * 2. create a valid DecimalFormatSymbols object with current JDK, then read the object - * 3. Try to create an valid DecimalFormatSymbols object by passing null to set null - * for the exponent separator symbol. Expect the NullPointerException. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.text.DecimalFormatSymbols; -import java.util.Locale; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.fail; - -public class DFSSerialization{ - - @Test - public void TestDFSSerialization(){ - /* - * 1. read from the object created using jdk1.4.2 - */ - File oldFile = new File(System.getProperty("test.src", "."), "DecimalFormatSymbols.142.txt"); - DecimalFormatSymbols dfs142 = readTestObject(oldFile); - if (dfs142 != null){ - if (dfs142.getExponentSeparator().equals("E") && dfs142.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ - System.out.println("\n Deserialization of JDK1.4.2 Object from the current JDK: Passed."); - System.out.println(" Deserialization of JDK1.4.2 Object from the current JDK: Passed."); - } else { - fail(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:" - +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator()); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:" - +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator()); - } - } - /* - * 2. create a valid DecimalFormatSymbols object with current JDK, then read the object - */ - String validObject = "DecimalFormatSymbols.current"; - File currentFile = createTestObject(validObject, "*SpecialExponentSeparator*"); - - DecimalFormatSymbols dfsValid = readTestObject(currentFile); - if (dfsValid != null){ - if (dfsValid.getExponentSeparator().equals("*SpecialExponentSeparator*") && - dfsValid.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ - System.out.println(" Deserialization of current JDK Object from the current JDK: Passed."); - System.out.println(" Deserialization of current JDK Object from the current JDK: Passed."); - } else { - fail(" Deserialization of current JDK Object from the current JDK was Failed:" - +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator()); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException(" Deserialization of current Object from the current JDK was Failed:" - +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator()); - } - } - /* - * 3. Try to create an valid DecimalFormatSymbols object by passing null - * to set null for the exponent separator symbol. Expect the NullPointerException. - */ - DecimalFormatSymbols symNPE = new DecimalFormatSymbols(Locale.US); - boolean npePassed = false; - try { - symNPE.setExponentSeparator(null); - } catch (NullPointerException npe){ - npePassed = true; - System.out.println(" Trying to set exponent separator with null: Passed."); - System.out.println(" Trying to set exponent separator with null: Passed."); - } - if (!npePassed){ - System.out.println(" Trying to set exponent separator with null:Failed."); - fail(" Trying to set exponent separator with null:Failed."); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException(" Trying to set exponent separator with null:Failed."); - } - - } - - private DecimalFormatSymbols readTestObject(File inputFile){ - try (InputStream istream = inputFile.getName().endsWith(".txt") ? - HexDumpReader.getStreamFromHexDump(inputFile) : - new FileInputStream(inputFile)) { - ObjectInputStream p = new ObjectInputStream(istream); - DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject(); - return dfs; - } catch (Exception e) { - fail("Test Malfunction in DFSSerialization: Exception while reading the object"); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException("Test Malfunction: re-throwing the exception", e); - } - } - - private File createTestObject(String objectName, String expString){ - DecimalFormatSymbols dfs= new DecimalFormatSymbols(); - dfs.setExponentSeparator(expString); - dfs.setCurrencySymbol("*SpecialCurrencySymbol*"); - System.out.println(" The special exponent separator is set : " + dfs.getExponentSeparator()); - System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol()); - - // 6345659: create a test object in the test.class dir where test user has a write permission. - File file = new File(System.getProperty("test.class", "."), objectName); - try (FileOutputStream ostream = new FileOutputStream(file)) { - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(dfs); - //System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol()); - return file; - } catch (Exception e){ - fail("Test Malfunction in DFSSerialization: Exception while creating an object"); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException("Test Malfunction: re-throwing the exception", e); - } - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java b/test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java deleted file mode 100644 index 4a5e873ee23..00000000000 --- a/test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * No at-test for this test, because it needs to be run on JDK 1.4.2 - * Instead, the resulting serialized file - * DecimalFormatSymbols.142 is archived. - */ - -import java.awt.*; -import java.text.*; -import java.util.*; -import java.io.*; - -public class DFSSerialization142 { - - public static void main(String[] args) - { - try { - - DecimalFormatSymbols dfs= new DecimalFormatSymbols(); - System.out.println("Default currency symbol in the default locale : " + dfs.getCurrencySymbol()); - dfs.setCurrencySymbol("*SpecialCurrencySymbol*"); - System.out.println("The special currency symbol is set : " + dfs.getCurrencySymbol()); - FileOutputStream ostream = new FileOutputStream("DecimalFormatSymbols.142"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(dfs); - ostream.close(); - System.out.println("DecimalFormatSymbols saved ok."); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/NumberRegression.java b/test/jdk/java/text/Format/NumberFormat/NumberRegression.java index 2ff111f0e4b..dcc87643b2b 100644 --- a/test/jdk/java/text/Format/NumberFormat/NumberRegression.java +++ b/test/jdk/java/text/Format/NumberFormat/NumberRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, 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 @@ -28,9 +28,8 @@ * 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713 * 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840 * 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198 - * 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742 - * 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313 - * 8174269 + * 4162852 4167494 4170798 4176114 4179818 4212072 4212073 4216742 4217661 + * 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313 8174269 * @summary Regression tests for NumberFormat and associated classes * @library /java/text/testlib * @build HexDumpReader TestUtils @@ -307,33 +306,6 @@ public class NumberRegression { Locale.setDefault(savedLocale); } - /* bugs 4069754, 4067878 - * null pointer thrown when accessing a deserialized DecimalFormat - * object. - */ - @Test - public void Test4069754() - { - try { - myformat it = new myformat(); - System.out.println(it.Now()); - FileOutputStream ostream = new FileOutputStream("t.tmp"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(it); - ostream.close(); - System.out.println("Saved ok."); - - FileInputStream istream = new FileInputStream("t.tmp"); - ObjectInputStream p2 = new ObjectInputStream(istream); - myformat it2 = (myformat)p2.readObject(); - System.out.println(it2.Now()); - istream.close(); - System.out.println("Loaded ok."); - } catch (Exception foo) { - fail("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); - } - } - /** * DecimalFormat.applyPattern(String) allows illegal patterns */ @@ -1485,59 +1457,6 @@ public class NumberRegression { } } - @Test - public void Test4185761() throws IOException, ClassNotFoundException { - /* Code used to write out the initial files, which are - * then edited manually: - NumberFormat nf = NumberFormat.getInstance(Locale.US); - nf.setMinimumIntegerDigits(0x111); // Keep under 309 - nf.setMaximumIntegerDigits(0x112); // Keep under 309 - nf.setMinimumFractionDigits(0x113); // Keep under 340 - nf.setMaximumFractionDigits(0x114); // Keep under 340 - FileOutputStream ostream = - new FileOutputStream("NumberFormat4185761"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(nf); - ostream.close(); - */ - - // File minint maxint minfrac maxfrac - // NumberFormat4185761a 0x122 0x121 0x124 0x123 - // NumberFormat4185761b 0x311 0x312 0x313 0x314 - // File a is bad because the mins are smaller than the maxes. - // File b is bad because the values are too big for a DecimalFormat. - // These files have a sufix ".ser.txt". - - InputStream istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761a.ser.txt"); - ObjectInputStream p = new ObjectInputStream(istream); - try { - NumberFormat nf = (NumberFormat) p.readObject(); - fail("FAIL: Deserialized bogus NumberFormat int:" + - nf.getMinimumIntegerDigits() + ".." + - nf.getMaximumIntegerDigits() + " frac:" + - nf.getMinimumFractionDigits() + ".." + - nf.getMaximumFractionDigits()); - } catch (InvalidObjectException e) { - System.out.println("Ok: " + e.getMessage()); - } - istream.close(); - - istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761b.ser.txt"); - p = new ObjectInputStream(istream); - try { - NumberFormat nf = (NumberFormat) p.readObject(); - fail("FAIL: Deserialized bogus DecimalFormat int:" + - nf.getMinimumIntegerDigits() + ".." + - nf.getMaximumIntegerDigits() + " frac:" + - nf.getMinimumFractionDigits() + ".." + - nf.getMaximumFractionDigits()); - } catch (InvalidObjectException e) { - System.out.println("Ok: " + e.getMessage()); - } - istream.close(); - } - - /** * Some DecimalFormatSymbols changes are not picked up by DecimalFormat. * This includes the minus sign, currency symbol, international currency @@ -1930,20 +1849,6 @@ public class NumberRegression { } } -@SuppressWarnings("serial") -class myformat implements Serializable -{ - DateFormat _dateFormat = DateFormat.getDateInstance(); - - public String Now() - { - GregorianCalendar calendar = new GregorianCalendar(); - Date t = calendar.getTime(); - String nowStr = _dateFormat.format(t); - return nowStr; - } -} - @SuppressWarnings("serial") class MyNumberFormatTest extends NumberFormat { public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { diff --git a/test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java b/test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java deleted file mode 100644 index 501af54c7da..00000000000 --- a/test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4101150 - * @library /java/text/testlib - * @build SerializationLoadTest HexDumpReader - * @run main SerializationLoadTest - * @summary test serialization compatibility of DecimalFormat and DecimalFormatSymbols - * @key randomness - */ - -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.util.Random; - -public class SerializationLoadTest { - - public static void main(String[] args) - { - try { - InputStream istream1 = HexDumpReader.getStreamFromHexDump("DecimalFormat.114.txt"); - ObjectInputStream p = new ObjectInputStream(istream1); - CheckDecimalFormat it = (CheckDecimalFormat)p.readObject(); - System.out.println("1.1.4 DecimalFormat Loaded ok."); - System.out.println(it.Update()); - System.out.println("Called Update successfully."); - istream1.close(); - - InputStream istream2 = HexDumpReader.getStreamFromHexDump("DecimalFormatSymbols.114.txt"); - ObjectInputStream p2 = new ObjectInputStream(istream2); - CheckDecimalFormatSymbols it2 = (CheckDecimalFormatSymbols)p2.readObject(); - System.out.println("1.1.4 DecimalFormatSymbols Loaded ok."); - System.out.println("getDigit : " + it2.Update()); - System.out.println("Called Update successfully."); - istream2.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormat implements Serializable -{ - DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance(); - - public String Update() - { - Random r = new Random(); - return _decFormat.format(r.nextDouble()); - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormatSymbols implements Serializable -{ - DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols(); - - public char Update() - { - return _decFormatSymbols.getDigit(); - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java b/test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java deleted file mode 100644 index 0332efeca0f..00000000000 --- a/test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * No at-test for this test, because it needs to be run on JDK 1.1.4. - * Instead, the resulting serialized files DecimalFormat.114 and - * DecimalFormatSymbols.114 are archived. - */ - -import java.awt.*; -import java.text.*; -import java.util.*; -import java.io.*; - -public class SerializationSaveTest { - - public static void main(String[] args) - { - try { - CheckDecimalFormat it = new CheckDecimalFormat(); - System.out.println(it.Update()); - FileOutputStream ostream = new FileOutputStream("DecimalFormat.114"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(it); - ostream.close(); - System.out.println("DecimalFormat saved ok."); - CheckDecimalFormatSymbols it2 = new CheckDecimalFormatSymbols(); - System.out.println("getDigit : " + it2.Update()); - FileOutputStream ostream2 = new FileOutputStream("DecimalFormatSymbols.114"); - ObjectOutputStream p2 = new ObjectOutputStream(ostream2); - p2.writeObject(it2); - ostream2.close(); - System.out.println("DecimalFormatSymbols saved ok."); - } catch (Exception e) { - e.printStackTrace(); - } - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormat implements Serializable -{ - DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance(); - - public String Update() - { - Random r = new Random(); - return _decFormat.format(r.nextDouble()); - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormatSymbols implements Serializable -{ - DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols(); - - public char Update() - { - return _decFormatSymbols.getDigit(); - } -} From f96403986b99008593e025c4991ee865fce59bb1 Mon Sep 17 00:00:00 2001 From: Dean Long Date: Tue, 9 Sep 2025 23:27:33 +0000 Subject: [PATCH 006/120] 8361376: Regressions 1-6% in several Renaissance in 26-b4 only MacOSX aarch64 Co-authored-by: Martin Doerr Reviewed-by: mdoerr, aph, eosterlund --- .../gc/shared/barrierSetNMethod_aarch64.cpp | 22 ++++++-- .../arm/gc/shared/barrierSetNMethod_arm.cpp | 22 ++++++-- .../ppc/gc/shared/barrierSetAssembler_ppc.cpp | 12 +++-- .../ppc/gc/shared/barrierSetNMethod_ppc.cpp | 53 ++++++++++++++----- src/hotspot/cpu/ppc/nativeInst_ppc.hpp | 6 ++- .../gc/shared/barrierSetNMethod_riscv.cpp | 22 ++++++-- .../s390/gc/shared/barrierSetNMethod_s390.cpp | 27 +++++++--- .../x86/gc/shared/barrierSetNMethod_x86.cpp | 29 ++++++++-- .../zero/gc/shared/barrierSetNMethod_zero.cpp | 2 +- .../share/gc/shared/barrierSetNMethod.cpp | 27 ++-------- .../share/gc/shared/barrierSetNMethod.hpp | 19 +++---- src/hotspot/share/gc/z/zBarrierSetNMethod.cpp | 28 ---------- src/hotspot/share/gc/z/zBarrierSetNMethod.hpp | 8 --- src/hotspot/share/runtime/mutexLocker.cpp | 3 -- src/hotspot/share/runtime/mutexLocker.hpp | 1 - 15 files changed, 169 insertions(+), 112 deletions(-) diff --git a/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp index 88c90a548d1..3a4ba913a8f 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp @@ -115,8 +115,22 @@ public: return Atomic::load_acquire(guard_addr()); } - void set_value(int value) { - Atomic::release_store(guard_addr(), value); + void set_value(int value, int bit_mask) { + if (bit_mask == ~0) { + Atomic::release_store(guard_addr(), value); + return; + } + assert((value & ~bit_mask) == 0, "trying to set bits outside the mask"); + value &= bit_mask; + int old_value = Atomic::load(guard_addr()); + while (true) { + // Only bits in the mask are changed + int new_value = value | (old_value & ~bit_mask); + if (new_value == old_value) break; + int v = Atomic::cmpxchg(guard_addr(), old_value, new_value, memory_order_release); + if (v == old_value) break; + old_value = v; + } } bool check_barrier(err_msg& msg) const; @@ -179,7 +193,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { new_frame->pc = SharedRuntime::get_handle_wrong_method_stub(); } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { if (!supports_entry_barrier(nm)) { return; } @@ -196,7 +210,7 @@ void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { } NativeNMethodBarrier barrier(nm); - barrier.set_value(value); + barrier.set_value(value, bit_mask); } int BarrierSetNMethod::guard_value(nmethod* nm) { diff --git a/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp b/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp index 52d71ca65c2..81b14f28c35 100644 --- a/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp @@ -51,8 +51,22 @@ public: return Atomic::load_acquire(guard_addr()); } - void set_value(int value) { - Atomic::release_store(guard_addr(), value); + void set_value(int value, int bit_mask) { + if (bit_mask == ~0) { + Atomic::release_store(guard_addr(), value); + return; + } + assert((value & ~bit_mask) == 0, "trying to set bits outside the mask"); + value &= bit_mask; + int old_value = Atomic::load(guard_addr()); + while (true) { + // Only bits in the mask are changed + int new_value = value | (old_value & ~bit_mask); + if (new_value == old_value) break; + int v = Atomic::cmpxchg(guard_addr(), old_value, new_value, memory_order_release); + if (v == old_value) break; + old_value = v; + } } void verify() const; @@ -115,7 +129,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { new_frame->pc = SharedRuntime::get_handle_wrong_method_stub(); } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { if (!supports_entry_barrier(nm)) { return; } @@ -123,7 +137,7 @@ void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { // Disarms the nmethod guard emitted by BarrierSetAssembler::nmethod_entry_barrier. // Symmetric "LDR; DMB ISHLD" is in the nmethod barrier. NativeNMethodBarrier* barrier = native_nmethod_barrier(nm); - barrier->set_value(value); + barrier->set_value(value, bit_mask); } int BarrierSetNMethod::guard_value(nmethod* nm) { diff --git a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp index 405ac4b2310..b2e830bcdb8 100644 --- a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp @@ -183,12 +183,9 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register t BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); assert_different_registers(tmp, R0); - __ block_comment("nmethod_entry_barrier (nmethod_entry_barrier) {"); + __ align(8); // must align the following block which requires atomic updates - // Load stub address using toc (fixed instruction size, unlike load_const_optimized) - __ calculate_address_from_global_toc(tmp, StubRoutines::method_entry_barrier(), - true, true, false); // 2 instructions - __ mtctr(tmp); + __ block_comment("nmethod_entry_barrier (nmethod_entry_barrier) {"); // This is a compound instruction. Patching support is provided by NativeMovRegMem. // Actual patching is done in (platform-specific part of) BarrierSetNMethod. @@ -198,6 +195,11 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register t __ ld(R0, in_bytes(bs_nm->thread_disarmed_guard_value_offset()), R16_thread); __ cmpw(CR0, R0, tmp); + // Load stub address using toc (fixed instruction size, unlike load_const_optimized) + __ calculate_address_from_global_toc(tmp, StubRoutines::method_entry_barrier(), + true, true, false); // 2 instructions + __ mtctr(tmp); + __ bnectrl(CR0); // Oops may have been changed. Make those updates observable. diff --git a/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp index d3bb9cc3c04..02423e13308 100644 --- a/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp @@ -38,7 +38,7 @@ class NativeNMethodBarrier: public NativeInstruction { NativeMovRegMem* get_patchable_instruction_handle() const { // Endianness is handled by NativeMovRegMem - return reinterpret_cast(get_barrier_start_address() + 3 * 4); + return reinterpret_cast(get_barrier_start_address()); } public: @@ -47,7 +47,7 @@ public: return get_patchable_instruction_handle()->offset(); } - void release_set_guard_value(int value) { + void release_set_guard_value(int value, int bit_mask) { // Patching is not atomic. // Stale observations of the "armed" state is okay as invoking the barrier stub in that case has no // unwanted side effects. Disarming is thus a non-critical operation. @@ -55,8 +55,37 @@ public: OrderAccess::release(); // Release modified oops - // Set the guard value (naming of 'offset' function is misleading). - get_patchable_instruction_handle()->set_offset(value); + if (bit_mask == ~0) { + // Set the guard value (naming of 'offset' function is misleading). + get_patchable_instruction_handle()->set_offset(value); + return; + } + + assert((value & ~bit_mask) == 0, "trying to set bits outside the mask"); + value &= bit_mask; + + NativeMovRegMem* mov = get_patchable_instruction_handle(); + assert(align_up(mov->instruction_address(), sizeof(uint64_t)) == + align_down(mov->instruction_address(), sizeof(uint64_t)), "instruction not aligned"); + uint64_t *instr = (uint64_t*)mov->instruction_address(); + assert(NativeMovRegMem::instruction_size == sizeof(*instr), "must be"); + union { + u_char buf[NativeMovRegMem::instruction_size]; + uint64_t u64; + } new_mov_instr, old_mov_instr; + new_mov_instr.u64 = old_mov_instr.u64 = Atomic::load(instr); + while (true) { + // Only bits in the mask are changed + int old_value = nativeMovRegMem_at(old_mov_instr.buf)->offset(); + int new_value = value | (old_value & ~bit_mask); + if (new_value == old_value) return; // skip icache flush if nothing changed + nativeMovRegMem_at(new_mov_instr.buf)->set_offset(new_value, false /* no icache flush */); + // Swap in the new value + uint64_t v = Atomic::cmpxchg(instr, old_mov_instr.u64, new_mov_instr.u64, memory_order_relaxed); + if (v == old_mov_instr.u64) break; + old_mov_instr.u64 = v; + } + ICache::ppc64_flush_icache_bytes(addr_at(0), NativeMovRegMem::instruction_size); } void verify() const { @@ -66,12 +95,6 @@ public: uint* current_instruction = reinterpret_cast(get_barrier_start_address()); - // calculate_address_from_global_toc (compound instruction) - verify_op_code_manually(current_instruction, MacroAssembler::is_addis(*current_instruction)); - verify_op_code_manually(current_instruction, MacroAssembler::is_addi(*current_instruction)); - - verify_op_code_manually(current_instruction, MacroAssembler::is_mtctr(*current_instruction)); - get_patchable_instruction_handle()->verify(); current_instruction += 2; @@ -80,6 +103,12 @@ public: // cmpw (mnemonic) verify_op_code(current_instruction, Assembler::CMP_OPCODE); + // calculate_address_from_global_toc (compound instruction) + verify_op_code_manually(current_instruction, MacroAssembler::is_addis(*current_instruction)); + verify_op_code_manually(current_instruction, MacroAssembler::is_addi(*current_instruction)); + + verify_op_code_manually(current_instruction, MacroAssembler::is_mtctr(*current_instruction)); + // bnectrl (mnemonic) (weak check; not checking the exact type) verify_op_code(current_instruction, Assembler::BCCTR_OPCODE); @@ -117,13 +146,13 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { // Thus, there's nothing to do here. } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { if (!supports_entry_barrier(nm)) { return; } NativeNMethodBarrier* barrier = get_nmethod_barrier(nm); - barrier->release_set_guard_value(value); + barrier->release_set_guard_value(value, bit_mask); } int BarrierSetNMethod::guard_value(nmethod* nm) { diff --git a/src/hotspot/cpu/ppc/nativeInst_ppc.hpp b/src/hotspot/cpu/ppc/nativeInst_ppc.hpp index 38126ec858d..d5dec3f4b1f 100644 --- a/src/hotspot/cpu/ppc/nativeInst_ppc.hpp +++ b/src/hotspot/cpu/ppc/nativeInst_ppc.hpp @@ -462,7 +462,7 @@ class NativeMovRegMem: public NativeInstruction { return ((*hi_ptr) << 16) | ((*lo_ptr) & 0xFFFF); } - void set_offset(intptr_t x) { + void set_offset(intptr_t x, bool flush_icache = true) { #ifdef VM_LITTLE_ENDIAN short *hi_ptr = (short*)(addr_at(0)); short *lo_ptr = (short*)(addr_at(4)); @@ -472,7 +472,9 @@ class NativeMovRegMem: public NativeInstruction { #endif *hi_ptr = x >> 16; *lo_ptr = x & 0xFFFF; - ICache::ppc64_flush_icache_bytes(addr_at(0), NativeMovRegMem::instruction_size); + if (flush_icache) { + ICache::ppc64_flush_icache_bytes(addr_at(0), NativeMovRegMem::instruction_size); + } } void add_offset_in_bytes(intptr_t radd_offset) { diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp index ac619f83f7d..4fa9b4b04fb 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp @@ -109,8 +109,22 @@ public: return Atomic::load_acquire(guard_addr()); } - void set_value(int value) { - Atomic::release_store(guard_addr(), value); + void set_value(int value, int bit_mask) { + if (bit_mask == ~0) { + Atomic::release_store(guard_addr(), value); + return; + } + assert((value & ~bit_mask) == 0, "trying to set bits outside the mask"); + value &= bit_mask; + int old_value = Atomic::load(guard_addr()); + while (true) { + // Only bits in the mask are changed + int new_value = value | (old_value & ~bit_mask); + if (new_value == old_value) break; + int v = Atomic::cmpxchg(guard_addr(), old_value, new_value, memory_order_release); + if (v == old_value) break; + old_value = v; + } } bool check_barrier(err_msg& msg) const; @@ -192,7 +206,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { new_frame->pc = SharedRuntime::get_handle_wrong_method_stub(); } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { if (!supports_entry_barrier(nm)) { return; } @@ -209,7 +223,7 @@ void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { } NativeNMethodBarrier barrier(nm); - barrier.set_value(value); + barrier.set_value(value, bit_mask); } int BarrierSetNMethod::guard_value(nmethod* nm) { diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp index 88b3199e4e1..1a609ad8d45 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp @@ -53,11 +53,26 @@ class NativeMethodBarrier: public NativeInstruction { return *((int32_t*)data_addr); } - void set_guard_value(int value) { - int32_t* data_addr = (int32_t*)get_patchable_data_address(); + void set_guard_value(int value, int bit_mask) { + if (bit_mask == ~0) { + int32_t* data_addr = (int32_t*)get_patchable_data_address(); - // Set guard instruction value - *data_addr = value; + // Set guard instruction value + *data_addr = value; + return; + } + assert((value & ~bit_mask) == 0, "trying to set bits outside the mask"); + value &= bit_mask; + int32_t* data_addr = (int32_t*)get_patchable_data_address(); + int old_value = Atomic::load(data_addr); + while (true) { + // Only bits in the mask are changed + int new_value = value | (old_value & ~bit_mask); + if (new_value == old_value) break; + int v = Atomic::cmpxchg(data_addr, old_value, new_value, memory_order_release); + if (v == old_value) break; + old_value = v; + } } #ifdef ASSERT @@ -100,13 +115,13 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { return; } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { if (!supports_entry_barrier(nm)) { return; } NativeMethodBarrier* barrier = get_nmethod_barrier(nm); - barrier->set_guard_value(value); + barrier->set_guard_value(value, bit_mask); } int BarrierSetNMethod::guard_value(nmethod* nm) { diff --git a/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp b/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp index c27af4a29cd..124daef4fa7 100644 --- a/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp @@ -50,8 +50,31 @@ public: address instruction_address() const { return addr_at(0); } address immediate_address() const { return addr_at(imm_offset); } + NativeNMethodCmpBarrier* nativeNMethodCmpBarrier_at(address a) { return (NativeNMethodCmpBarrier*)a; } + jint get_immediate() const { return int_at(imm_offset); } - void set_immediate(jint imm) { set_int_at(imm_offset, imm); } + void set_immediate(jint imm, int bit_mask) { + if (bit_mask == ~0) { + set_int_at(imm_offset, imm); + return; + } + + assert((imm & ~bit_mask) == 0, "trying to set bits outside the mask"); + imm &= bit_mask; + + assert(align_up(immediate_address(), sizeof(jint)) == + align_down(immediate_address(), sizeof(jint)), "immediate not aligned"); + jint* data_addr = (jint*)immediate_address(); + jint old_value = Atomic::load(data_addr); + while (true) { + // Only bits in the mask are changed + jint new_value = imm | (old_value & ~bit_mask); + if (new_value == old_value) break; + jint v = Atomic::cmpxchg(data_addr, old_value, new_value, memory_order_release); + if (v == old_value) break; + old_value = v; + } + } bool check_barrier(err_msg& msg) const; void verify() const { #ifdef ASSERT @@ -159,13 +182,13 @@ static NativeNMethodCmpBarrier* native_nmethod_barrier(nmethod* nm) { return barrier; } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { if (!supports_entry_barrier(nm)) { return; } NativeNMethodCmpBarrier* cmp = native_nmethod_barrier(nm); - cmp->set_immediate(value); + cmp->set_immediate(value, bit_mask); } int BarrierSetNMethod::guard_value(nmethod* nm) { diff --git a/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp b/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp index 62e7134ed61..e9220ff57e4 100644 --- a/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp +++ b/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp @@ -29,7 +29,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) { ShouldNotReachHere(); } -void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) { +void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) { ShouldNotReachHere(); } diff --git a/src/hotspot/share/gc/shared/barrierSetNMethod.cpp b/src/hotspot/share/gc/shared/barrierSetNMethod.cpp index 522000e0a99..0e5c5d02d1c 100644 --- a/src/hotspot/share/gc/shared/barrierSetNMethod.cpp +++ b/src/hotspot/share/gc/shared/barrierSetNMethod.cpp @@ -72,21 +72,12 @@ bool BarrierSetNMethod::supports_entry_barrier(nmethod* nm) { } void BarrierSetNMethod::disarm(nmethod* nm) { - guard_with(nm, disarmed_guard_value()); + set_guard_value(nm, disarmed_guard_value()); } void BarrierSetNMethod::guard_with(nmethod* nm, int value) { assert((value & not_entrant) == 0, "not_entrant bit is reserved"); - // Enter critical section. Does not block for safepoint. - ConditionalMutexLocker ml(NMethodEntryBarrier_lock, !NMethodEntryBarrier_lock->owned_by_self(), Mutex::_no_safepoint_check_flag); - // Do not undo sticky bit - if (is_not_entrant(nm)) { - value |= not_entrant; - } - if (guard_value(nm) != value) { - // Patch the code only if needed. - set_guard_value(nm, value); - } + set_guard_value(nm, value); } bool BarrierSetNMethod::is_armed(nmethod* nm) { @@ -119,6 +110,8 @@ bool BarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { return true; } + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current())); + // If the nmethod is the only thing pointing to the oops, and we are using a // SATB GC, then it is important that this code marks them live. // Also, with concurrent GC, it is possible that frames in continuation stack @@ -179,10 +172,6 @@ void BarrierSetNMethod::arm_all_nmethods() { } int BarrierSetNMethod::nmethod_stub_entry_barrier(address* return_address_ptr) { - // Enable WXWrite: the function is called directly from nmethod_entry_barrier - // stub. - MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current())); - address return_address = *return_address_ptr; AARCH64_PORT_ONLY(return_address = pauth_strip_pointer(return_address)); CodeBlob* cb = CodeCache::find_blob(return_address); @@ -243,13 +232,7 @@ oop BarrierSetNMethod::oop_load_phantom(const nmethod* nm, int index) { // nmethod_stub_entry_barrier() may appear to be spurious, because is_armed() still returns // false and nmethod_entry_barrier() is not called. void BarrierSetNMethod::make_not_entrant(nmethod* nm) { - // Enter critical section. Does not block for safepoint. - ConditionalMutexLocker ml(NMethodEntryBarrier_lock, !NMethodEntryBarrier_lock->owned_by_self(), Mutex::_no_safepoint_check_flag); - int value = guard_value(nm) | not_entrant; - if (guard_value(nm) != value) { - // Patch the code only if needed. - set_guard_value(nm, value); - } + set_guard_value(nm, not_entrant, not_entrant); } bool BarrierSetNMethod::is_not_entrant(nmethod* nm) { diff --git a/src/hotspot/share/gc/shared/barrierSetNMethod.hpp b/src/hotspot/share/gc/shared/barrierSetNMethod.hpp index b905e8869b5..88bae4d5c1c 100644 --- a/src/hotspot/share/gc/shared/barrierSetNMethod.hpp +++ b/src/hotspot/share/gc/shared/barrierSetNMethod.hpp @@ -36,17 +36,18 @@ class nmethod; class BarrierSetNMethod: public CHeapObj { private: int _current_phase; + + void deoptimize(nmethod* nm, address* return_addr_ptr); + +protected: enum { not_entrant = 1 << 31, // armed sticky bit, see make_not_entrant armed = 0, initial = 1, }; - void deoptimize(nmethod* nm, address* return_addr_ptr); - -protected: - virtual int guard_value(nmethod* nm); - void set_guard_value(nmethod* nm, int value); + int guard_value(nmethod* nm); + void set_guard_value(nmethod* nm, int value, int bit_mask = ~not_entrant); public: BarrierSetNMethod() : _current_phase(initial) {} @@ -60,13 +61,13 @@ public: static int nmethod_stub_entry_barrier(address* return_address_ptr); bool nmethod_osr_entry_barrier(nmethod* nm); - virtual bool is_armed(nmethod* nm); + bool is_armed(nmethod* nm); void arm(nmethod* nm) { guard_with(nm, armed); } void disarm(nmethod* nm); - virtual void make_not_entrant(nmethod* nm); - virtual bool is_not_entrant(nmethod* nm); + void make_not_entrant(nmethod* nm); + bool is_not_entrant(nmethod* nm); - virtual void guard_with(nmethod* nm, int value); + void guard_with(nmethod* nm, int value); virtual void arm_all_nmethods(); diff --git a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp index 392d194a65b..d80ce4e149d 100644 --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp @@ -106,34 +106,6 @@ oop ZBarrierSetNMethod::oop_load_phantom(const nmethod* nm, int index) { return ZNMethod::oop_load_phantom(nm, index); } -void ZBarrierSetNMethod::guard_with(nmethod* nm, int value) { - assert((value & not_entrant) == 0, "not_entrant bit is reserved"); - ZLocker locker(ZNMethod::lock_for_nmethod(nm)); - // Preserve the sticky bit - if (is_not_entrant(nm)) { - value |= not_entrant; - } - if (guard_value(nm) != value) { - // Patch the code only if needed. - set_guard_value(nm, value); - } -} - -bool ZBarrierSetNMethod::is_armed(nmethod* nm) { - int value = guard_value(nm) & ~not_entrant; - return value != disarmed_guard_value(); -} - -void ZBarrierSetNMethod::make_not_entrant(nmethod* nm) { - ZLocker locker(ZNMethod::lock_for_nmethod(nm)); - int value = guard_value(nm) | not_entrant; // permanent sticky value - set_guard_value(nm, value); -} - -bool ZBarrierSetNMethod::is_not_entrant(nmethod* nm) { - return (guard_value(nm) & not_entrant) != 0; -} - uintptr_t ZBarrierSetNMethod::color(nmethod* nm) { // color is stored at low order bits of int; conversion to uintptr_t is fine return uintptr_t(guard_value(nm) & ~not_entrant); diff --git a/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp b/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp index e0b7ba6c773..f51aa53a7e9 100644 --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp @@ -30,10 +30,6 @@ class nmethod; class ZBarrierSetNMethod : public BarrierSetNMethod { - enum : int { - not_entrant = 1 << 31, // armed sticky bit, see make_not_entrant - }; - protected: virtual bool nmethod_entry_barrier(nmethod* nm); @@ -46,10 +42,6 @@ public: virtual oop oop_load_no_keepalive(const nmethod* nm, int index); virtual oop oop_load_phantom(const nmethod* nm, int index); - virtual void make_not_entrant(nmethod* nm); - virtual bool is_not_entrant(nmethod* nm); - virtual void guard_with(nmethod* nm, int value); - virtual bool is_armed(nmethod* nm); virtual void arm_all_nmethods() { ShouldNotCallThis(); } }; diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 3f8915973e2..0c604205939 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -36,7 +36,6 @@ // Mutexes used in the VM (see comment in mutexLocker.hpp): Mutex* NMethodState_lock = nullptr; -Mutex* NMethodEntryBarrier_lock = nullptr; Monitor* SystemDictionary_lock = nullptr; Mutex* InvokeMethodTypeTable_lock = nullptr; Monitor* InvokeMethodIntrinsicTable_lock = nullptr; @@ -207,8 +206,6 @@ void assert_lock_strong(const Mutex* lock) { void mutex_init() { MUTEX_DEFN(tty_lock , PaddedMutex , tty); // allow to lock in VM - MUTEX_DEFN(NMethodEntryBarrier_lock , PaddedMutex , service-1); - MUTEX_DEFN(STS_lock , PaddedMonitor, nosafepoint); #if INCLUDE_G1GC diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index f888c789eb7..3a73edc7bf2 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -34,7 +34,6 @@ class Thread; // Mutexes used in the VM. extern Mutex* NMethodState_lock; // a lock used to guard a compiled method state -extern Mutex* NMethodEntryBarrier_lock; // protects nmethod entry barrier extern Monitor* SystemDictionary_lock; // a lock on the system dictionary extern Mutex* InvokeMethodTypeTable_lock; extern Monitor* InvokeMethodIntrinsicTable_lock; From 8cd4e7d856dcc68243505f4e771dc8ab87176584 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Tue, 9 Sep 2025 23:50:33 +0000 Subject: [PATCH 007/120] 8365192: post_meth_exit should be in vm state when calling get_jvmti_thread_state Reviewed-by: mdoerr, dholmes --- src/hotspot/share/prims/jvmtiExport.cpp | 68 +++++++++++++------------ 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp index 8c10a371e5a..2da9a074fb6 100644 --- a/src/hotspot/share/prims/jvmtiExport.cpp +++ b/src/hotspot/share/prims/jvmtiExport.cpp @@ -418,6 +418,7 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) { JvmtiThreadState* JvmtiExport::get_jvmti_thread_state(JavaThread *thread, bool allow_suspend) { assert(thread == JavaThread::current(), "must be current thread"); + assert(thread->thread_state() == _thread_in_vm, "thread should be in vm"); if (thread->is_vthread_mounted() && thread->jvmti_thread_state() == nullptr) { JvmtiEventController::thread_started(thread); if (allow_suspend && thread->is_suspended()) { @@ -1826,47 +1827,50 @@ void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame cu } void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame current_frame) { + // At this point we only have the address of a "raw result" and + // we just call into the interpreter to convert this into a jvalue. + // This method always makes transition to vm and back where GC can happen. + // So it is needed to preserve result and then restore it + // even if events are not actually posted. + // Saving oop_result into value.j is deferred until jvmti state is ready. HandleMark hm(thread); methodHandle mh(thread, method); - - JvmtiThreadState *state = get_jvmti_thread_state(thread); - - if (state == nullptr || !state->is_interp_only_mode()) { - // for any thread that actually wants method exit, interp_only_mode is set - return; - } - Handle result; + oop oop_result; jvalue value; value.j = 0L; - - if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { - // At this point we only have the address of a "raw result" and - // we just call into the interpreter to convert this into a jvalue. - oop oop_result; - BasicType type = current_frame.interpreter_frame_result(&oop_result, &value); - assert(type == T_VOID || current_frame.interpreter_frame_expression_stack_size() > 0, - "Stack shouldn't be empty"); - if (is_reference_type(type)) { - result = Handle(thread, oop_result); - value.l = JNIHandles::make_local(thread, result()); - } + BasicType type = current_frame.interpreter_frame_result(&oop_result, &value); + assert(mh->is_native() || type == T_VOID || current_frame.interpreter_frame_expression_stack_size() > 0, + "Stack shouldn't be empty"); + if (is_reference_type(type)) { + result = Handle(thread, oop_result); } - - // Do not allow NotifyFramePop to add new FramePop event request at - // depth 0 as it is already late in the method exiting dance. - state->set_top_frame_is_exiting(); - - // Deferred transition to VM, so we can stash away the return oop before GC. + JvmtiThreadState* state; // should be initialized in vm state only JavaThread* current = thread; // for JRT_BLOCK + bool interp_only; // might be changed in JRT_BLOCK_END JRT_BLOCK - post_method_exit_inner(thread, mh, state, false /* not exception exit */, current_frame, value); + state = get_jvmti_thread_state(thread); + interp_only = state != nullptr && state->is_interp_only_mode(); + if (interp_only) { + if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { + // Deferred saving Object result into value. + if (is_reference_type(type)) { + value.l = JNIHandles::make_local(thread, result()); + } + } + + // Do not allow NotifyFramePop to add new FramePop event request at + // depth 0 as it is already late in the method exiting dance. + state->set_top_frame_is_exiting(); + + post_method_exit_inner(thread, mh, state, false /* not exception exit */, current_frame, value); + } JRT_BLOCK_END - - // The JRT_BLOCK_END can safepoint in ThreadInVMfromJava desctructor. Now it is safe to allow - // adding FramePop event requests as no safepoint can happen before removing activation. - state->clr_top_frame_is_exiting(); - + if (interp_only) { + // The JRT_BLOCK_END can safepoint in ThreadInVMfromJava destructor. Now it is safe to allow + // adding FramePop event requests as no safepoint can happen before removing activation. + state->clr_top_frame_is_exiting(); + } if (result.not_null() && !mh->is_native()) { // We have to restore the oop on the stack for interpreter frames *(oop*)current_frame.interpreter_frame_tos_address() = result(); From 53b3e0567d2801ddf62c5849b219324ddfcb264a Mon Sep 17 00:00:00 2001 From: erifan Date: Wed, 10 Sep 2025 01:49:55 +0000 Subject: [PATCH 008/120] 8366588: VectorAPI: Re-intrinsify VectorMask.laneIsSet where the input index is a variable Reviewed-by: shade, xgong, epeter --- src/hotspot/share/opto/vectorIntrinsics.cpp | 2 +- .../compiler/lib/ir_framework/IRNode.java | 5 + .../vectorapi/VectorMaskLaneIsSetTest.java | 160 ++++++++++++++++++ .../vector/VectorExtractBenchmark.java | 5 +- 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 43ca51fca67..85d9790c0eb 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -2502,7 +2502,7 @@ bool LibraryCallKit::inline_vector_extract() { if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || elem_klass == nullptr || elem_klass->const_oop() == nullptr || vlen == nullptr || !vlen->is_con() || - idx == nullptr || !idx->is_con()) { + idx == nullptr) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 16c6d99a64f..52fc9a05f98 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1417,6 +1417,11 @@ public class IRNode { beforeMatchingNameRegex(VECTOR_MASK_TO_LONG, "VectorMaskToLong"); } + public static final String VECTOR_MASK_LANE_IS_SET = PREFIX + "VECTOR_MASK_LANE_IS_SET" + POSTFIX; + static { + beforeMatchingNameRegex(VECTOR_MASK_LANE_IS_SET, "ExtractUB"); + } + // Can only be used if avx512_vnni is available. public static final String MUL_ADD_VS2VI_VNNI = PREFIX + "MUL_ADD_VS2VI_VNNI" + POSTFIX; static { diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java new file mode 100644 index 00000000000..b7f2103c56c --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import compiler.lib.ir_framework.*; +import jdk.incubator.vector.*; +import jdk.test.lib.Asserts; + +/** + * @test + * @bug 8366588 + * @key randomness + * @library /test/lib / + * @summary VectorAPI: Re-intrinsify VectorMask.laneIsSet where the input index is a variable + * @modules jdk.incubator.vector + * + * @run driver compiler.vectorapi.VectorMaskLaneIsSetTest + */ + +public class VectorMaskLaneIsSetTest { + static final VectorSpecies B_SPECIES = ByteVector.SPECIES_MAX; + static final VectorSpecies S_SPECIES = ShortVector.SPECIES_MAX; + static final VectorSpecies I_SPECIES = IntVector.SPECIES_MAX; + static final VectorSpecies F_SPECIES = FloatVector.SPECIES_MAX; + static final VectorSpecies L_SPECIES = LongVector.SPECIES_MAX; + static final VectorSpecies D_SPECIES = DoubleVector.SPECIES_MAX; + static final int LENGTH = 512; + static boolean[] ma; + static VectorMask mask_b; + static VectorMask mask_s; + static VectorMask mask_i; + static VectorMask mask_l; + static VectorMask mask_f; + static VectorMask mask_d; + + static { + ma = new boolean[LENGTH]; + for (int i = 0; i < LENGTH; i++) { + ma[i] = i % 2 == 0; + } + mask_b = VectorMask.fromArray(B_SPECIES, ma, 0); + mask_s = VectorMask.fromArray(S_SPECIES, ma, 0); + mask_i = VectorMask.fromArray(I_SPECIES, ma, 0); + mask_l = VectorMask.fromArray(L_SPECIES, ma, 0); + mask_f = VectorMask.fromArray(F_SPECIES, ma, 0); + mask_d = VectorMask.fromArray(D_SPECIES, ma, 0); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 6" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 6" }, applyIfCPUFeature = { "avx2", "true" }) + public static void testVectorMaskLaneIsSetByte_const() { + Asserts.assertEquals(ma[0], mask_b.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_s.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_i.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_l.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_f.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_d.laneIsSet(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Byte_variable(int i) { + return mask_b.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Byte_variable") + public static void testVectorMaskLaneIsSet_Byte_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Byte_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Short_variable(int i) { + return mask_s.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Short_variable") + public static void testVectorMaskLaneIsSet_Short_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Short_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Int_variable(int i) { + return mask_i.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Int_variable") + public static void testVectorMaskLaneIsSet_Int_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Int_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) + public static boolean testVectorMaskLaneIsSet_Long_variable(int i) { + return mask_l.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Long_variable") + public static void testVectorMaskLaneIsSet_Long_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Long_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Float_variable(int i) { + return mask_f.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Float_variable") + public static void testVectorMaskLaneIsSet_Float_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Float_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) + public static boolean testVectorMaskLaneIsSet_Double_variable(int i) { + return mask_d.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Double_variable") + public static void testVectorMaskLaneIsSet_Double_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Double_variable(0)); + } + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.setDefaultWarmup(10000) + .addFlags("--add-modules=jdk.incubator.vector") + .start(); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java index 6358cb0a5d4..84c9031739c 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Arm Limited. All rights reserved. + * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +29,9 @@ import org.openjdk.jmh.annotations.*; @OutputTimeUnit(TimeUnit.MILLISECONDS) @State(Scope.Thread) -@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector"}) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 1, jvmArgs = {"--add-modules=jdk.incubator.vector"}) public class VectorExtractBenchmark { private int idx = 0; private boolean[] res = new boolean[8]; From af9b9050ec51d0c43690fc42658741bd865b0310 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 10 Sep 2025 03:30:16 +0000 Subject: [PATCH 009/120] 8366057: HotSpot Style Guide should permit trailing return types Reviewed-by: dholmes, stefank, kvn, adinn, jsjolen --- doc/hotspot-style.html | 52 ++++++++++++++++++++++++++++++++++++++---- doc/hotspot-style.md | 37 ++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index 98d813242a5..fb4cffc9d43 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -75,6 +75,9 @@ Standard Library Deduction
  • Expression SFINAE
  • +
  • Trailing return type +syntax for functions
  • Non-type template parameter values
  • @@ -719,11 +722,14 @@ href="http://wg21.link/p0127r2">p0127r2)
    auto may be used as a placeholder for the type of a non-type template parameter. The type is deduced from the value provided in a template instantiation.

    -
  • Function return type deduction ( +

    * Function return type +deduction (n3638)
    Only use if the function body has a very small number of return -statements, and generally relatively little other code.

  • -
  • Class template argument deduction ( +

      +
    • Class template argument deduction (n3602, p0091r3)
      The template arguments of a class template may be deduced from the arguments to a constructor. @@ -736,7 +742,7 @@ harder to understand, because explicit type information is lacking. But it can also remove the need to be explicit about types that are either obvious, or that are very hard to write. For example, these allow the addition of a scope-guard mechanism with nice syntax; something like -this

    • +this
      ScopeGuard guard{[&]{ ... cleanup code ... }};
      @@ -771,6 +777,44 @@ class="uri">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95468
      https://developercommunity.visualstudio.com/content/problem/396562/sizeof-deduced-type-is-sometimes-not-a-constant-ex.html

      +

      Trailing return type +syntax for functions

      +

      A function's return type may be specified after the parameters and +qualifiers (n2541). +In such a declaration the normal return type is auto and +the return type is indicated by -> followed by the type. +Although both use auto in the "normal" leading return type +position, this differs from function return type +deduction, in that the return type is explicit rather than deduced, +but specified in a trailing position.

      +

      Use of trailing return types is permitted. However, the normal, +leading position for the return type is preferred. A trailing return +type should only be used where it provides some benefit. Such benefits +usually arise because a trailing return type is in a different scope +than a leading return type.

      +
        +
      • If the function identifier is a nested name specifier, then the +trailing return type occurs in the nested scope. This may permit simpler +naming in the return type because of the different name lookup +context.

      • +
      • The trailing return type is in the scope of the parameters, +making their types accessible via decltype. For +example

      • +
      +
      template<typename T, typename U> auto add(T t, U u) -> decltype(t + u);
      +

      rather than

      +
      template<typename T, typename U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);
      +
        +
      • Complex calculated leading return types may obscure the normal +syntactic boundaries, making it more difficult for a reader to find the +function name and parameters. This is particularly common in cases where +the return type is being used for SFINAE. A trailing +return type may be preferable in such situations.
      • +

      Non-type template parameter values

      C++17 extended the arguments permitted for non-type template diff --git a/doc/hotspot-style.md b/doc/hotspot-style.md index e3ba4b470ce..3fd5468d531 100644 --- a/doc/hotspot-style.md +++ b/doc/hotspot-style.md @@ -642,6 +642,7 @@ use can make code much harder to understand. parameter. The type is deduced from the value provided in a template instantiation. + * Function return type deduction ([n3638](https://isocpp.org/files/papers/N3638.html))
      Only use if the function body has a very small number of `return` @@ -691,6 +692,42 @@ Here are a few closely related example bugs:

      +### Trailing return type syntax for functions + +A function's return type may be specified after the parameters and qualifiers +([n2541](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm)). +In such a declaration the normal return type is `auto` and the return type is +indicated by `->` followed by the type. Although both use `auto` in the +"normal" leading return type position, this differs from +[function return type deduction](#function-return-type-deduction), +in that the return type is explicit rather than deduced, but specified in a +trailing position. + +Use of trailing return types is permitted. However, the normal, leading +position for the return type is preferred. A trailing return type should only +be used where it provides some benefit. Such benefits usually arise because a +trailing return type is in a different scope than a leading return type. + +* If the function identifier is a nested name specifier, then the trailing +return type occurs in the nested scope. This may permit simpler naming in the +return type because of the different name lookup context. + +* The trailing return type is in the scope of the parameters, making their +types accessible via `decltype`. For example +``` +template auto add(T t, U u) -> decltype(t + u); +``` +rather than +``` +template decltype((*(T*)0) + (*(U*)0)) add(T t, U u); +``` + +* Complex calculated leading return types may obscure the normal syntactic +boundaries, making it more difficult for a reader to find the function name and +parameters. This is particularly common in cases where the return type is +being used for [SFINAE]. A trailing return type may be preferable in such +situations. + ### Non-type template parameter values C++17 extended the arguments permitted for non-type template parameters From 8ab8d02e40e987a5eb5e8036ff4f12146ac2b16a Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 10 Sep 2025 05:45:31 +0000 Subject: [PATCH 010/120] 8366938: Test runtime/handshake/HandshakeTimeoutTest.java crashed Reviewed-by: kbarrett --- .../hotspot/jtreg/runtime/handshake/HandshakeTimeoutTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/runtime/handshake/HandshakeTimeoutTest.java b/test/hotspot/jtreg/runtime/handshake/HandshakeTimeoutTest.java index a1a5ff68c31..7f1ee4be711 100644 --- a/test/hotspot/jtreg/runtime/handshake/HandshakeTimeoutTest.java +++ b/test/hotspot/jtreg/runtime/handshake/HandshakeTimeoutTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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,7 +36,7 @@ import jdk.test.whitebox.WhiteBox; * @library /testlibrary /test/lib * @build HandshakeTimeoutTest * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run driver HandshakeTimeoutTest + * @run driver/timeout=480 HandshakeTimeoutTest */ public class HandshakeTimeoutTest { From 2705e880b64825044e67487f01263121780d8f7a Mon Sep 17 00:00:00 2001 From: Disha Date: Wed, 10 Sep 2025 06:16:12 +0000 Subject: [PATCH 011/120] 8366764: Deproblemlist java/awt/ScrollPane/ScrollPositionTest.java Reviewed-by: azvegint --- test/jdk/ProblemList.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index aac9d9a8a21..475704f7e95 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -455,7 +455,6 @@ java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java 6848810 macosx-all java/awt/FileDialog/ModalFocus/FileDialogModalFocusTest.java 8194751 linux-all java/awt/image/VolatileImage/BitmaskVolatileImage.java 8133102 linux-all java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java 8203004 linux-all -java/awt/ScrollPane/ScrollPositionTest.java 8040070 linux-all java/awt/ScrollPane/ScrollPaneEventType.java 8296516 macosx-all java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528 linux-all,macosx-all java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676 linux-all From b7b01d6f564ae34e913ae51bd2f8243a32807136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Wed, 10 Sep 2025 06:16:39 +0000 Subject: [PATCH 012/120] 8366984: Remove delay slot support Reviewed-by: dlong, epeter --- .../cpu/aarch64/c1_LIRAssembler_aarch64.cpp | 5 - src/hotspot/cpu/arm/arm.ad | 20 +- src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp | 5 - src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp | 5 - .../cpu/riscv/c1_LIRAssembler_riscv.cpp | 2 - src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp | 4 - src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp | 5 - src/hotspot/share/adlc/adlparse.cpp | 32 +- src/hotspot/share/adlc/formsopt.cpp | 4 - src/hotspot/share/adlc/formsopt.hpp | 4 - src/hotspot/share/adlc/output_c.cpp | 23 +- src/hotspot/share/adlc/output_h.cpp | 42 +-- src/hotspot/share/c1/c1_LIR.cpp | 20 -- src/hotspot/share/c1/c1_LIR.hpp | 24 -- src/hotspot/share/c1/c1_LIRAssembler.cpp | 3 +- src/hotspot/share/c1/c1_LIRAssembler.hpp | 6 +- src/hotspot/share/code/relocInfo.hpp | 4 +- src/hotspot/share/opto/output.cpp | 304 ++---------------- src/hotspot/share/runtime/sharedRuntime.cpp | 2 - 19 files changed, 54 insertions(+), 460 deletions(-) diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index e9bb2350b5b..d788c0c201a 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -2585,11 +2585,6 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } -void LIR_Assembler::emit_delay(LIR_OpDelay*) { - Unimplemented(); -} - - void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); } diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 45d51aaac57..2835a256153 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -3281,18 +3281,18 @@ pipe_class loadPollP(iRegP poll) %{ %} pipe_class br(Universe br, label labl) %{ - single_instruction_with_delay_slot; + single_instruction; BR : R; %} pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{ - single_instruction_with_delay_slot; + single_instruction; cr : E(read); BR : R; %} pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{ - single_instruction_with_delay_slot; + single_instruction; op1 : E(read); BR : R; MS : R; @@ -3323,14 +3323,14 @@ pipe_class call(method meth) %{ %} pipe_class tail_call(Universe ignore, label labl) %{ - single_instruction; has_delay_slot; + single_instruction; fixed_latency(100); BR : R(1); MS : R(1); %} pipe_class ret(Universe ignore) %{ - single_instruction; has_delay_slot; + single_instruction; BR : R(1); MS : R(1); %} @@ -3373,14 +3373,6 @@ pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{ IALU : R(3) %} -// Perform a compare, then move conditionally in a branch delay slot. -pipe_class min_max( iRegI src2, iRegI srcdst ) %{ - src2 : E(read); - srcdst : E(read); - IALU : R; - BR : R; -%} - // Define the class for the Nop node define %{ MachNop = ialu_nop; @@ -9053,7 +9045,7 @@ instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dum format %{ "MOV $zero,0\n" " MOV $temp,$cnt\n" "loop: SUBS $temp,$temp,4\t! Count down a dword of bytes\n" - " STR.ge $zero,[$base+$temp]\t! delay slot" + " STR.ge $zero,[$base+$temp]\n" " B.gt loop\t\t! Clearing loop\n" %} ins_encode %{ __ mov($zero$$Register, 0); diff --git a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp index c3b91e8c76f..d6ed82dcdb2 100644 --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp @@ -2552,11 +2552,6 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { fatal("Type profiling not implemented on this platform"); } -void LIR_Assembler::emit_delay(LIR_OpDelay*) { - Unimplemented(); -} - - void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { Address mon_addr = frame_map()->address_for_monitor_lock(monitor_no); __ add_slow(dst->as_pointer_register(), mon_addr.base(), mon_addr.disp()); diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp index 73509c22134..3ca75305eca 100644 --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp @@ -2747,11 +2747,6 @@ void LIR_Assembler::align_backward_branch_target() { } -void LIR_Assembler::emit_delay(LIR_OpDelay* op) { - Unimplemented(); -} - - void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) { // tmp must be unused assert(tmp->is_illegal(), "wasting a register if tmp is allocated"); diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index f60be85a141..c3fe72870cf 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -1590,8 +1590,6 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } } -void LIR_Assembler::emit_delay(LIR_OpDelay*) { Unimplemented(); } - void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { __ la(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); } diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index 87dc8b9286d..b875eeca9ad 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -2816,10 +2816,6 @@ void LIR_Assembler::align_backward_branch_target() { __ align(OptoLoopAlignment); } -void LIR_Assembler::emit_delay(LIR_OpDelay* op) { - ShouldNotCallThis(); // There are no delay slots on ZARCH_64. -} - void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) { // tmp must be unused assert(tmp->is_illegal(), "wasting a register if tmp is allocated"); diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index a30bbe08c55..98759295bb1 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -3001,11 +3001,6 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ bind(next); } -void LIR_Assembler::emit_delay(LIR_OpDelay*) { - Unimplemented(); -} - - void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); } diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index 15dbf070674..356c24760e8 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp @@ -1389,13 +1389,8 @@ void ADLParser::pipe_parse(void) { } if (!strcmp(ident, "branch_has_delay_slot")) { - skipws(); - if (_curchar == ';') { - next_char(); skipws(); - } - - pipeline->_branchHasDelaySlot = true; - continue; + parse_err(SYNERR, "Using obsolete token, branch_has_delay_slot"); + break; } if (!strcmp(ident, "max_instructions_per_bundle")) { @@ -1762,16 +1757,8 @@ void ADLParser::pipe_class_parse(PipelineForm &pipeline) { if (!strcmp(ident, "one_instruction_with_delay_slot") || !strcmp(ident, "single_instruction_with_delay_slot")) { - skipws(); - if (_curchar != ';') { - parse_err(SYNERR, "missing \";\" in latency definition\n"); - return; - } - - pipe_class->setInstructionCount(1); - pipe_class->setBranchDelay(true); - next_char(); skipws(); - continue; + parse_err(SYNERR, "Using obsolete token, %s", ident); + return; } if (!strcmp(ident, "one_instruction") || @@ -1831,15 +1818,8 @@ void ADLParser::pipe_class_parse(PipelineForm &pipeline) { } if (!strcmp(ident, "has_delay_slot")) { - skipws(); - if (_curchar != ';') { - parse_err(SYNERR, "missing \";\" after \"has_delay_slot\"\n"); - return; - } - - pipe_class->setBranchDelay(true); - next_char(); skipws(); - continue; + parse_err(SYNERR, "Using obsolete token, %s", ident); + return; } if (!strcmp(ident, "force_serialization")) { diff --git a/src/hotspot/share/adlc/formsopt.cpp b/src/hotspot/share/adlc/formsopt.cpp index 01fe6288c53..92489da2f5a 100644 --- a/src/hotspot/share/adlc/formsopt.cpp +++ b/src/hotspot/share/adlc/formsopt.cpp @@ -512,7 +512,6 @@ PipelineForm::PipelineForm() , _classlist () , _classcnt (0) , _variableSizeInstrs (false) - , _branchHasDelaySlot (false) , _maxInstrsPerBundle (0) , _maxBundlesPerCycle (1) , _instrUnitSize (0) @@ -546,8 +545,6 @@ void PipelineForm::output(FILE *fp) { // Write info to output files fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize); else fprintf(fp," fixed-sized instructions"); - if (_branchHasDelaySlot) - fprintf(fp,", branch has delay slot"); if (_maxInstrsPerBundle > 0) fprintf(fp,", max of %d instruction%s in parallel", _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : ""); @@ -637,7 +634,6 @@ PipeClassForm::PipeClassForm(const char *id, int num) , _fixed_latency(0) , _instruction_count(0) , _has_multiple_bundles(false) - , _has_branch_delay_slot(false) , _force_serialization(false) , _may_have_no_code(false) { } diff --git a/src/hotspot/share/adlc/formsopt.hpp b/src/hotspot/share/adlc/formsopt.hpp index db7b9dbd8d8..34cbc24bed0 100644 --- a/src/hotspot/share/adlc/formsopt.hpp +++ b/src/hotspot/share/adlc/formsopt.hpp @@ -387,7 +387,6 @@ public: int _classcnt; // Number of classes bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions - bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP int _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP int _instrUnitSize; // The minimum instruction unit size, in bytes @@ -499,7 +498,6 @@ public: int _fixed_latency; // Always takes this number of cycles int _instruction_count; // Number of instructions in first bundle bool _has_multiple_bundles; // Indicates if 1 or multiple bundles - bool _has_branch_delay_slot; // Has branch delay slot as last instruction bool _force_serialization; // This node serializes relative to surrounding nodes bool _may_have_no_code; // This node may generate no code based on register allocation @@ -518,13 +516,11 @@ public: void setInstructionCount(int i) { _instruction_count = i; } void setMultipleBundles(bool b) { _has_multiple_bundles = b; } - void setBranchDelay(bool s) { _has_branch_delay_slot = s; } void setForceSerialization(bool s) { _force_serialization = s; } void setMayHaveNoCode(bool s) { _may_have_no_code = s; } int InstructionCount() const { return _instruction_count; } bool hasMultipleBundles() const { return _has_multiple_bundles; } - bool hasBranchDelay() const { return _has_branch_delay_slot; } bool forceSerialization() const { return _force_serialization; } bool mayHaveNoCode() const { return _may_have_no_code; } diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index abebf39a2b2..caf2c9952a6 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp @@ -794,8 +794,8 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) { // Create the pipeline class description - fprintf(fp_cpp, "static const Pipeline pipeline_class_Zero_Instructions(0, 0, true, 0, 0, false, false, false, false, nullptr, nullptr, nullptr, Pipeline_Use(0, 0, 0, nullptr));\n\n"); - fprintf(fp_cpp, "static const Pipeline pipeline_class_Unknown_Instructions(0, 0, true, 0, 0, false, true, true, false, nullptr, nullptr, nullptr, Pipeline_Use(0, 0, 0, nullptr));\n\n"); + fprintf(fp_cpp, "static const Pipeline pipeline_class_Zero_Instructions(0, 0, true, 0, 0, false, false, false, nullptr, nullptr, nullptr, Pipeline_Use(0, 0, 0, nullptr));\n\n"); + fprintf(fp_cpp, "static const Pipeline pipeline_class_Unknown_Instructions(0, 0, true, 0, 0, true, true, false, nullptr, nullptr, nullptr, Pipeline_Use(0, 0, 0, nullptr));\n\n"); fprintf(fp_cpp, "const Pipeline_Use_Element Pipeline_Use::elaborated_elements[%d] = {\n", _pipeline->_rescount); for (int i1 = 0; i1 < _pipeline->_rescount; i1++) { @@ -895,12 +895,11 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) { fprintf(fp_cpp, "(uint)stage_%s", _pipeline->_stages.name(maxWriteStage)); else fprintf(fp_cpp, "((uint)stage_%s)+%d", _pipeline->_stages.name(maxWriteStage), maxMoreInstrs); - fprintf(fp_cpp, ", %d, %s, %d, %d, %s, %s, %s, %s,\n", + fprintf(fp_cpp, ", %d, %s, %d, %d, %s, %s, %s,\n", paramcount, pipeclass->hasFixedLatency() ? "true" : "false", pipeclass->fixedLatency(), pipeclass->InstructionCount(), - pipeclass->hasBranchDelay() ? "true" : "false", pipeclass->hasMultipleBundles() ? "true" : "false", pipeclass->forceSerialization() ? "true" : "false", pipeclass->mayHaveNoCode() ? "true" : "false" ); @@ -979,16 +978,6 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) { fprintf(fp_cpp, "#ifndef PRODUCT\n"); fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n"); - fprintf(fp_cpp, " static const char * bundle_flags[] = {\n"); - fprintf(fp_cpp, " \"\",\n"); - fprintf(fp_cpp, " \"use nop delay\",\n"); - fprintf(fp_cpp, " \"use unconditional delay\",\n"); - fprintf(fp_cpp, " \"use conditional delay\",\n"); - fprintf(fp_cpp, " \"used in conditional delay\",\n"); - fprintf(fp_cpp, " \"used in unconditional delay\",\n"); - fprintf(fp_cpp, " \"used in all conditional delays\",\n"); - fprintf(fp_cpp, " };\n\n"); - fprintf(fp_cpp, " static const char *resource_names[%d] = {", _pipeline->_rescount); // Don't add compound resources to the list of resource names const char* resource; @@ -1003,12 +992,8 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) { // See if the same string is in the table fprintf(fp_cpp, " bool needs_comma = false;\n\n"); - fprintf(fp_cpp, " if (_flags) {\n"); - fprintf(fp_cpp, " st->print(\"%%s\", bundle_flags[_flags]);\n"); - fprintf(fp_cpp, " needs_comma = true;\n"); - fprintf(fp_cpp, " };\n"); fprintf(fp_cpp, " if (instr_count()) {\n"); - fprintf(fp_cpp, " st->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n"); + fprintf(fp_cpp, " st->print(\"%%d instr%%s\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n"); fprintf(fp_cpp, " needs_comma = true;\n"); fprintf(fp_cpp, " };\n"); fprintf(fp_cpp, " uint r = resources_used();\n"); diff --git a/src/hotspot/share/adlc/output_h.cpp b/src/hotspot/share/adlc/output_h.cpp index 78cf5ea7988..e3fde235443 100644 --- a/src/hotspot/share/adlc/output_h.cpp +++ b/src/hotspot/share/adlc/output_h.cpp @@ -935,8 +935,6 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { _pipeline->_variableSizeInstrs ? 1 : 0); fprintf(fp_hpp, " _fixed_size_instructions = %d,\n", _pipeline->_variableSizeInstrs ? 0 : 1); - fprintf(fp_hpp, " _branch_has_delay_slot = %d,\n", - _pipeline->_branchHasDelaySlot ? 1 : 0); fprintf(fp_hpp, " _max_instrs_per_bundle = %d,\n", _pipeline->_maxInstrsPerBundle); fprintf(fp_hpp, " _max_bundles_per_cycle = %d,\n", @@ -983,7 +981,6 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { fprintf(fp_hpp, " const unsigned char _fixed_latency;\n"); fprintf(fp_hpp, " const unsigned char _instruction_count;\n"); fprintf(fp_hpp, " const bool _has_fixed_latency;\n"); - fprintf(fp_hpp, " const bool _has_branch_delay;\n"); fprintf(fp_hpp, " const bool _has_multiple_bundles;\n"); fprintf(fp_hpp, " const bool _force_serialization;\n"); fprintf(fp_hpp, " const bool _may_have_no_code;\n"); @@ -998,7 +995,6 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { fprintf(fp_hpp, " bool has_fixed_latency,\n"); fprintf(fp_hpp, " uint fixed_latency,\n"); fprintf(fp_hpp, " uint instruction_count,\n"); - fprintf(fp_hpp, " bool has_branch_delay,\n"); fprintf(fp_hpp, " bool has_multiple_bundles,\n"); fprintf(fp_hpp, " bool force_serialization,\n"); fprintf(fp_hpp, " bool may_have_no_code,\n"); @@ -1011,7 +1007,6 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { fprintf(fp_hpp, " , _fixed_latency(fixed_latency)\n"); fprintf(fp_hpp, " , _instruction_count(instruction_count)\n"); fprintf(fp_hpp, " , _has_fixed_latency(has_fixed_latency)\n"); - fprintf(fp_hpp, " , _has_branch_delay(has_branch_delay)\n"); fprintf(fp_hpp, " , _has_multiple_bundles(has_multiple_bundles)\n"); fprintf(fp_hpp, " , _force_serialization(force_serialization)\n"); fprintf(fp_hpp, " , _may_have_no_code(may_have_no_code)\n"); @@ -1046,8 +1041,6 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { fprintf(fp_hpp, " return (_resource_use._count); }\n\n"); fprintf(fp_hpp, " uint instructionCount() const {\n"); fprintf(fp_hpp, " return (_instruction_count); }\n\n"); - fprintf(fp_hpp, " bool hasBranchDelay() const {\n"); - fprintf(fp_hpp, " return (_has_branch_delay); }\n\n"); fprintf(fp_hpp, " bool hasMultipleBundles() const {\n"); fprintf(fp_hpp, " return (_has_multiple_bundles); }\n\n"); fprintf(fp_hpp, " bool forceSerialization() const {\n"); @@ -1071,50 +1064,19 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { uint rshift = rescount; fprintf(fp_hpp, "protected:\n"); - fprintf(fp_hpp, " enum {\n"); - fprintf(fp_hpp, " _unused_delay = 0x%x,\n", 0); - fprintf(fp_hpp, " _use_nop_delay = 0x%x,\n", 1); - fprintf(fp_hpp, " _use_unconditional_delay = 0x%x,\n", 2); - fprintf(fp_hpp, " _use_conditional_delay = 0x%x,\n", 3); - fprintf(fp_hpp, " _used_in_conditional_delay = 0x%x,\n", 4); - fprintf(fp_hpp, " _used_in_unconditional_delay = 0x%x,\n", 5); - fprintf(fp_hpp, " _used_in_all_conditional_delays = 0x%x,\n", 6); - fprintf(fp_hpp, "\n"); - fprintf(fp_hpp, " _use_delay = 0x%x,\n", 3); - fprintf(fp_hpp, " _used_in_delay = 0x%x\n", 4); - fprintf(fp_hpp, " };\n\n"); - fprintf(fp_hpp, " uint _flags : 3,\n"); - fprintf(fp_hpp, " _starts_bundle : 1,\n"); + fprintf(fp_hpp, " uint _starts_bundle : 1,\n"); fprintf(fp_hpp, " _instr_count : %d,\n", mshift); fprintf(fp_hpp, " _resources_used : %d;\n", rshift); fprintf(fp_hpp, "public:\n"); - fprintf(fp_hpp, " Bundle() : _flags(_unused_delay), _starts_bundle(0), _instr_count(0), _resources_used(0) {}\n\n"); + fprintf(fp_hpp, " Bundle() : _starts_bundle(0), _instr_count(0), _resources_used(0) {}\n\n"); fprintf(fp_hpp, " void set_instr_count(uint i) { _instr_count = i; }\n"); fprintf(fp_hpp, " void set_resources_used(uint i) { _resources_used = i; }\n"); - fprintf(fp_hpp, " void clear_usage() { _flags = _unused_delay; }\n"); fprintf(fp_hpp, " void set_starts_bundle() { _starts_bundle = true; }\n"); - fprintf(fp_hpp, " uint flags() const { return (_flags); }\n"); fprintf(fp_hpp, " uint instr_count() const { return (_instr_count); }\n"); fprintf(fp_hpp, " uint resources_used() const { return (_resources_used); }\n"); fprintf(fp_hpp, " bool starts_bundle() const { return (_starts_bundle != 0); }\n"); - fprintf(fp_hpp, " void set_use_nop_delay() { _flags = _use_nop_delay; }\n"); - fprintf(fp_hpp, " void set_use_unconditional_delay() { _flags = _use_unconditional_delay; }\n"); - fprintf(fp_hpp, " void set_use_conditional_delay() { _flags = _use_conditional_delay; }\n"); - fprintf(fp_hpp, " void set_used_in_unconditional_delay() { _flags = _used_in_unconditional_delay; }\n"); - fprintf(fp_hpp, " void set_used_in_conditional_delay() { _flags = _used_in_conditional_delay; }\n"); - fprintf(fp_hpp, " void set_used_in_all_conditional_delays() { _flags = _used_in_all_conditional_delays; }\n"); - - fprintf(fp_hpp, " bool use_nop_delay() { return (_flags == _use_nop_delay); }\n"); - fprintf(fp_hpp, " bool use_unconditional_delay() { return (_flags == _use_unconditional_delay); }\n"); - fprintf(fp_hpp, " bool use_conditional_delay() { return (_flags == _use_conditional_delay); }\n"); - fprintf(fp_hpp, " bool used_in_unconditional_delay() { return (_flags == _used_in_unconditional_delay); }\n"); - fprintf(fp_hpp, " bool used_in_conditional_delay() { return (_flags == _used_in_conditional_delay); }\n"); - fprintf(fp_hpp, " bool used_in_all_conditional_delays() { return (_flags == _used_in_all_conditional_delays); }\n"); - fprintf(fp_hpp, " bool use_delay() { return ((_flags & _use_delay) != 0); }\n"); - fprintf(fp_hpp, " bool used_in_delay() { return ((_flags & _used_in_delay) != 0); }\n\n"); - fprintf(fp_hpp, "#ifndef PRODUCT\n"); fprintf(fp_hpp, " void dump(outputStream *st = tty) const;\n"); fprintf(fp_hpp, "#endif\n"); diff --git a/src/hotspot/share/c1/c1_LIR.cpp b/src/hotspot/share/c1/c1_LIR.cpp index 4c8ebd5a09d..f11e178bd55 100644 --- a/src/hotspot/share/c1/c1_LIR.cpp +++ b/src/hotspot/share/c1/c1_LIR.cpp @@ -800,15 +800,6 @@ void LIR_OpVisitState::visit(LIR_Op* op) { } -// LIR_OpDelay - case lir_delay_slot: { - assert(op->as_OpDelay() != nullptr, "must be"); - LIR_OpDelay* opDelay = (LIR_OpDelay*)op; - - visit(opDelay->delay_op()); - break; - } - // LIR_OpTypeCheck case lir_instanceof: case lir_checkcast: @@ -1073,10 +1064,6 @@ void LIR_OpAssert::emit_code(LIR_Assembler* masm) { } #endif -void LIR_OpDelay::emit_code(LIR_Assembler* masm) { - masm->emit_delay(this); -} - void LIR_OpProfileCall::emit_code(LIR_Assembler* masm) { masm->emit_profile_call(this); } @@ -1761,8 +1748,6 @@ const char * LIR_Op::name() const { // LIR_OpLock case lir_lock: s = "lock"; break; case lir_unlock: s = "unlock"; break; - // LIR_OpDelay - case lir_delay_slot: s = "delay"; break; // LIR_OpTypeCheck case lir_instanceof: s = "instanceof"; break; case lir_checkcast: s = "checkcast"; break; @@ -2044,11 +2029,6 @@ void LIR_OpAssert::print_instr(outputStream* out) const { #endif -void LIR_OpDelay::print_instr(outputStream* out) const { - _op->print_on(out); -} - - // LIR_OpProfileCall void LIR_OpProfileCall::print_instr(outputStream* out) const { profiled_method()->name()->print_symbol_on(out); diff --git a/src/hotspot/share/c1/c1_LIR.hpp b/src/hotspot/share/c1/c1_LIR.hpp index c7726bf5c3f..0427c868e6f 100644 --- a/src/hotspot/share/c1/c1_LIR.hpp +++ b/src/hotspot/share/c1/c1_LIR.hpp @@ -879,7 +879,6 @@ class LIR_OpConvert; class LIR_OpAllocObj; class LIR_OpReturn; class LIR_Op2; -class LIR_OpDelay; class LIR_Op3; class LIR_OpAllocArray; class LIR_Op4; @@ -985,9 +984,6 @@ enum LIR_Code { , lir_lock , lir_unlock , end_opLock - , begin_delay_slot - , lir_delay_slot - , end_delay_slot , begin_opTypeCheck , lir_instanceof , lir_checkcast @@ -1124,7 +1120,6 @@ class LIR_Op: public CompilationResourceObj { virtual LIR_OpCall* as_OpCall() { return nullptr; } virtual LIR_OpJavaCall* as_OpJavaCall() { return nullptr; } virtual LIR_OpLabel* as_OpLabel() { return nullptr; } - virtual LIR_OpDelay* as_OpDelay() { return nullptr; } virtual LIR_OpLock* as_OpLock() { return nullptr; } virtual LIR_OpAllocArray* as_OpAllocArray() { return nullptr; } virtual LIR_OpAllocObj* as_OpAllocObj() { return nullptr; } @@ -1886,25 +1881,6 @@ class LIR_OpLoadKlass: public LIR_Op { void print_instr(outputStream* out) const PRODUCT_RETURN; }; -class LIR_OpDelay: public LIR_Op { - friend class LIR_OpVisitState; - - private: - LIR_Op* _op; - - public: - LIR_OpDelay(LIR_Op* op, CodeEmitInfo* info): - LIR_Op(lir_delay_slot, LIR_OprFact::illegalOpr, info), - _op(op) { - assert(op->code() == lir_nop, "should be filling with nops"); - } - virtual void emit_code(LIR_Assembler* masm); - virtual LIR_OpDelay* as_OpDelay() { return this; } - void print_instr(outputStream* out) const PRODUCT_RETURN; - LIR_Op* delay_op() const { return _op; } - CodeEmitInfo* call_info() const { return info(); } -}; - #ifdef ASSERT // LIR_OpAssert class LIR_OpAssert : public LIR_Op2 { diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 7cf414ae7dc..6dbd35f054f 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -194,8 +194,7 @@ void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) { XHandler* handler = handlers->handler_at(j); assert(handler->lir_op_id() != -1, "handler not processed by LinearScan"); assert(handler->entry_code() == nullptr || - handler->entry_code()->instructions_list()->last()->code() == lir_branch || - handler->entry_code()->instructions_list()->last()->code() == lir_delay_slot, "last operation must be branch"); + handler->entry_code()->instructions_list()->last()->code() == lir_branch, "last operation must be branch"); if (handler->entry_pco() == -1) { // entry code not emitted yet diff --git a/src/hotspot/share/c1/c1_LIRAssembler.hpp b/src/hotspot/share/c1/c1_LIRAssembler.hpp index a4c5fd61d4c..4cb313af901 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.hpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, 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 @@ -154,8 +154,7 @@ class LIR_Assembler: public CompilationResourceObj { void emit_block(BlockBegin* block); void emit_lir_list(LIR_List* list); - // any last minute peephole optimizations are performed here. In - // particular sparc uses this for delay slot filling. + // any last minute peephole optimizations are performed here. void peephole(LIR_List* list); void return_op(LIR_Opr result, C1SafepointPollStub* code_stub); @@ -204,7 +203,6 @@ class LIR_Assembler: public CompilationResourceObj { void emit_rtcall(LIR_OpRTCall* op); void emit_profile_call(LIR_OpProfileCall* op); void emit_profile_type(LIR_OpProfileType* op); - void emit_delay(LIR_OpDelay* op); void arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info); void arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info); diff --git a/src/hotspot/share/code/relocInfo.hpp b/src/hotspot/share/code/relocInfo.hpp index 714a964b28d..a6a08815d10 100644 --- a/src/hotspot/share/code/relocInfo.hpp +++ b/src/hotspot/share/code/relocInfo.hpp @@ -186,8 +186,7 @@ class nmethod; // relative offset. (Both n and l are relative to the call's first byte.) // // The limit l of the search is exclusive. However, if it points within -// the call (e.g., offset zero), it is adjusted to point after the call and -// any associated machine-specific delay slot. +// the call (e.g., offset zero), it is adjusted to point after the call. // // Since the offsets could be as wide as 32-bits, these conventions // put no restrictions whatever upon code reorganization. @@ -1109,7 +1108,6 @@ class virtual_call_Relocation : public CallRelocation { // data is packed as scaled offsets in "2_ints" format: [f l] or [Ff Ll] // oop_limit is set to 0 if the limit falls somewhere within the call. // When unpacking, a zero oop_limit is taken to refer to the end of the call. - // (This has the effect of bringing in the call's delay slot on SPARC.) void pack_data_to(CodeSection* dest) override; void unpack_data() override; diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 9a6970ebf20..90d24b609a7 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -106,12 +106,6 @@ private: // Remember the next node Node *_next_node; - // Use this for an unconditional branch delay slot - Node *_unconditional_delay_slot; - - // Pointer to a Nop - MachNopNode *_nop; - // Length of the current bundle, in instructions uint _bundle_instr_count; @@ -128,9 +122,6 @@ private: public: Scheduling(Arena *arena, Compile &compile); - // Destructor - NOT_PRODUCT( ~Scheduling(); ) - // Step ahead "i" cycles void step(uint i); @@ -194,10 +185,7 @@ public: #ifndef PRODUCT private: // Gather information on size of nops relative to total - uint _branches, _unconditional_delays; - static uint _total_nop_size, _total_method_size; - static uint _total_branches, _total_unconditional_delays; static uint _total_instructions_per_bundle[Pipeline::_max_instrs_per_cycle+1]; public: @@ -1472,7 +1460,6 @@ void PhaseOutput::fill_buffer(C2_MacroAssembler* masm, uint* blk_starts) { } // Now fill in the code buffer - Node* delay_slot = nullptr; for (uint i = 0; i < nblocks; i++) { Block* block = C->cfg()->get_block(i); _block = block; @@ -1511,15 +1498,6 @@ void PhaseOutput::fill_buffer(C2_MacroAssembler* masm, uint* blk_starts) { // Get the node Node* n = block->get_node(j); - // See if delay slots are supported - if (valid_bundle_info(n) && node_bundling(n)->used_in_unconditional_delay()) { - assert(delay_slot == nullptr, "no use of delay slot node"); - assert(n->size(C->regalloc()) == Pipeline::instr_unit_size(), "delay slot instruction wrong size"); - - delay_slot = n; - continue; - } - // If this starts a new instruction group, then flush the current one // (but allow split bundles) if (Pipeline::requires_bundling() && starts_bundle(n)) @@ -1538,9 +1516,6 @@ void PhaseOutput::fill_buffer(C2_MacroAssembler* masm, uint* blk_starts) { current_offset = masm->offset(); } - // A padding may be needed again since a previous instruction - // could be moved to delay slot. - // align the instruction if necessary int padding = mach->compute_padding(current_offset); // Make sure safepoint node for polling is distinct from a call's @@ -1613,13 +1588,10 @@ void PhaseOutput::fill_buffer(C2_MacroAssembler* masm, uint* blk_starts) { // This requires the TRUE branch target be in succs[0] uint block_num = block->non_connector_successor(0)->_pre_order; - // Try to replace long branch if delay slot is not used, + // Try to replace long branch, // it is mostly for back branches since forward branch's // distance is not updated yet. - bool delay_slot_is_used = valid_bundle_info(n) && - C->output()->node_bundling(n)->use_unconditional_delay(); - if (!delay_slot_is_used && mach->may_be_short_branch()) { - assert(delay_slot == nullptr, "not expecting delay slot node"); + if (mach->may_be_short_branch()) { int br_size = n->size(C->regalloc()); int offset = blk_starts[block_num] - current_offset; if (block_num >= i) { @@ -1753,44 +1725,6 @@ void PhaseOutput::fill_buffer(C2_MacroAssembler* masm, uint* blk_starts) { last_avoid_back_to_back_offset = current_offset; } - // See if this instruction has a delay slot - if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { - guarantee(delay_slot != nullptr, "expecting delay slot node"); - - // Back up 1 instruction - masm->code()->set_insts_end(masm->code()->insts_end() - Pipeline::instr_unit_size()); - - // Save the offset for the listing -#if defined(SUPPORT_OPTO_ASSEMBLY) - if ((node_offsets != nullptr) && (delay_slot->_idx < node_offset_limit)) { - node_offsets[delay_slot->_idx] = masm->offset(); - } -#endif - - // Support a SafePoint in the delay slot - if (delay_slot->is_MachSafePoint()) { - MachNode *mach = delay_slot->as_Mach(); - // !!!!! Stubs only need an oopmap right now, so bail out - if (!mach->is_MachCall() && mach->as_MachSafePoint()->jvms()->method() == nullptr) { - // Write the oopmap directly to the code blob??!! - delay_slot = nullptr; - continue; - } - - int adjusted_offset = current_offset - Pipeline::instr_unit_size(); - non_safepoints.observe_safepoint(mach->as_MachSafePoint()->jvms(), - adjusted_offset); - // Generate an OopMap entry - Process_OopMap_Node(mach, adjusted_offset); - } - - // Insert the delay slot instruction - delay_slot->emit(masm, C->regalloc()); - - // Don't reuse it - delay_slot = nullptr; - } - } // End for all instructions in block // If the next block is the top of a loop, pad this block out to align @@ -2031,8 +1965,6 @@ void PhaseOutput::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_s #ifndef PRODUCT uint Scheduling::_total_nop_size = 0; uint Scheduling::_total_method_size = 0; -uint Scheduling::_total_branches = 0; -uint Scheduling::_total_unconditional_delays = 0; uint Scheduling::_total_instructions_per_bundle[Pipeline::_max_instrs_per_cycle+1]; #endif @@ -2050,14 +1982,7 @@ Scheduling::Scheduling(Arena *arena, Compile &compile) _bundle_instr_count(0), _bundle_cycle_number(0), _bundle_use(0, 0, resource_count, &_bundle_use_elements[0]) -#ifndef PRODUCT - , _branches(0) - , _unconditional_delays(0) -#endif { - // Create a MachNopNode - _nop = new MachNopNode(); - // Save the count _node_bundling_limit = compile.unique(); uint node_max = _regalloc->node_regs_max_index(); @@ -2087,14 +2012,6 @@ Scheduling::Scheduling(Arena *arena, Compile &compile) _next_node = block->get_node(block->number_of_nodes() - 1); } -#ifndef PRODUCT -// Scheduling destructor -Scheduling::~Scheduling() { - _total_branches += _branches; - _total_unconditional_delays += _unconditional_delays; -} -#endif - // Step ahead "i" cycles void Scheduling::step(uint i) { @@ -2199,15 +2116,6 @@ void PhaseOutput::print_scheduling(outputStream* output_stream) { bool Scheduling::NodeFitsInBundle(Node *n) { uint n_idx = n->_idx; - // If this is the unconditional delay instruction, then it fits - if (n == _unconditional_delay_slot) { -#ifndef PRODUCT - if (_cfg->C->trace_opto_output()) - tty->print("# NodeFitsInBundle [%4d]: TRUE; is in unconditional delay slot\n", n->_idx); -#endif - return (true); - } - // If the node cannot be scheduled this cycle, skip it if (_current_latency[n_idx] > _bundle_cycle_number) { #ifndef PRODUCT @@ -2223,8 +2131,6 @@ bool Scheduling::NodeFitsInBundle(Node *n) { uint instruction_count = node_pipeline->instructionCount(); if (node_pipeline->mayHaveNoCode() && n->size(_regalloc) == 0) instruction_count = 0; - else if (node_pipeline->hasBranchDelay() && !_unconditional_delay_slot) - instruction_count++; if (_bundle_instr_count + instruction_count > Pipeline::_max_instrs_per_cycle) { #ifndef PRODUCT @@ -2436,99 +2342,6 @@ void Scheduling::AddNodeToBundle(Node *n, const Block *bb) { const Pipeline *node_pipeline = n->pipeline(); const Pipeline_Use& node_usage = node_pipeline->resourceUse(); - // Check for instructions to be placed in the delay slot. We - // do this before we actually schedule the current instruction, - // because the delay slot follows the current instruction. - if (Pipeline::_branch_has_delay_slot && - node_pipeline->hasBranchDelay() && - !_unconditional_delay_slot) { - - uint siz = _available.size(); - - // Conditional branches can support an instruction that - // is unconditionally executed and not dependent by the - // branch, OR a conditionally executed instruction if - // the branch is taken. In practice, this means that - // the first instruction at the branch target is - // copied to the delay slot, and the branch goes to - // the instruction after that at the branch target - if ( n->is_MachBranch() ) { - - assert( !n->is_MachNullCheck(), "should not look for delay slot for Null Check" ); - assert( !n->is_Catch(), "should not look for delay slot for Catch" ); - -#ifndef PRODUCT - _branches++; -#endif - - // At least 1 instruction is on the available list - // that is not dependent on the branch - for (uint i = 0; i < siz; i++) { - Node *d = _available[i]; - const Pipeline *avail_pipeline = d->pipeline(); - - // Don't allow safepoints in the branch shadow, that will - // cause a number of difficulties - if ( avail_pipeline->instructionCount() == 1 && - !avail_pipeline->hasMultipleBundles() && - !avail_pipeline->hasBranchDelay() && - Pipeline::instr_has_unit_size() && - d->size(_regalloc) == Pipeline::instr_unit_size() && - NodeFitsInBundle(d) && - !node_bundling(d)->used_in_delay()) { - - if (d->is_Mach() && !d->is_MachSafePoint()) { - // A node that fits in the delay slot was found, so we need to - // set the appropriate bits in the bundle pipeline information so - // that it correctly indicates resource usage. Later, when we - // attempt to add this instruction to the bundle, we will skip - // setting the resource usage. - _unconditional_delay_slot = d; - node_bundling(n)->set_use_unconditional_delay(); - node_bundling(d)->set_used_in_unconditional_delay(); - _bundle_use.add_usage(avail_pipeline->resourceUse()); - _current_latency[d->_idx] = _bundle_cycle_number; - _next_node = d; - ++_bundle_instr_count; -#ifndef PRODUCT - _unconditional_delays++; -#endif - break; - } - } - } - } - - // No delay slot, add a nop to the usage - if (!_unconditional_delay_slot) { - // See if adding an instruction in the delay slot will overflow - // the bundle. - if (!NodeFitsInBundle(_nop)) { -#ifndef PRODUCT - if (_cfg->C->trace_opto_output()) - tty->print("# *** STEP(1 instruction for delay slot) ***\n"); -#endif - step(1); - } - - _bundle_use.add_usage(_nop->pipeline()->resourceUse()); - _next_node = _nop; - ++_bundle_instr_count; - } - - // See if the instruction in the delay slot requires a - // step of the bundles - if (!NodeFitsInBundle(n)) { -#ifndef PRODUCT - if (_cfg->C->trace_opto_output()) - tty->print("# *** STEP(branch won't fit) ***\n"); -#endif - // Update the state information - _bundle_instr_count = 0; - _bundle_cycle_number += 1; - _bundle_use.step(1); - } - } // Get the number of instructions uint instruction_count = node_pipeline->instructionCount(); @@ -2556,47 +2369,40 @@ void Scheduling::AddNodeToBundle(Node *n, const Block *bb) { } } - // If this was placed in the delay slot, ignore it - if (n != _unconditional_delay_slot) { - - if (delay == 0) { - if (node_pipeline->hasMultipleBundles()) { + if (delay == 0) { + if (node_pipeline->hasMultipleBundles()) { #ifndef PRODUCT - if (_cfg->C->trace_opto_output()) - tty->print("# *** STEP(multiple instructions) ***\n"); + if (_cfg->C->trace_opto_output()) + tty->print("# *** STEP(multiple instructions) ***\n"); #endif - step(1); - } - - else if (instruction_count + _bundle_instr_count > Pipeline::_max_instrs_per_cycle) { -#ifndef PRODUCT - if (_cfg->C->trace_opto_output()) - tty->print("# *** STEP(%d >= %d instructions) ***\n", - instruction_count + _bundle_instr_count, - Pipeline::_max_instrs_per_cycle); -#endif - step(1); - } + step(1); } - if (node_pipeline->hasBranchDelay() && !_unconditional_delay_slot) - _bundle_instr_count++; - - // Set the node's latency - _current_latency[n->_idx] = _bundle_cycle_number; - - // Now merge the functional unit information - if (instruction_count > 0 || !node_pipeline->mayHaveNoCode()) - _bundle_use.add_usage(node_usage); - - // Increment the number of instructions in this bundle - _bundle_instr_count += instruction_count; - - // Remember this node for later - if (n->is_Mach()) - _next_node = n; + else if (instruction_count + _bundle_instr_count > Pipeline::_max_instrs_per_cycle) { +#ifndef PRODUCT + if (_cfg->C->trace_opto_output()) + tty->print("# *** STEP(%d >= %d instructions) ***\n", + instruction_count + _bundle_instr_count, + Pipeline::_max_instrs_per_cycle); +#endif + step(1); + } } + // Set the node's latency + _current_latency[n->_idx] = _bundle_cycle_number; + + // Now merge the functional unit information + if (instruction_count > 0 || !node_pipeline->mayHaveNoCode()) + _bundle_use.add_usage(node_usage); + + // Increment the number of instructions in this bundle + _bundle_instr_count += instruction_count; + + // Remember this node for later + if (n->is_Mach()) + _next_node = n; + // It's possible to have a BoxLock in the graph and in the _bbs mapping but // not in the bb->_nodes array. This happens for debug-info-only BoxLocks. // 'Schedule' them (basically ignore in the schedule) but do not insert them @@ -2647,9 +2453,6 @@ void Scheduling::ComputeUseCount(const Block *bb) { _available.clear(); _scheduled.clear(); - // No delay slot specified - _unconditional_delay_slot = nullptr; - #ifdef ASSERT for( uint i=0; i < bb->number_of_nodes(); i++ ) assert( _uses[bb->get_node(i)->_idx] == 0, "_use array not clean" ); @@ -2767,11 +2570,7 @@ void Scheduling::DoScheduling() { break; // Funny loop structure to be sure... } // Compute last "interesting" instruction in block - last instruction we - // might schedule. _bb_end points just after last schedulable inst. We - // normally schedule conditional branches (despite them being forced last - // in the block), because they have delay slots we can fill. Calls all - // have their delay slots filled in the template expansions, so we don't - // bother scheduling them. + // might schedule. _bb_end points just after last schedulable inst. Node *last = bb->get_node(_bb_end); // Ignore trailing NOPs. while (_bb_end > 0 && last->is_Mach() && @@ -2837,7 +2636,7 @@ void Scheduling::DoScheduling() { Node *n = bb->get_node(j); if( valid_bundle_info(n) ) { Bundle *bundle = node_bundling(n); - if (bundle->instr_count() > 0 || bundle->flags() > 0) { + if (bundle->instr_count() > 0) { tty->print("*** Bundle: "); bundle->dump(); } @@ -3273,16 +3072,6 @@ void Scheduling::print_statistics() { ((double)_total_nop_size) / ((double) _total_method_size) * 100.0); tty->print("\n"); - // Print the number of branch shadows filled - if (Pipeline::_branch_has_delay_slot) { - tty->print("Of %d branches, %d had unconditional delay slots filled", - _total_branches, _total_unconditional_delays); - if (_total_branches > 0) - tty->print(", for %.2f%%", - ((double)_total_unconditional_delays) / ((double)_total_branches) * 100.0); - tty->print("\n"); - } - uint total_instructions = 0, total_bundles = 0; for (uint i = 1; i <= Pipeline::_max_instrs_per_cycle; i++) { @@ -3572,7 +3361,6 @@ void PhaseOutput::dump_asm_on(outputStream* st, int* pcs, uint pc_limit) { } // For all instructions - Node *delay = nullptr; for (uint j = 0; j < block->number_of_nodes(); j++) { if (VMThread::should_terminate()) { cut_short = true; @@ -3581,10 +3369,6 @@ void PhaseOutput::dump_asm_on(outputStream* st, int* pcs, uint pc_limit) { n = block->get_node(j); if (valid_bundle_info(n)) { Bundle* bundle = node_bundling(n); - if (bundle->used_in_unconditional_delay()) { - delay = n; - continue; - } if (bundle->starts_bundle()) { starts_bundle = '+'; } @@ -3617,29 +3401,6 @@ void PhaseOutput::dump_asm_on(outputStream* st, int* pcs, uint pc_limit) { st->cr(); } - // If we have an instruction with a delay slot, and have seen a delay, - // then back up and print it - if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { - // Coverity finding - Explicit null dereferenced. - guarantee(delay != nullptr, "no unconditional delay instruction"); - if (WizardMode) delay->dump(); - - if (node_bundling(delay)->starts_bundle()) - starts_bundle = '+'; - if ((pcs != nullptr) && (n->_idx < pc_limit)) { - pc = pcs[n->_idx]; - st->print("%*.*x", pc_digits, pc_digits, pc); - } else { - st->fill_to(pc_digits); - } - st->print(" %c ", starts_bundle); - starts_bundle = ' '; - st->fill_to(prefix_len); - delay->format(C->regalloc(), st); - st->cr(); - delay = nullptr; - } - // Dump the exception table as well if( n->is_Catch() && (Verbose || WizardMode) ) { // Print the exception table for this offset @@ -3648,7 +3409,6 @@ void PhaseOutput::dump_asm_on(outputStream* st, int* pcs, uint pc_limit) { st->bol(); // Make sure we start on a new line } st->cr(); // one empty line between blocks - assert(cut_short || delay == nullptr, "no unconditional delay branch"); } // End of per-block dump if (cut_short) st->print_cr("*** disassembly is cut short ***"); diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 60161643315..710d34c3ccb 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -3502,8 +3502,6 @@ frame SharedRuntime::look_for_reserved_stack_annotated_method(JavaThread* curren if (cb != nullptr && cb->is_nmethod()) { nm = cb->as_nmethod(); method = nm->method(); - // scope_desc_near() must be used, instead of scope_desc_at() because on - // SPARC, the pcDesc can be on the delay slot after the call instruction. for (ScopeDesc *sd = nm->scope_desc_near(fr.pc()); sd != nullptr; sd = sd->sender()) { method = sd->method(); if (method != nullptr && method->has_reserved_stack_access()) { From 9e3fa3216fd4ebd73da6e003a7b767cf001a1169 Mon Sep 17 00:00:00 2001 From: Kazuhisa Takakuri Date: Wed, 10 Sep 2025 06:37:17 +0000 Subject: [PATCH 013/120] 8349288: runtime/os/windows/TestAvailableProcessors.java fails on localized Windows platform Reviewed-by: dholmes, alanb --- .../os/windows/TestAvailableProcessors.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java b/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java index 795b3d76e54..f15514d024e 100644 --- a/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java +++ b/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java @@ -34,6 +34,7 @@ * @run testng/othervm/native TestAvailableProcessors */ +import java.io.File; import java.io.IOException; import java.util.List; import java.util.HashSet; @@ -58,7 +59,23 @@ public class TestAvailableProcessors { private static String getWindowsVersion() throws IOException { String systeminfoPath = "systeminfo.exe"; - var processBuilder = new ProcessBuilder(systeminfoPath); + List command = new ArrayList<>(); + + String systemRoot = System.getenv("SystemRoot"); + if (systemRoot == null) { + systemRoot = System.getenv("WINDIR"); + if (systemRoot == null) { + throw new RuntimeException("SystemRoot or WINDIR environment variable is not set."); + } + } + String system32 = Path.of(systemRoot, "System32").toString(); + + // It switches the active code page to cp437, the default code page for US english. + command.addAll(List.of("cmd.exe", "/c", "set", "PATH=%PATH%;" + system32 + ";" + system32 + "\\wbem", "&&")); + command.addAll(List.of("chcp", "437", ">nul", "2>&1", "&&")); + command.add(systeminfoPath); + + var processBuilder = new ProcessBuilder(command); OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start()); outputAnalyzer.shouldHaveExitValue(0); outputAnalyzer.shouldContain(osVersionMessage); From f3de386263e16e33c2812706cf41410da2cd58c6 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 10 Sep 2025 08:46:07 +0000 Subject: [PATCH 014/120] 8367309: Test runtime/os/windows/TestAvailableProcessors.java fails to compile after mis-merge Reviewed-by: shade, alanb --- .../jtreg/runtime/os/windows/TestAvailableProcessors.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java b/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java index f15514d024e..d5e5b1626b6 100644 --- a/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java +++ b/test/hotspot/jtreg/runtime/os/windows/TestAvailableProcessors.java @@ -34,8 +34,10 @@ * @run testng/othervm/native TestAvailableProcessors */ -import java.io.File; + import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.HashSet; import java.util.Set; From 1d3364b00725f9d2afa8274e2244357a109be545 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 10 Sep 2025 09:45:05 +0000 Subject: [PATCH 015/120] 8365239: Spec Clarification - InterfaceAddress:getBroadcast() returning null for loop back address Reviewed-by: msheppar, djelinski, jpai --- src/java.base/share/classes/java/net/InterfaceAddress.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/net/InterfaceAddress.java b/src/java.base/share/classes/java/net/InterfaceAddress.java index 6df2de353e3..44b3456c6fc 100644 --- a/src/java.base/share/classes/java/net/InterfaceAddress.java +++ b/src/java.base/share/classes/java/net/InterfaceAddress.java @@ -63,8 +63,8 @@ public final class InterfaceAddress { * Only IPv4 networks have broadcast address therefore, in the case * of an IPv6 network, {@code null} will be returned. *

      - * Certain network interfaces, such as the loopback interface, do not support - * broadcasting and will also return {@code null}. + * Some network interfaces do not support broadcasting and may + * also return {@code null}. * * @return the {@code InetAddress} representing the broadcast * address or {@code null} if there is no broadcast address. From 5c9f60dc5a6e64be55819469bbf10948803d0fd5 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 10 Sep 2025 09:57:44 +0000 Subject: [PATCH 016/120] 8367259: Clean up make/scripts and bin directory Reviewed-by: erikj --- {make/scripts => bin}/generate-symbol-data.sh | 31 ++- {make/scripts => bin}/lic_check.sh | 4 +- {make/scripts => bin}/normalizer.pl | 0 bin/unshuffle_list.txt | 191 -------------- bin/unshuffle_patch.sh | 237 ------------------ .../scripts => bin}/update_copyright_year.sh | 0 {make/scripts => bin}/update_pch.sh | 12 +- make/autoconf/compare.sh.template | 2 +- make/scripts/{logger.sh => compare-logger.sh} | 0 .../hide_important_warnings_from_javac.sh | 36 --- 10 files changed, 43 insertions(+), 470 deletions(-) rename {make/scripts => bin}/generate-symbol-data.sh (83%) rename {make/scripts => bin}/lic_check.sh (98%) rename {make/scripts => bin}/normalizer.pl (100%) delete mode 100644 bin/unshuffle_list.txt delete mode 100644 bin/unshuffle_patch.sh rename {make/scripts => bin}/update_copyright_year.sh (100%) rename {make/scripts => bin}/update_pch.sh (92%) rename make/scripts/{logger.sh => compare-logger.sh} (100%) delete mode 100644 make/scripts/hide_important_warnings_from_javac.sh diff --git a/make/scripts/generate-symbol-data.sh b/bin/generate-symbol-data.sh similarity index 83% rename from make/scripts/generate-symbol-data.sh rename to bin/generate-symbol-data.sh index 6f38d873009..283757a6918 100644 --- a/make/scripts/generate-symbol-data.sh +++ b/bin/generate-symbol-data.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2019, 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 @@ -52,12 +52,39 @@ # include the SCM state that was used to build it, which can be found in ${JDK_N_INSTALL}/release, # in property "SOURCE". +source_path="$(dirname ${0})" +this_script_dir="$(cd -- "${source_path}" > /dev/null && pwd)" +if test -z "${this_script_dir}"; then + echo "Error: Could not determine location of this script" + exit 1 +fi + +symbols_dir="$(dirname $this_script_dir)/src/jdk.compiler/share/data/symbols" +if [ ! -d $symbols_dir ] ; then + echo "Cannot locate symbols directory: $symbols_dir" >&2 + exit 1 +fi + +generator_dir="$(dirname $this_script_dir)/make/langtools/src/classes/build/tools/symbolgenerator" + if [ "$1x" = "x" ] ; then echo "Must provide the target JDK as a parameter:" >&2 echo "$0 " >&2 exit 1 fi; +if [ ! -d $1 ] ; then + echo "Target JDK argument is not a directory:" $1 >&2 + exit 1 +fi; + +if [ ! -x $1/bin/java ] ; then + echo "Target JDK argument is not a valid JDK: $1" >&2 + exit 1 +fi; + +cd $symbols_dir + if [ ! -f symbols ] ; then echo "Must run inside the src/jdk.compiler/share/data/symbols directory" >&2 exit 1 @@ -72,5 +99,5 @@ $1/bin/java --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ --add-modules jdk.jdeps \ - ../../../../../make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java \ + $generator_dir/CreateSymbols.java \ build-description-incremental symbols include.list diff --git a/make/scripts/lic_check.sh b/bin/lic_check.sh similarity index 98% rename from make/scripts/lic_check.sh rename to bin/lic_check.sh index d70d8914181..2fc6abf4d82 100644 --- a/make/scripts/lic_check.sh +++ b/bin/lic_check.sh @@ -1,6 +1,6 @@ #! /bin/sh -f # -# Copyright (c) 2012, 2020, 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 @@ -62,7 +62,7 @@ B=`basename "${script_directory}"` script_dir="`cd \"${D}\" 2>/dev/null && pwd || echo \"${D}\"`/${B}" # set up a variable for the template directory -template_dir=${script_dir}/../data/license-templates +template_dir=${script_dir}/../make/data/license-templates # Check existence of the template directory. if [ ! -d ${template_dir} ] ; then diff --git a/make/scripts/normalizer.pl b/bin/normalizer.pl similarity index 100% rename from make/scripts/normalizer.pl rename to bin/normalizer.pl diff --git a/bin/unshuffle_list.txt b/bin/unshuffle_list.txt deleted file mode 100644 index a910f6b4621..00000000000 --- a/bin/unshuffle_list.txt +++ /dev/null @@ -1,191 +0,0 @@ -# -# Copyright (c) 2014, 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -src/bsd : jdk/src/bsd -src/demo : jdk/src/demo -src/java.activation : jaxws/src/java.activation -src/java.base : jdk/src/java.base -src/java.compiler : langtools/src/java.compiler -src/java.corba : corba/src/java.corba -src/java.datatransfer : jdk/src/java.datatransfer -src/java.desktop : jdk/src/java.desktop -src/java.instrument : jdk/src/java.instrument -src/java.logging : jdk/src/java.logging -src/java.management : jdk/src/java.management -src/java.management.rmi : jdk/src/java.management.rmi -src/java.naming : jdk/src/java.naming -src/java.prefs : jdk/src/java.prefs -src/java.rmi : jdk/src/java.rmi -src/java.scripting : jdk/src/java.scripting -src/java.se : jdk/src/java.se -src/java.security.jgss : jdk/src/java.security.jgss -src/java.security.sasl : jdk/src/java.security.sasl -src/java.se.ee : jdk/src/java.se.ee -src/java.smartcardio : jdk/src/java.smartcardio -src/java.sql : jdk/src/java.sql -src/java.sql.rowset : jdk/src/java.sql.rowset -src/java.transaction : jdk/src/java.transaction -src/java.xml : jaxp/src/java.xml -src/java.xml.bind : jaxws/src/java.xml.bind -src/java.xml.crypto : jdk/src/java.xml.crypto -src/java.xml.ws : jaxws/src/java.xml.ws -src/java.xml.ws.annotation : jaxws/src/java.xml.ws.annotation -src/jdk.accessibility : jdk/src/jdk.accessibility -src/jdk.aot : hotspot/src/jdk.aot -src/jdk.attach : jdk/src/jdk.attach -src/jdk.charsets : jdk/src/jdk.charsets -src/jdk.compiler : jdk/src/jdk.compiler langtools/src/jdk.compiler -src/jdk.crypto.cryptoki : jdk/src/jdk.crypto.cryptoki -src/jdk.crypto.ec : jdk/src/jdk.crypto.ec -src/jdk.crypto.mscapi : jdk/src/jdk.crypto.mscapi -src/jdk.dynalink : nashorn/src/jdk.dynalink -src/jdk.editpad : jdk/src/jdk.editpad -src/jdk.hotspot.agent : hotspot/src/jdk.hotspot.agent -src/jdk.httpserver : jdk/src/jdk.httpserver -src/jdk.incubator.httpclient : jdk/src/jdk.incubator.httpclient -src/jdk.internal.ed : jdk/src/jdk.internal.ed -src/jdk.internal.jvmstat : jdk/src/jdk.internal.jvmstat -src/jdk.internal.le : jdk/src/jdk.internal.le -src/jdk.internal.opt : jdk/src/jdk.internal.opt -src/jdk.internal.vm.ci : hotspot/src/jdk.internal.vm.ci -src/jdk.internal.vm.compiler : hotspot/src/jdk.internal.vm.compiler -src/jdk.jartool : jdk/src/jdk.jartool -src/jdk.javadoc : langtools/src/jdk.javadoc -src/jdk.jcmd : jdk/src/jdk.jcmd -src/jdk.jconsole : jdk/src/jdk.jconsole -src/jdk.jdeps : langtools/src/jdk.jdeps -src/jdk.jdi : jdk/src/jdk.jdi -src/jdk.jdwp.agent : jdk/src/jdk.jdwp.agent -src/jdk.jlink : jdk/src/jdk.jlink -src/jdk.jshell : langtools/src/jdk.jshell -src/jdk.jstatd : jdk/src/jdk.jstatd -src/jdk.localedata : jdk/src/jdk.localedata -src/jdk.management : jdk/src/jdk.management -src/jdk.management.agent : jdk/src/jdk.management.agent -src/jdk.naming.dns : jdk/src/jdk.naming.dns -src/jdk.naming.rmi : jdk/src/jdk.naming.rmi -src/jdk.net : jdk/src/jdk.net -src/jdk.pack : jdk/src/jdk.pack -src/jdk.scripting.nashorn : nashorn/src/jdk.scripting.nashorn -src/jdk.scripting.nashorn.shell : nashorn/src/jdk.scripting.nashorn.shell -src/jdk.sctp : jdk/src/jdk.sctp -src/jdk.security.auth : jdk/src/jdk.security.auth -src/jdk.security.jgss : jdk/src/jdk.security.jgss -src/jdk.unsupported : jdk/src/jdk.unsupported -src/jdk.xml.bind : jaxws/src/jdk.xml.bind -src/jdk.xml.dom : jaxp/src/jdk.xml.dom -src/jdk.xml.ws : jaxws/src/jdk.xml.ws -src/jdk.zipfs : jdk/src/jdk.zipfs -src/langtools/sample : langtools/src/sample -src/linux : jdk/src/linux -src/sample : jdk/src/sample -src/hotspot/share : hotspot/src/share/vm -src/hotspot/cpu/aarch64 : hotspot/src/cpu/aarch64/vm -src/hotspot/cpu/arm : hotspot/src/cpu/arm/vm -src/hotspot/cpu/ppc : hotspot/src/cpu/ppc/vm -src/hotspot/cpu/s390 : hotspot/src/cpu/s390/vm -src/hotspot/cpu/x86 : hotspot/src/cpu/x86/vm -src/hotspot/cpu/zero : hotspot/src/cpu/zero/vm -src/hotspot/os/aix : hotspot/src/os/aix/vm -src/hotspot/os/bsd : hotspot/src/os/bsd/vm -src/hotspot/os/linux : hotspot/src/os/linux/vm -src/hotspot/os/posix/dtrace : hotspot/src/os/posix/dtrace -src/hotspot/os/posix : hotspot/src/os/posix/vm -src/hotspot/os/windows : hotspot/src/os/windows/vm -src/hotspot/os_cpu/aix_ppc : hotspot/src/os_cpu/aix_ppc/vm -src/hotspot/os_cpu/bsd_x86 : hotspot/src/os_cpu/bsd_x86/vm -src/hotspot/os_cpu/bsd_zero : hotspot/src/os_cpu/bsd_zero/vm -src/hotspot/os_cpu/linux_aarch64 : hotspot/src/os_cpu/linux_aarch64/vm -src/hotspot/os_cpu/linux_arm : hotspot/src/os_cpu/linux_arm/vm -src/hotspot/os_cpu/linux_ppc : hotspot/src/os_cpu/linux_ppc/vm -src/hotspot/os_cpu/linux_s390 : hotspot/src/os_cpu/linux_s390/vm -src/hotspot/os_cpu/linux_x86 : hotspot/src/os_cpu/linux_x86/vm -src/hotspot/os_cpu/linux_zero : hotspot/src/os_cpu/linux_zero/vm -src/hotspot/os_cpu/windows_x86 : hotspot/src/os_cpu/windows_x86/vm -src/hotspot : hotspot/src -src/utils/IdealGraphVisualizer : hotspot/src/share/tools/IdealGraphVisualizer -src/utils/LogCompilation : hotspot/src/share/tools/LogCompilation -src/utils/hsdis : hotspot/src/share/tools/hsdis -src/utils/reorder : jdk/make/non-build-utils/reorder -src/utils/src/build : jdk/make/non-build-utils/src/build -make/BuildNashorn.gmk : nashorn/make/BuildNashorn.gmk -make/CompileDemos.gmk : jdk/make/CompileDemos.gmk -make/CompileInterimLangtools.gmk : langtools/make/CompileInterim.gmk -make/CompileModuleTools.gmk : jdk/make/CompileModuleTools.gmk -make/CompileToolsHotspot.gmk : hotspot/make/CompileTools.gmk -make/CompileToolsJdk.gmk : jdk/make/CompileTools.gmk -make/CopyInterimCLDRConverter.gmk : jdk/make/CopyInterimCLDRConverter.gmk -make/GenerateModuleSummary.gmk : jdk/make/GenerateModuleSummary.gmk -make/ModuleTools.gmk : jdk/make/ModuleTools.gmk -make/ToolsJdk.gmk : jdk/make/Tools.gmk -make/ToolsLangtools.gmk : langtools/make/Tools.gmk -make/UnpackSecurity.gmk : jdk/make/UnpackSecurity.gmk -make/autoconf : common/autoconf -make/conf : common/conf -make/copy : jdk/make/copy -make/copy/Copy-java.corba.gmk : corba/make/copy/Copy-java.corba.gmk -make/corba : corba/make -make/data : jdk/make/data -make/gendata : jdk/make/gendata -make/gendata/Gendata-jdk.compiler.gmk : langtools/make/gendata/Gendata-jdk.compiler.gmk -make/gensrc : jdk/make/gensrc -make/gensrc/Gensrc-java.corba.gmk : corba/make/gensrc/Gensrc-java.corba.gmk -make/gensrc/Gensrc-jdk.compiler.gmk : langtools/make/gensrc/Gensrc-jdk.compiler.gmk -make/gensrc/Gensrc-jdk.hotspot.agent.gmk : hotspot/make/gensrc/Gensrc-jdk.hotspot.agent.gmk -make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk : hotspot/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk -make/gensrc/Gensrc-jdk.javadoc.gmk : langtools/make/gensrc/Gensrc-jdk.javadoc.gmk -make/gensrc/Gensrc-jdk.jdeps.gmk : langtools/make/gensrc/Gensrc-jdk.jdeps.gmk -make/gensrc/Gensrc-jdk.jshell.gmk : langtools/make/gensrc/Gensrc-jdk.jshell.gmk -make/gensrc/GensrcCommonLangtools.gmk : langtools/make/gensrc/GensrcCommon.gmk -make/hotspot : hotspot/make -make/jdk : jdk/make -make/langtools : langtools/make -make/launcher : jdk/make/launcher -make/lib : jdk/make/lib -make/lib/Lib-jdk.hotspot.agent.gmk : hotspot/make/lib/Lib-jdk.hotspot.agent.gmk -make/mapfiles : jdk/make/mapfiles -make/mapfiles/libjsig : hotspot/make/mapfiles/libjsig -make/mapfiles/libjvm_db : hotspot/make/mapfiles/libjvm_db -make/mapfiles/libjvm_dtrace : hotspot/make/mapfiles/libjvm_dtrace -make/mapfiles/libsaproc : hotspot/make/mapfiles/libsaproc -make/nashorn : nashorn/make -make/nb_native : common/nb_native -make/scripts/addNotices.sh : jdk/make/scripts/addNotices.sh -make/scripts/compare.sh : common/bin/compare.sh -make/scripts/compare_exceptions.sh.incl : common/bin/compare_exceptions.sh.incl -make/scripts/genExceptions.sh : jdk/make/scripts/genExceptions.sh -make/scripts/hide_important_warnings_from_javac.sh : common/bin/hide_important_warnings_from_javac.sh -make/scripts/logger.sh : common/bin/logger.sh -make/src/native/fixpath.c : common/src/fixpath.c -make/test/JtregNativeHotspot.gmk : hotspot/make/test/JtregNative.gmk -make/test/JtregNativeJdk.gmk : jdk/make/test/JtregNative.gmk -test/jdk : jdk/test -test/langtools : langtools/test -test/nashorn : nashorn/test -test/jaxp : jaxp/test -test/hotspot/gtest : hotspot/test/native -test/hotspot/jtreg : hotspot/test -bin : common/bin -bin/nashorn : nashorn/bin -doc : common/doc -doc/nashorn : nashorn/docs diff --git a/bin/unshuffle_patch.sh b/bin/unshuffle_patch.sh deleted file mode 100644 index c5cdc3851c3..00000000000 --- a/bin/unshuffle_patch.sh +++ /dev/null @@ -1,237 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# Script for updating a patch file as per the shuffled/unshuffled source location. - -usage() { - echo "Usage: $0 [-h|--help] [-v|--verbose] [-to9|-to10] [-r ] " - echo "where:" - echo " -to9 create patches appropriate for a JDK 9 source tree" - echo " When going to 9, the output patches will be suffixed with the" - echo " repo name" - echo " -to10 create patches appropriate for a JDK 10 source tree" - echo " -r specify repo for source patch, set to 'top' for top repo" - echo " is the input patch file, that needs shuffling/unshuffling" - echo " is the updated patch file " - echo " " - exit 1 -} - -SCRIPT_DIR=`dirname $0` -UNSHUFFLE_LIST=$SCRIPT_DIR"/unshuffle_list.txt" - -if [ ! -f "$UNSHUFFLE_LIST" ] ; then - echo "FATAL: cannot find $UNSHUFFLE_LIST" >&2 - exit 1 -fi - -vflag="false" -while [ $# -gt 0 ] -do - case $1 in - -h | --help ) - usage - ;; - - -v | --verbose ) - vflag="true" - ;; - - -r) - repo="$2" - shift - ;; - - -to9) - shuffle_to=9 - ;; - - -to10) - shuffle_to=10 - ;; - - -*) # bad option - usage - ;; - - * ) # non option - break - ;; - esac - shift -done - -# Make sure we have the right number of arguments -if [ ! $# -eq 2 ] ; then - echo "ERROR: Invalid number of arguments." >&2 - usage -fi - -# Check the given repo -repos="top corba jaxp jaxws jdk langtools nashorn hotspot" -found="false" -if [ -n "$repo" ]; then - for r in $repos ; do - if [ $repo = "$r" ] ; then - found="true" - break; - fi - done - if [ $found = "false" ] ; then - echo "ERROR: Unknown repo: $repo. Should be one of [$repos]." >&2 - usage - fi -fi - -if [ "$shuffle_to" != "9" -a "$shuffle_to" != "10" ]; then - echo "ERROR: Must pick either -to9 or -to10" - exit 1 -fi - -# When going to 10, a repo must be specified for the source patch -if [ "$shuffle_to" = "10" -a -z "$repo" ]; then - echo "ERROR: Must specify src repo for JDK 9 patch" - exit 1 -fi - -# Check given input/output files -input="$1" -if [ "x$input" = "x-" ] ; then - input="/dev/stdin" -fi - -if [ ! -f $input -a "x$input" != "x/dev/stdin" ] ; then - echo "ERROR: Cannot find input patch file: $input" >&2 - exit 1 -fi - -output="$2" -if [ "x$output" = "x-" ] ; then - output="/dev/stdout" -fi -base_output="$output" - -if [ "$shuffle_to" = "10" ]; then - if [ -f $output -a "x$output" != "x/dev/stdout" ] ; then - echo "ERROR: Output patch already exists: $output" >&2 - exit 1 - fi -else - for r in $repos; do - if [ -f "$output.$r" ]; then - echo "ERROR: Output patch already exists: $output.$r" >&2 - exit 1 - fi - done -fi - -verbose() { - if [ ${vflag} = "true" ] ; then - echo "$@" >&2 - fi -} - -unshuffle() { - line=$@ - verbose "Attempting to rewrite: \"$line\"" - - # Retrieve the file name - path= - if echo "$line" | egrep '^diff' > /dev/null ; then - if ! echo "$line" | egrep '\-\-git' > /dev/null ; then - echo "ERROR: Only git patches supported. Please use 'hg export --git ...'." >&2 - exit 1 - fi - path="`echo "$line" | sed -e s@'diff --git a/'@@ -e s@' b/.*$'@@`" - elif echo "$line" | egrep '^\-\-\-' > /dev/null ; then - path="`echo "$line" | sed -e s@'--- a/'@@`" - elif echo "$line" | egrep '^\+\+\+' > /dev/null ; then - path="`echo "$line" | sed s@'+++ b/'@@`" - fi - verbose "Extracted path: \"$path\"" - - # Find the most specific matches in the shuffle list - matches= - if [ -n "$repo" -a "$repo" != "top" ]; then - matchpath="$repo"/"$path"/x - else - matchpath="$path"/x - fi - while [ "$matchpath" != "" ] ; do - matchpath="`echo $matchpath | sed s@'\(.*\)/.*$'@'\1'@`" - - if [ "$shuffle_to" = "10" ] ; then - pattern=": $matchpath$" - else - pattern="^$matchpath :" - fi - verbose "Attempting to find \"$matchpath\"" - matches=`egrep "$pattern" "$UNSHUFFLE_LIST"` - if ! [ "x${matches}" = "x" ] ; then - verbose "Got matches: [$matches]" - break; - fi - - if ! echo "$matchpath" | egrep '.*/.*' > /dev/null ; then - break; - fi - done - - # Rewrite the line, if we have a match - if ! [ "x${matches}" = "x" ] ; then - shuffled="${matches%% : *}" - unshuffled="${matches#* : }" - patch_suffix_9="" - for r in $repos; do - if [ "$unshuffled" != "${unshuffled#$r}" ]; then - unshuffled="${unshuffled#$r\/}" - patch_suffix_9=".$r" - fi - done - verbose "shuffled: $shuffled" - verbose "unshuffled: $unshuffled" - verbose "patch_suffix_9: $patch_suffix_9" - if [ "$shuffle_to" = "10" ] ; then - newline="`echo "$line" | sed -e s@"$unshuffled"@"$shuffled"@g`" - else - newline="`echo "$line" | sed -e s@"$shuffled"@"$unshuffled"@g`" - output=$base_output$patch_suffix_9 - verbose "Writing to $output" - fi - verbose "Rewriting to \"$newline\"" - echo "$newline" >> $output - else - echo "WARNING: no match found for $path" - echo "$line" >> $output - fi -} - -while IFS= read -r line -do - if echo "$line" | egrep '^diff|^\-\-\-|^\+\+\+' > /dev/null ; then - unshuffle "$line" - else - printf "%s\n" "$line" >> $output - fi -done < "$input" diff --git a/make/scripts/update_copyright_year.sh b/bin/update_copyright_year.sh similarity index 100% rename from make/scripts/update_copyright_year.sh rename to bin/update_copyright_year.sh diff --git a/make/scripts/update_pch.sh b/bin/update_pch.sh similarity index 92% rename from make/scripts/update_pch.sh rename to bin/update_pch.sh index 534525353fd..d7871fdd753 100644 --- a/make/scripts/update_pch.sh +++ b/bin/update_pch.sh @@ -23,9 +23,19 @@ # The output of this script may require some degree of human curation: # - Redundant headers, e.g. both x.hpp, x.inline.hpp are included; # - Headers relative to a non-default feature should be protected by an -# appropriate 'if' clause to make sure all variants can build without +# appropriate 'if' clause to make sure all variants can build without # errors. +source_path="$(dirname ${0})" +this_script_dir="$(cd -- "${source_path}" > /dev/null && pwd)" +if test -z "${this_script_dir}"; then + echo "Error: Could not determine location of this script" + exit 1 +fi + +# Work in top directory +cd $this_script_dir/.. + # Time threshold for header compilation, if the time exceeds the # threshold the header will be precompiled. if [ -z "$MIN_MS" ]; then diff --git a/make/autoconf/compare.sh.template b/make/autoconf/compare.sh.template index bcb5608855a..84421035ab9 100644 --- a/make/autoconf/compare.sh.template +++ b/make/autoconf/compare.sh.template @@ -110,4 +110,4 @@ $MV $OUTPUTDIR/compare.log $OUTPUTDIR/compare.log.old 2> /dev/null export SCRIPT_DIR="$( cd "$( dirname "$0" )" > /dev/null && pwd )" -$BASH $TOPDIR/make/scripts/logger.sh $OUTPUTDIR/compare.log $BASH "$REAL_COMPARE_SCRIPT" "$@" +$BASH $TOPDIR/make/scripts/compare-logger.sh $OUTPUTDIR/compare.log $BASH "$REAL_COMPARE_SCRIPT" "$@" diff --git a/make/scripts/logger.sh b/make/scripts/compare-logger.sh similarity index 100% rename from make/scripts/logger.sh rename to make/scripts/compare-logger.sh diff --git a/make/scripts/hide_important_warnings_from_javac.sh b/make/scripts/hide_important_warnings_from_javac.sh deleted file mode 100644 index 392ed33247a..00000000000 --- a/make/scripts/hide_important_warnings_from_javac.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -GREP=grep - -# -EXP="Note: Some input files use or override a deprecated API." -EXP="${EXP}|Note: Recompile with -Xlint:deprecation for details." -EXP="${EXP}|Note: Some input files use unchecked or unsafe operations." -EXP="${EXP}|Note: Recompile with -Xlint:unchecked for details." -EXP="${EXP}| warning" -EXP="${EXP}|uses or overrides a deprecated API." -EXP="${EXP}|uses unchecked or unsafe operations." -# -${GREP} --line-buffered -v -E "${EXP}" From 33244c82445994131a9168451275216916ce635c Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 10 Sep 2025 10:00:15 +0000 Subject: [PATCH 017/120] 8344030: Improved handling of TOOLCHAIN_PATH Reviewed-by: erikj --- make/autoconf/basic.m4 | 24 ++++-------------------- make/autoconf/basic_tools.m4 | 19 ++----------------- make/autoconf/build-performance.m4 | 7 +------ make/autoconf/flags-ldflags.m4 | 2 +- make/autoconf/toolchain.m4 | 17 ++++------------- make/autoconf/util_paths.m4 | 12 ++++++------ 6 files changed, 18 insertions(+), 63 deletions(-) diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index 2d3e071dd52..316bfc5037d 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -210,17 +210,8 @@ AC_DEFUN([BASIC_SETUP_XCODE_SYSROOT], if test $? -ne 0; then AC_MSG_ERROR([The xcodebuild tool in the devkit reports an error: $XCODEBUILD_OUTPUT]) fi - elif test "x$TOOLCHAIN_PATH" != x; then - UTIL_LOOKUP_PROGS(XCODEBUILD, xcodebuild, $TOOLCHAIN_PATH) - if test "x$XCODEBUILD" != x; then - XCODEBUILD_OUTPUT=`"$XCODEBUILD" -version 2>&1` - if test $? -ne 0; then - AC_MSG_WARN([Ignoring the located xcodebuild tool $XCODEBUILD due to an error: $XCODEBUILD_OUTPUT]) - XCODEBUILD= - fi - fi else - UTIL_LOOKUP_PROGS(XCODEBUILD, xcodebuild) + UTIL_LOOKUP_TOOLCHAIN_PROGS(XCODEBUILD, xcodebuild) if test "x$XCODEBUILD" != x; then XCODEBUILD_OUTPUT=`"$XCODEBUILD" -version 2>&1` if test $? -ne 0; then @@ -348,21 +339,11 @@ AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT], # You can force the sysroot if the sysroot encoded into the compiler tools # is not correct. - AC_ARG_WITH(sys-root, [AS_HELP_STRING([--with-sys-root], - [alias for --with-sysroot for backwards compatibility])], - [SYSROOT=$with_sys_root] - ) - AC_ARG_WITH(sysroot, [AS_HELP_STRING([--with-sysroot], [use this directory as sysroot])], [SYSROOT=$with_sysroot] ) - AC_ARG_WITH([tools-dir], [AS_HELP_STRING([--with-tools-dir], - [alias for --with-toolchain-path for backwards compatibility])], - [UTIL_PREPEND_TO_PATH([TOOLCHAIN_PATH],$with_tools_dir)] - ) - AC_ARG_WITH([toolchain-path], [AS_HELP_STRING([--with-toolchain-path], [prepend these directories when searching for toolchain binaries (compilers etc)])], [UTIL_PREPEND_TO_PATH([TOOLCHAIN_PATH],$with_toolchain_path)] @@ -371,6 +352,9 @@ AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT], AC_ARG_WITH([xcode-path], [AS_HELP_STRING([--with-xcode-path], [set up toolchain on Mac OS using a path to an Xcode installation])]) + UTIL_DEPRECATED_ARG_WITH(sys-root) + UTIL_DEPRECATED_ARG_WITH(tools-dir) + if test "x$with_xcode_path" != x; then if test "x$OPENJDK_BUILD_OS" = "xmacosx"; then UTIL_PREPEND_TO_PATH([TOOLCHAIN_PATH], diff --git a/make/autoconf/basic_tools.m4 b/make/autoconf/basic_tools.m4 index 5815c55c962..5367db46679 100644 --- a/make/autoconf/basic_tools.m4 +++ b/make/autoconf/basic_tools.m4 @@ -207,29 +207,14 @@ AC_DEFUN([BASIC_CHECK_GNU_MAKE], UTIL_SETUP_TOOL(MAKE, [ # Try our hardest to locate a correct version of GNU make - UTIL_LOOKUP_PROGS(CHECK_GMAKE, gmake) + UTIL_LOOKUP_TOOLCHAIN_PROGS(CHECK_GMAKE, gmake) BASIC_CHECK_MAKE_VERSION("$CHECK_GMAKE", [gmake in PATH]) if test "x$FOUND_MAKE" = x; then - UTIL_LOOKUP_PROGS(CHECK_MAKE, make) + UTIL_LOOKUP_TOOLCHAIN_PROGS(CHECK_MAKE, make) BASIC_CHECK_MAKE_VERSION("$CHECK_MAKE", [make in PATH]) fi - if test "x$FOUND_MAKE" = x; then - if test "x$TOOLCHAIN_PATH" != x; then - # We have a toolchain path, check that as well before giving up. - OLD_PATH=$PATH - PATH=$TOOLCHAIN_PATH:$PATH - UTIL_LOOKUP_PROGS(CHECK_TOOLSDIR_GMAKE, gmake) - BASIC_CHECK_MAKE_VERSION("$CHECK_TOOLSDIR_GMAKE", [gmake in tools-dir]) - if test "x$FOUND_MAKE" = x; then - UTIL_LOOKUP_PROGS(CHECK_TOOLSDIR_MAKE, make) - BASIC_CHECK_MAKE_VERSION("$CHECK_TOOLSDIR_MAKE", [make in tools-dir]) - fi - PATH=$OLD_PATH - fi - fi - if test "x$FOUND_MAKE" = x; then AC_MSG_ERROR([Cannot find GNU make $MAKE_REQUIRED_VERSION or newer! Please put it in the path, or add e.g. MAKE=/opt/gmake3.81/make as argument to configure.]) fi diff --git a/make/autoconf/build-performance.m4 b/make/autoconf/build-performance.m4 index 10e86e75199..dfc9e979d2f 100644 --- a/make/autoconf/build-performance.m4 +++ b/make/autoconf/build-performance.m4 @@ -162,12 +162,7 @@ AC_DEFUN([BPERF_SETUP_CCACHE], # Check if ccache is available CCACHE_AVAILABLE=true - OLD_PATH="$PATH" - if test "x$TOOLCHAIN_PATH" != x; then - PATH=$TOOLCHAIN_PATH:$PATH - fi - UTIL_LOOKUP_PROGS(CCACHE, ccache) - PATH="$OLD_PATH" + UTIL_LOOKUP_TOOLCHAIN_PROGS(CCACHE, ccache) AC_MSG_CHECKING([if ccache is available]) if test "x$TOOLCHAIN_TYPE" != "xgcc" && test "x$TOOLCHAIN_TYPE" != "xclang"; then diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4 index 509e0dd825f..a12a6e7f9a6 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4 @@ -74,7 +74,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER], # Clang needs the lld linker to work correctly BASIC_LDFLAGS="-fuse-ld=lld -Wl,--exclude-libs,ALL" if test "x$CXX_IS_USER_SUPPLIED" = xfalse && test "x$CC_IS_USER_SUPPLIED" = xfalse; then - UTIL_REQUIRE_PROGS(LLD, lld, $TOOLCHAIN_PATH:$PATH) + UTIL_REQUIRE_TOOLCHAIN_PROGS(LLD, lld) fi fi if test "x$OPENJDK_TARGET_OS" = xaix; then diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index f3ef44d382b..4662c62d901 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4 @@ -276,9 +276,6 @@ AC_DEFUN_ONCE([TOOLCHAIN_PRE_DETECTION], ORG_CFLAGS="$CFLAGS" ORG_CXXFLAGS="$CXXFLAGS" - # autoconf magic only relies on PATH, so update it if tools dir is specified - OLD_PATH="$PATH" - if test "x$OPENJDK_BUILD_OS" = "xmacosx"; then if test "x$XCODEBUILD" != x; then XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version 2> /dev/null | $HEAD -n 1` @@ -300,9 +297,10 @@ AC_DEFUN_ONCE([TOOLCHAIN_PRE_DETECTION], fi AC_SUBST(TOOLCHAIN_VERSION) - # Finally prepend TOOLCHAIN_PATH to the PATH, to allow --with-tools-dir to - # override all other locations. - if test "x$TOOLCHAIN_PATH" != x; then + # For the microsoft toolchain the toolchain path needs to be added to the + # normal path, or the compiler will not work in some situations in later + # configure checks. + if test "x$TOOLCHAIN_TYPE" = "xmicrosoft" && test "x$TOOLCHAIN_PATH" != x; then export PATH=$TOOLCHAIN_PATH:$PATH fi ]) @@ -310,13 +308,6 @@ AC_DEFUN_ONCE([TOOLCHAIN_PRE_DETECTION], # Restore path, etc AC_DEFUN_ONCE([TOOLCHAIN_POST_DETECTION], [ - # Restore old path, except for the microsoft toolchain, which requires the - # toolchain path to remain in place. Otherwise the compiler will not work in - # some situations in later configure checks. - if test "x$TOOLCHAIN_TYPE" != "xmicrosoft"; then - PATH="$OLD_PATH" - fi - # Restore the flags to the user specified values. # This is necessary since AC_PROG_CC defaults CFLAGS to "-g -O2" CFLAGS="$ORG_CFLAGS" diff --git a/make/autoconf/util_paths.m4 b/make/autoconf/util_paths.m4 index 40864680aad..abe79c40fb6 100644 --- a/make/autoconf/util_paths.m4 +++ b/make/autoconf/util_paths.m4 @@ -458,17 +458,18 @@ AC_DEFUN([UTIL_LOOKUP_PROGS], ################################################################################ # Call UTIL_SETUP_TOOL with AC_CHECK_TOOLS to locate the tool. This will look -# first for cross-compilation tools. +# first for tools using the cross-compilation prefix, and then for tools without +# this prefix. For each of these name variants, it will look first in the +# toolchain path, and then in the normal path. # $1: variable to set # $2: executable name (or list of names) to look for -# $3: [path] AC_DEFUN([UTIL_LOOKUP_TOOLCHAIN_PROGS], [ if test "x$ac_tool_prefix" = x; then - UTIL_LOOKUP_PROGS($1, $2, $3) + UTIL_LOOKUP_PROGS($1, $2, [$TOOLCHAIN_PATH:$PATH]) else prefixed_names=$(for name in $2; do echo ${ac_tool_prefix}${name} $name; done) - UTIL_LOOKUP_PROGS($1, $prefixed_names, $3) + UTIL_LOOKUP_PROGS($1, $prefixed_names, [$TOOLCHAIN_PATH:$PATH]) fi ]) @@ -497,10 +498,9 @@ AC_DEFUN([UTIL_REQUIRE_PROGS], # Like UTIL_LOOKUP_PROGS but fails if no tool was found. # $1: variable to set # $2: executable name (or list of names) to look for -# $3: [path] AC_DEFUN([UTIL_REQUIRE_TOOLCHAIN_PROGS], [ - UTIL_LOOKUP_TOOLCHAIN_PROGS($1, $2, $3) + UTIL_LOOKUP_TOOLCHAIN_PROGS($1, $2) UTIL_CHECK_NONEMPTY($1) ]) From edae355e95f23294eda092dbedcb7f6cf165b0f8 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 10 Sep 2025 10:27:38 +0000 Subject: [PATCH 018/120] 8246325: Add DRYRUN facility to SetupExecute Reviewed-by: erikj --- make/Bundles.gmk | 4 ++-- make/autoconf/spec.gmk.template | 10 ++++++---- make/common/Execute.gmk | 20 ++++++++++++++++---- test/make/TestExecute.gmk | 24 ++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/make/Bundles.gmk b/make/Bundles.gmk index ba8ec0c864b..cf3b77e4e52 100644 --- a/make/Bundles.gmk +++ b/make/Bundles.gmk @@ -301,7 +301,7 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), ) $(call LogWarn, Signing $(JDK_BUNDLE_NAME)) $(CODESIGN) -s "$(MACOSX_CODESIGN_IDENTITY)" \ --timestamp --options runtime --deep --force \ - $(JDK_MACOSX_BUNDLE_DIR_SIGNED)/$(JDK_MACOSX_BUNDLE_TOP_DIR) $(LOG_DEBUG) + $(JDK_MACOSX_BUNDLE_DIR_SIGNED)/$(JDK_MACOSX_BUNDLE_TOP_SUBDIR) $(LOG_DEBUG) $(TOUCH) $@ $(eval $(call SetupBundleFile, BUILD_JDK_BUNDLE, \ @@ -330,7 +330,7 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), ) $(call LogWarn, Signing $(JRE_BUNDLE_NAME)) $(CODESIGN) -s "$(MACOSX_CODESIGN_IDENTITY)" \ --timestamp --options runtime --deep --force \ - $(JRE_MACOSX_BUNDLE_DIR_SIGNED)/$(JRE_MACOSX_BUNDLE_TOP_DIR) $(LOG_DEBUG) + $(JRE_MACOSX_BUNDLE_DIR_SIGNED)/$(JRE_MACOSX_BUNDLE_TOP_SUBDIR) $(LOG_DEBUG) $(TOUCH) $@ $(eval $(call SetupBundleFile, BUILD_JRE_BUNDLE, \ diff --git a/make/autoconf/spec.gmk.template b/make/autoconf/spec.gmk.template index e3345940101..ab6bb51c27e 100644 --- a/make/autoconf/spec.gmk.template +++ b/make/autoconf/spec.gmk.template @@ -898,12 +898,14 @@ JDK_MACOSX_BUNDLE_DIR = $(IMAGES_OUTPUTDIR)/$(JDK_MACOSX_BUNDLE_SUBDIR) JRE_MACOSX_BUNDLE_DIR = $(IMAGES_OUTPUTDIR)/$(JRE_MACOSX_BUNDLE_SUBDIR) JDK_MACOSX_BUNDLE_DIR_SIGNED = $(IMAGES_OUTPUTDIR)/$(JDK_MACOSX_BUNDLE_SUBDIR_SIGNED) JRE_MACOSX_BUNDLE_DIR_SIGNED = $(IMAGES_OUTPUTDIR)/$(JRE_MACOSX_BUNDLE_SUBDIR_SIGNED) -JDK_MACOSX_BUNDLE_TOP_DIR = jdk-$(VERSION_NUMBER).jdk -JRE_MACOSX_BUNDLE_TOP_DIR = jre-$(VERSION_NUMBER).jre -JDK_MACOSX_CONTENTS_SUBDIR = $(JDK_MACOSX_BUNDLE_TOP_DIR)/Contents -JRE_MACOSX_CONTENTS_SUBDIR = $(JRE_MACOSX_BUNDLE_TOP_DIR)/Contents +JDK_MACOSX_BUNDLE_TOP_SUBDIR = jdk-$(VERSION_NUMBER).jdk +JRE_MACOSX_BUNDLE_TOP_SUBDIR = jre-$(VERSION_NUMBER).jre +JDK_MACOSX_CONTENTS_SUBDIR = $(JDK_MACOSX_BUNDLE_TOP_SUBDIR)/Contents +JRE_MACOSX_CONTENTS_SUBDIR = $(JRE_MACOSX_BUNDLE_TOP_SUBDIR)/Contents JDK_MACOSX_CONTENTS_DIR = $(JDK_MACOSX_BUNDLE_DIR)/$(JDK_MACOSX_CONTENTS_SUBDIR) JRE_MACOSX_CONTENTS_DIR = $(JRE_MACOSX_BUNDLE_DIR)/$(JRE_MACOSX_CONTENTS_SUBDIR) +JDK_MACOSX_BUNDLE_TOP_DIR = $(JDK_MACOSX_BUNDLE_DIR)/$(JDK_MACOSX_BUNDLE_TOP_SUBDIR) +JRE_MACOSX_BUNDLE_TOP_DIR = $(JRE_MACOSX_BUNDLE_DIR)/$(JRE_MACOSX_BUNDLE_TOP_SUBDIR) # Bundle names ifneq ($(VERSION_BUILD), ) diff --git a/make/common/Execute.gmk b/make/common/Execute.gmk index 1ee3c28261b..4199e8f13b7 100644 --- a/make/common/Execute.gmk +++ b/make/common/Execute.gmk @@ -82,6 +82,8 @@ ifeq ($(INCLUDE), true) # INFO : Message to display at LOG=info level when running command (optional) # WARN : Message to display at LOG=warn level when running command (optional) # DEPS : Dependencies for the execution to take place +# DRYRUN : Set to true to perform everything but executing the command \ +# (defaults to false, primarily intended for debugging) # # Setup make rules for copying files, with an option to do more complex @@ -161,8 +163,13 @@ define SetupExecuteBody $$(TOUCH) $$@ $$($1_EXEC_RESULT): $$($1_PRE_MARKER) - $$(call ExecuteWithLog, $$($1_BASE)_exec, \ - cd $$($1_WORKING_DIR) && $$($1_COMMAND)) + ifneq ($$($1_DRYRUN), true) + $$(call ExecuteWithLog, $$($1_BASE)_exec, \ + cd $$($1_WORKING_DIR) && $$($1_COMMAND)) + else + $$(call LogWarn, DRYRUN enabled for $1, not actually running command) + $$(TOUCH) $$@ + endif ifeq ($$($1_EXEC_RESULT), $$($1_EXEC_MARKER)) $$(TOUCH) $$@ endif @@ -177,8 +184,13 @@ define SetupExecuteBody $$(call LogInfo, $$($1_INFO)) endif $$(call MakeDir, $$(call EncodeSpace, $$($1_WORKING_DIR)) $$(call EncodeSpace, $$($1_SUPPORT_DIR)) $$(call EncodeSpace, $$($1_OUTPUT_DIR))) - $$(call ExecuteWithLog, $$($1_BASE)_exec, \ - cd $$($1_WORKING_DIR) && $$($1_COMMAND)) + ifneq ($$($1_DRYRUN), true) + $$(call ExecuteWithLog, $$($1_BASE)_exec, \ + cd $$($1_WORKING_DIR) && $$($1_COMMAND)) + else + $$(call LogWarn, DRYRUN enabled for $1, not actually running command) + $$(TOUCH) $$@ + endif ifeq ($$($1_EXEC_RESULT), $$($1_EXEC_MARKER)) $$(TOUCH) $$@ endif diff --git a/test/make/TestExecute.gmk b/test/make/TestExecute.gmk index f71a402502e..5d57d244c39 100644 --- a/test/make/TestExecute.gmk +++ b/test/make/TestExecute.gmk @@ -60,10 +60,30 @@ $(eval $(call SetupExecute, EXEC_2, \ run-test2: $(EXEC_2) test -f $(OUTPUT_DIR)/exec_2/special/specialfile +$(eval $(call SetupExecute, EXEC_3, \ + INFO := Testing that SetupExecute with DRYRUN does nothing, \ + OUTPUT_DIR := $(OUTPUT_DIR)/exec_3, \ + DRYRUN := true, \ + COMMAND := $(ECHO) "This should not happen" > $(OUTPUT_DIR)/exec_3/dryrunfile, \ +)) -TEST_TARGETS += run-test1 run-test2 +run-test3: $(EXEC_3) + test ! -f $(OUTPUT_DIR)/exec_3/dryrunfile -.PHONY: run-test1 run-test2 +$(eval $(call SetupExecute, EXEC_4, \ + INFO := Testing that SetupExecute with DRYRUN does nothing but touches output file, \ + OUTPUT_FILE := $(OUTPUT_DIR)/exec_4/output, \ + DRYRUN := true, \ + COMMAND := $(ECHO) "This should not happen" > $(OUTPUT_DIR)/exec_4/dryrunfile, \ +)) + +run-test4: $(EXEC_4) + test ! -f $(OUTPUT_DIR)/exec_4/dryrunfile + test -f $(OUTPUT_DIR)/exec_4/output + +TEST_TARGETS += run-test1 run-test2 run-test3 run-test4 + +.PHONY: run-test1 run-test2 run-test3 run-test4 ################################################################################ From 4d4e51c41fed79427fb621fd9fcc8e5e23bfb287 Mon Sep 17 00:00:00 2001 From: David Beaumont Date: Wed, 10 Sep 2025 11:49:02 +0000 Subject: [PATCH 019/120] 8365483: Test sun/rmi/runtime/Log/6409194/NoConsoleOutput.java sometimes fails Reviewed-by: dfuchs, jpai --- .../java/util/logging/StreamHandler.java | 13 +- .../logging/StreamHandlerRacyCloseTest.java | 137 ++++++++++++++++++ 2 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 test/jdk/java/util/logging/StreamHandlerRacyCloseTest.java diff --git a/src/java.logging/share/classes/java/util/logging/StreamHandler.java b/src/java.logging/share/classes/java/util/logging/StreamHandler.java index ddfea9674dc..3b9af54814d 100644 --- a/src/java.logging/share/classes/java/util/logging/StreamHandler.java +++ b/src/java.logging/share/classes/java/util/logging/StreamHandler.java @@ -214,13 +214,16 @@ public class StreamHandler extends Handler { try { synchronized (this) { + // Re-check writer between isLoggable() and here. Writer writer = this.writer; - if (!doneHeader) { - writer.write(formatter.getHead(this)); - doneHeader = true; + if (writer != null) { + if (!doneHeader) { + writer.write(formatter.getHead(this)); + doneHeader = true; + } + writer.write(msg); + synchronousPostWriteHook(); } - writer.write(msg); - synchronousPostWriteHook(); } } catch (Exception ex) { // We don't want to throw an exception here, but we diff --git a/test/jdk/java/util/logging/StreamHandlerRacyCloseTest.java b/test/jdk/java/util/logging/StreamHandlerRacyCloseTest.java new file mode 100644 index 00000000000..5bb465088e5 --- /dev/null +++ b/test/jdk/java/util/logging/StreamHandlerRacyCloseTest.java @@ -0,0 +1,137 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.ErrorManager; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.SimpleFormatter; +import java.util.logging.StreamHandler; + +import org.junit.jupiter.api.Test; + +/* + * @test + * @bug 8365483 + * @summary verify that concurrent calls to publish() and close() on a + * StreamHandler do not cause unexpected exceptions + * @run junit StreamHandlerRacyCloseTest + */ +public class StreamHandlerRacyCloseTest { + + private static final class ExceptionTrackingErrorManager extends ErrorManager { + private final AtomicReference firstError = new AtomicReference<>(); + + @Override + public void error(String msg, Exception ex, int code) { + // just track one/first exception, that's good enough for this test + this.firstError.compareAndSet(null, new RuntimeException(msg, ex)); + } + } + + @Test + void testRacyClose() throws Exception { + final int numTimes = 100; + try (ExecutorService executor = Executors.newFixedThreadPool(numTimes)) { + final List> tasks = new ArrayList<>(); + for (int i = 1; i <= numTimes; i++) { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // construct a StreamHandler with an ErrorManager which propagates + // any errors that happen during publish() + final StreamHandler handler = new StreamHandler(baos, new SimpleFormatter()); + handler.setErrorManager(new ExceptionTrackingErrorManager()); + + final CountDownLatch latch = new CountDownLatch(2); + // create a publisher and closer task which will run concurrently + tasks.add(new Publisher(handler, latch)); + tasks.add(new Closer(handler, latch)); + } + // submit the tasks and expect successful completion of each + final List> completed = executor.invokeAll(tasks); + for (var f : completed) { + f.get(); + } + } + } + + private static final class Closer implements Callable { + private final StreamHandler handler; + private final CountDownLatch startLatch; + + private Closer(final StreamHandler handler, final CountDownLatch startLatch) { + this.handler = handler; + this.startLatch = startLatch; + } + + @Override + public Void call() throws Exception { + // notify the other task of our readiness + this.startLatch.countDown(); + // wait for the other task to arrive + this.startLatch.await(); + // close the handler + this.handler.close(); + // propagate any exception that may have been caught by the error manager + final var errMgr = (ExceptionTrackingErrorManager) this.handler.getErrorManager(); + if (errMgr.firstError.get() != null) { + throw errMgr.firstError.get(); + } + return null; + } + } + + private static final class Publisher implements Callable { + private final StreamHandler handler; + private final CountDownLatch startLatch; + + private Publisher(final StreamHandler handler, final CountDownLatch startLatch) { + this.handler = handler; + this.startLatch = startLatch; + } + + @Override + public Void call() throws Exception { + final LogRecord record = new LogRecord(Level.WARNING, "hello world"); + // notify the other task of our readiness + this.startLatch.countDown(); + // wait for the other task to arrive + this.startLatch.await(); + // publish the record + this.handler.publish(record); + // propagate any exception that may have been caught by the error manager + final var errMgr = (ExceptionTrackingErrorManager) this.handler.getErrorManager(); + if (errMgr.firstError.get() != null) { + throw errMgr.firstError.get(); + } + return null; + } + } +} From 703d930e4d52a6f9741cf9affee8caade550e67b Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Wed, 10 Sep 2025 11:55:31 +0000 Subject: [PATCH 020/120] 8366980: TestTransparentHugePagesHeap.java fails when run with -UseCompressedOops Reviewed-by: aboldtch, tschatzl --- .../gc/TestTransparentHugePagesHeap.java | 81 +++++++++++++------ 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/test/hotspot/jtreg/gc/TestTransparentHugePagesHeap.java b/test/hotspot/jtreg/gc/TestTransparentHugePagesHeap.java index 25044d2c3e4..2c2e19b87c4 100644 --- a/test/hotspot/jtreg/gc/TestTransparentHugePagesHeap.java +++ b/test/hotspot/jtreg/gc/TestTransparentHugePagesHeap.java @@ -49,6 +49,7 @@ * @run driver TestTransparentHugePagesHeap Serial */ +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -98,47 +99,76 @@ public class TestTransparentHugePagesHeap { class VerifyTHPEnabledForHeap { public static void main(String args[]) throws Exception { - String heapAddress = readHeapAddressInLog(); + // Extract the heap start from pagesize logging + BigInteger heapStart = extractHeapStartFromLog(); + Path smaps = makeSmapsCopy(); - final Pattern heapSection = Pattern.compile("^" + heapAddress + ".*"); - final Pattern thpEligible = Pattern.compile("THPeligible:\\s+(\\d)\\s*"); + final Pattern addressRangePattern = Pattern.compile("([0-9a-f]*?)-([0-9a-f]*?) .*"); + final Pattern thpEligiblePattern = Pattern.compile("THPeligible:\\s+(\\d)\\s*"); Scanner smapsFile = new Scanner(smaps); while (smapsFile.hasNextLine()) { - Matcher heapMatcher = heapSection.matcher(smapsFile.nextLine()); - - if (heapMatcher.matches()) { - // Found the first heap section, verify that it is THP eligible - while (smapsFile.hasNextLine()) { - Matcher m = thpEligible.matcher(smapsFile.nextLine()); - if (m.matches()) { - if (Integer.parseInt(m.group(1)) == 1) { - // THPeligible is 1, heap can be backed by huge pages - return; - } - - throw new RuntimeException("First heap section at 0x" + heapAddress + " is not THPeligible"); - } - } + Matcher addressRangeMatcher = addressRangePattern.matcher(smapsFile.nextLine()); + if (!addressRangeMatcher.matches()) { + continue; } + + // Found an address range line in the smaps file + + BigInteger addressStart = new BigInteger(addressRangeMatcher.group(1), 16); + BigInteger addressEnd = new BigInteger(addressRangeMatcher.group(2), 16); + + // Linux sometimes merges adjacent VMAs so we can't search for a range that + // exactly matches the heap range. Instead we look for the first range that + // contains the start of the heap and verify that that range is THP eligible. + + if (addressStart.compareTo(heapStart) > 0 || heapStart.compareTo(addressEnd) >= 0) { + continue; + } + + // Found a range that contains the start of the heap, verify that it is THP eligible. + + while (smapsFile.hasNextLine()) { + Matcher m = thpEligiblePattern.matcher(smapsFile.nextLine()); + if (!m.matches()) { + continue; + } + + // Found the THPeligible line + + if (m.group(1).equals("1")) { + // Success - THPeligible is 1, heap can be backed by huge pages + return; + } + + throw new RuntimeException("The address range 0x" + addressStart.toString(16) + + "-0x" + addressEnd.toString(16) + + " that contains the heap start" + heapStart + + " is not THPeligible"); + } + + throw new RuntimeException("Couldn't find THPeligible in the smaps file"); } - // Failed to verify THP for heap - throw new RuntimeException("Could not find heap section in smaps file"); + throw new RuntimeException("Could not find an address range containing the heap start " + heapStart + " in the smaps file"); } - private static String readHeapAddressInLog() throws Exception { - final Pattern heapAddress = Pattern.compile(".* Heap: .*base=(0x[0-9A-Fa-f]*).*"); + private static BigInteger extractHeapStartFromLog() throws Exception { + // [0.041s][info][pagesize] Heap: min=128M max=128M base=0x0000ffff5c600000 size=128M page_size=2M + final Pattern heapAddress = Pattern.compile(".* Heap: .*base=0x([0-9A-Fa-f]*).*"); Scanner logFile = new Scanner(Paths.get("thp-" + ProcessHandle.current().pid() + ".log")); while (logFile.hasNextLine()) { - Matcher m = heapAddress.matcher(logFile.nextLine()); + String line = logFile.nextLine(); + + Matcher m = heapAddress.matcher(line); if (m.matches()) { - return Long.toHexString(Long.decode(m.group(1))); + return new BigInteger(m.group(1), 16); } } - throw new RuntimeException("Failed to parse heap address, failing test"); + + throw new RuntimeException("Failed to find heap start"); } private static Path makeSmapsCopy() throws Exception { @@ -149,4 +179,3 @@ public class TestTransparentHugePagesHeap { } } } - From 46ae1ee87152742082e6047d0556944d7ae4567d Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Wed, 10 Sep 2025 12:33:06 +0000 Subject: [PATCH 021/120] 8277444: Data race between JvmtiClassFileReconstituter::copy_bytecodes and class linking Reviewed-by: dholmes, amenkov, coleenp --- .../prims/jvmtiClassFileReconstituter.cpp | 5 + src/hotspot/share/prims/jvmtiEnv.cpp | 22 ++- .../instrument/RetransformBigClassTest.java | 161 ++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 test/jdk/java/lang/instrument/RetransformBigClassTest.java diff --git a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp index 831f407e7ec..a441d405f8d 100644 --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp @@ -996,6 +996,11 @@ void JvmtiClassFileReconstituter::write_u8(u8 x) { void JvmtiClassFileReconstituter::copy_bytecodes(const methodHandle& mh, unsigned char* bytecodes) { + // We must copy bytecodes only from linked classes. + // Being linked guarantees we are not getting bytecodes at + // the same time the linking process is rewriting them. + guarantee(mh->method_holder()->is_linked(), "Bytecodes must be copied from a linked class"); + // use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes // and the breakpoint bytecode are converted to their original bytecodes. diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 30dd1f77d23..3eb507ba5e3 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -450,6 +450,18 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) { InstanceKlass* ik = InstanceKlass::cast(klass); if (ik->get_cached_class_file_bytes() == nullptr) { + // Link the class to avoid races with the rewriter. This will call the verifier also + // on the class. Linking is also done in VM_RedefineClasses below, but we need + // to keep that for other VM_RedefineClasses callers. + JavaThread* THREAD = current_thread; + ik->link_class(THREAD); + if (HAS_PENDING_EXCEPTION) { + // Retransform/JVMTI swallows error messages. Using this class will rerun the verifier in a context + // that propagates the VerifyError, if thrown. + CLEAR_PENDING_EXCEPTION; + return JVMTI_ERROR_INVALID_CLASS; + } + // Not cached, we need to reconstitute the class file from the // VM representation. We don't attach the reconstituted class // bytes to the InstanceKlass here because they have not been @@ -3407,7 +3419,8 @@ jvmtiError JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) { NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID); - methodHandle mh(Thread::current(), method); + JavaThread* current_thread = JavaThread::current(); + methodHandle mh(current_thread, method); jint size = (jint)mh->code_size(); jvmtiError err = allocate(size, bytecodes_ptr); if (err != JVMTI_ERROR_NONE) { @@ -3416,6 +3429,13 @@ JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** (*bytecode_count_ptr) = size; // get byte codes + // Make sure the class is verified and rewritten first. + JavaThread* THREAD = current_thread; + mh->method_holder()->link_class(THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + return JVMTI_ERROR_INVALID_CLASS; + } JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr); return JVMTI_ERROR_NONE; diff --git a/test/jdk/java/lang/instrument/RetransformBigClassTest.java b/test/jdk/java/lang/instrument/RetransformBigClassTest.java new file mode 100644 index 00000000000..c4788217be1 --- /dev/null +++ b/test/jdk/java/lang/instrument/RetransformBigClassTest.java @@ -0,0 +1,161 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8277444 + * + * @library /test/lib + * @compile SimpleIdentityTransformer.java + * @run shell MakeJAR.sh retransformAgent + * @run main/othervm -javaagent:retransformAgent.jar RetransformBigClassTest + */ + +import jdk.test.lib.compiler.InMemoryJavaCompiler; + +/* + * JvmtiClassFileReconstituter::copy_bytecodes restores bytecodes rewritten + * by the linking process. It is used by RetransformClasses. + * JDK-8277444 is a data race between copy_bytecodes and the linking process. + * This test puts the linking process in one thread and the retransforming process + * in another thread. The test uses Class.forName("BigClass", false, classLoader) + * which does not link the class. When the class is used, the linking process starts. + * In another thread retransforming of the class is happening. + * We generate a class with big methods. A number of methods and their size are + * chosen to make the linking and retransforming processes run concurrently. + * We delay the retransforming process to follow the linking process. + * If there is no synchronization between the processes, a data race will happen. + */ +public class RetransformBigClassTest extends AInstrumentationTestCase { + + private static final Object LOCK = new Object(); + private static final int COUNTER_INC_COUNT = 2000; // A number of 'c+=1;' statements in methods of a class. + private static final int MIN_LINK_TIME_MS = 60; // Large enough so the linking and retransforming processes run in parallel. + private static final int RETRANSFORM_CLASSES_DELAY_MS = 37; // We manage to create a data race when a delay is in the range 0.52x - 0.62x of MIN_LINK_TIME_MS. + + private static Class bigClass; + private static byte[] bigClassBytecode; + + private Thread retransformThread; + + RetransformBigClassTest() { + super("RetransformBigClassTest"); + } + + public static void main(String[] args) throws Throwable { + new RetransformBigClassTest().runTest(); + } + + protected final void doRunTest() throws Throwable { + ClassLoader classLoader = new ClassLoader() { + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if (name.equals("BigClass")) { + return defineClass(name, bigClassBytecode, 0, bigClassBytecode.length); + } + + return super.findClass(name); + } + }; + synchronized (LOCK) { + bigClass = Class.forName("BigClass", false, classLoader); + LOCK.notify(); + } + // Make a use of the BigClass + assertTrue(bigClass.getConstructor().newInstance().hashCode() != 0); + retransformThread.join(); + } + + private byte[] createClassBytecode(String className, int methodCount) throws Exception { + String methodBody = ""; + for (int j = 0; j < COUNTER_INC_COUNT; j++) { + methodBody += "c+=1;"; + } + + String classSrc = "public class " + className + " { int c;"; + + for (int i = 0; i < methodCount; i++) { + classSrc += "\npublic void m" + i + "(){"; + classSrc += methodBody; + classSrc += "\n}"; + } + classSrc += "\n}"; + + return InMemoryJavaCompiler.compile(className, classSrc); + } + + // We need a number of methods such that the linking time is greater than + // or equal to MIN_LINK_TIME_MS. + // We create a class having 5 methods and trigger the linking process. + // We measure the time taken and use it to calculate the needed number. + private int findMethodCount() throws Exception { + int methodCount = 5; + final String className = "BigClass" + methodCount; + final byte[] bytecode = createClassBytecode(className, methodCount); + ClassLoader classLoader = new ClassLoader() { + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if (name.equals(className)) { + return defineClass(name, bytecode, 0, bytecode.length); + } + + return super.findClass(name); + } + }; + var bigClass = Class.forName(className, false, classLoader); + long startTime = System.nanoTime(); + assertTrue(bigClass.getConstructor().newInstance().hashCode() != 0); + double linkTimeMs = (System.nanoTime() - startTime) / 1000000.0; + System.out.println("Link time for a class with " + methodCount + " methods each having " + COUNTER_INC_COUNT + " counter increments: " + Math.round(linkTimeMs)); + if (linkTimeMs < MIN_LINK_TIME_MS) { + methodCount = (int)Math.round((MIN_LINK_TIME_MS * methodCount) / linkTimeMs); + } + System.out.println("The number of methods to exceed " + MIN_LINK_TIME_MS + " ms linking time: " + methodCount); + return methodCount; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + bigClassBytecode = createClassBytecode("BigClass", findMethodCount()); + fInst.addTransformer(new SimpleIdentityTransformer()); + retransformThread = new Thread(() -> { + try { + synchronized (LOCK) { + while (bigClass == null) { + System.out.println("[retransformThread]: Waiting for bigClass"); + LOCK.wait(); + } + } + Thread.sleep(RETRANSFORM_CLASSES_DELAY_MS); + fInst.retransformClasses(bigClass); + } catch (Exception e) { + e.printStackTrace(); + } + }); + retransformThread.start(); + Thread.sleep(100); + } +} From 385c13298932f1de16e6161652be35d966d822ec Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 10 Sep 2025 12:49:38 +0000 Subject: [PATCH 022/120] 8367240: Parallel: Refactor PSScavengeCLDClosure Reviewed-by: stefank --- .../share/gc/parallel/psClosure.inline.hpp | 57 ++++++++----------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psClosure.inline.hpp b/src/hotspot/share/gc/parallel/psClosure.inline.hpp index 5cc059a09f5..914a16e77a6 100644 --- a/src/hotspot/share/gc/parallel/psClosure.inline.hpp +++ b/src/hotspot/share/gc/parallel/psClosure.inline.hpp @@ -78,16 +78,17 @@ typedef PSRootsClosure PSScavengeRootsClosure; typedef PSRootsClosure PSPromoteRootsClosure; // Scavenges a single oop in a ClassLoaderData. -class PSScavengeFromCLDClosure: public OopClosure { -private: +class PSScavengeCLDOopClosure : public OopClosure { PSPromotionManager* _pm; - // Used to redirty a scanned cld if it has oops - // pointing to the young generation after being scanned. - ClassLoaderData* _scanned_cld; + public: - PSScavengeFromCLDClosure(PSPromotionManager* pm) : _pm(pm), _scanned_cld(nullptr) { } + // Records whether this CLD contains oops pointing into young-gen after scavenging. + bool _has_oops_into_young_gen; + + PSScavengeCLDOopClosure(PSPromotionManager* pm) : _pm(pm), _has_oops_into_young_gen(false) {} + void do_oop(narrowOop* p) { ShouldNotReachHere(); } - void do_oop(oop* p) { + void do_oop(oop* p) { ParallelScavengeHeap* psh = ParallelScavengeHeap::heap(); assert(!psh->is_in_reserved(p), "GC barrier needed"); if (PSScavenge::should_scavenge(p)) { @@ -97,43 +98,33 @@ public: oop new_obj = _pm->copy_to_survivor_space(o); RawAccess::oop_store(p, new_obj); - if (PSScavenge::is_obj_in_young(new_obj)) { - do_cld_barrier(); + if (PSScavenge::is_obj_in_young(new_obj) && !_has_oops_into_young_gen) { + _has_oops_into_young_gen = true; } } } - - void set_scanned_cld(ClassLoaderData* cld) { - assert(_scanned_cld == nullptr || cld == nullptr, "Should always only handling one cld at a time"); - _scanned_cld = cld; - } - -private: - void do_cld_barrier() { - assert(_scanned_cld != nullptr, "Should not be called without having a scanned cld"); - _scanned_cld->record_modified_oops(); - } }; // Scavenges the oop in a ClassLoaderData. class PSScavengeCLDClosure: public CLDClosure { -private: - PSScavengeFromCLDClosure _oop_closure; + PSPromotionManager* _pm; + public: - PSScavengeCLDClosure(PSPromotionManager* pm) : _oop_closure(pm) { } + PSScavengeCLDClosure(PSPromotionManager* pm) : _pm(pm) { } + void do_cld(ClassLoaderData* cld) { - // If the cld has not been dirtied we know that there's - // no references into the young gen and we can skip it. + // If the cld has not been dirtied we know that there are + // no references into the young gen, so we can skip it. + if (!cld->has_modified_oops()) { + return; + } - if (cld->has_modified_oops()) { - // Setup the promotion manager to redirty this cld - // if references are left in the young gen. - _oop_closure.set_scanned_cld(cld); + PSScavengeCLDOopClosure oop_closure{_pm}; + // Clean the cld since we're going to scavenge all the metadata. + cld->oops_do(&oop_closure, ClassLoaderData::_claim_none, /*clear_modified_oops*/true); - // Clean the cld since we're going to scavenge all the metadata. - cld->oops_do(&_oop_closure, ClassLoaderData::_claim_none, /*clear_modified_oops*/true); - - _oop_closure.set_scanned_cld(nullptr); + if (oop_closure._has_oops_into_young_gen) { + cld->record_modified_oops(); } } }; From c968a672c034fe533ea5f4ac5efe37ffb76c93e2 Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Wed, 10 Sep 2025 13:45:06 +0000 Subject: [PATCH 023/120] 8362282: runtime/logging/StressAsyncUL.java failed with exitValue = 134 Reviewed-by: jsjolen, dholmes --- src/hotspot/share/logging/logAsyncWriter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/logging/logAsyncWriter.cpp b/src/hotspot/share/logging/logAsyncWriter.cpp index cfb6a991c4c..d184827f582 100644 --- a/src/hotspot/share/logging/logAsyncWriter.cpp +++ b/src/hotspot/share/logging/logAsyncWriter.cpp @@ -318,13 +318,13 @@ void AsyncLogWriter::initialize() { AsyncLogWriter* self = new AsyncLogWriter(); if (self->_initialized) { - Atomic::release_store_fence(&AsyncLogWriter::_instance, self); - // All readers of _instance after the fence see non-null. // We use LogOutputList's RCU counters to ensure all synchronous logsites have completed. - // After that, we start AsyncLog Thread and it exclusively takes over all logging I/O. + // After that, we publish the initalized _instance to readers. + // Then we start the AsyncLog Thread and it exclusively takes over all logging I/O. for (LogTagSet* ts = LogTagSet::first(); ts != nullptr; ts = ts->next()) { ts->wait_until_no_readers(); } + Atomic::release_store_fence(&AsyncLogWriter::_instance, self); os::start_thread(self); log_debug(logging, thread)("Async logging thread started."); } else { From 5cd7721ad448cc4bdac37b0456252335f6b9d9f5 Mon Sep 17 00:00:00 2001 From: Kerem Kat Date: Wed, 10 Sep 2025 14:36:11 +0000 Subject: [PATCH 024/120] 8366154: Validate thread type requirements in debug commands Reviewed-by: dholmes, simonis, kevinw --- src/hotspot/share/utilities/debug.cpp | 87 ++++++++++++++++++++------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index 2865dbc5991..bd82336020a 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -63,6 +63,7 @@ #include "utilities/unsigned5.hpp" #include "utilities/vmError.hpp" +#include #include #include @@ -296,20 +297,40 @@ void report_java_out_of_memory(const char* message) { class Command : public StackObj { private: - ResourceMark _rm; - DebuggingContext _debugging; - public: static int level; - Command(const char* str) { - if (level++ > 0) return; - tty->cr(); - tty->print_cr("\"Executing %s\"", str); + DebuggingContext _debugging; + bool _has_rm; + // Union members of class type are implicitly allocated but not constructed automatically. + // We therefore have to explicitly construct _rm with a placement new call (see 'onThread()') and + // clean it up afterwards with an explicit destructor call (see '~Command()'). + union { ResourceMark _rm; }; + public: + Command(const char* str) : _has_rm(false) { + if (level++ == 0) { + tty->cr(); + tty->print_cr("\"Executing %s\"", str); + } + tty->flush(); } - ~Command() { + if (_has_rm) _rm.~ResourceMark(); tty->flush(); level--; } + + bool onThread() { + Thread* thread = Thread::current_or_null(); + if (thread == nullptr) { + tty->print_cr("Failed: Current thread is not attached"); + return false; + } + + if (!_has_rm) { + ::new (&_rm) ResourceMark(); + _has_rm = true; + } + return true; + } }; int Command::level = 0; @@ -370,6 +391,7 @@ extern "C" DEBUGEXPORT void printnm(intptr_t p) { extern "C" DEBUGEXPORT void universe() { Command c("universe"); + if (!c.onThread()) return; Universe::print_on(tty); } @@ -379,6 +401,7 @@ extern "C" DEBUGEXPORT void verify() { // note: this may not be safe if we're not at a safepoint; for debugging, // this manipulates the safepoint settings to avoid assertion failures Command c("universe verify"); + if (!c.onThread()) return; bool safe = SafepointSynchronize::is_at_safepoint(); if (!safe) { tty->print_cr("warning: not at safepoint -- verify may fail"); @@ -393,6 +416,7 @@ extern "C" DEBUGEXPORT void verify() { extern "C" DEBUGEXPORT void pp(void* p) { Command c("pp"); + if (!c.onThread()) return; FlagSetting fl(DisplayVMOutput, true); if (p == nullptr) { tty->print_cr("null"); @@ -416,14 +440,15 @@ extern "C" DEBUGEXPORT void pp(void* p) { } -extern "C" DEBUGEXPORT void findpc(intptr_t x); - extern "C" DEBUGEXPORT void ps() { // print stack - if (Thread::current_or_null() == nullptr) return; - Command c("ps"); - // Prints the stack of the current Java thread + Command c("ps"); + if (!c.onThread()) return; JavaThread* p = JavaThread::active(); + if (p == nullptr) { + tty->print_cr("Failed: JavaThread::active is null"); + return; + } tty->print(" for thread: "); p->print(); tty->cr(); @@ -450,7 +475,12 @@ extern "C" DEBUGEXPORT void ps() { // print stack extern "C" DEBUGEXPORT void pfl() { // print frame layout Command c("pfl"); + if (!c.onThread()) return; JavaThread* p = JavaThread::active(); + if (p == nullptr) { + tty->print_cr("Failed: JavaThread::active is null"); + return; + } tty->print(" for thread: "); p->print(); tty->cr(); @@ -460,34 +490,39 @@ extern "C" DEBUGEXPORT void pfl() { } extern "C" DEBUGEXPORT void psf() { // print stack frames - { - Command c("psf"); - JavaThread* p = JavaThread::active(); - tty->print(" for thread: "); - p->print(); - tty->cr(); - if (p->has_last_Java_frame()) { - p->trace_frames(); - } + Command c("psf"); + if (!c.onThread()) return; + JavaThread* p = JavaThread::active(); + if (p == nullptr) { + tty->print_cr("Failed: JavaThread::active is null"); + return; + } + tty->print(" for thread: "); + p->print(); + tty->cr(); + if (p->has_last_Java_frame()) { + p->trace_frames(); } } extern "C" DEBUGEXPORT void threads() { Command c("threads"); + if (!c.onThread()) return; Threads::print(false, true); } extern "C" DEBUGEXPORT void psd() { Command c("psd"); + if (!c.onThread()) return; SystemDictionary::print(); } extern "C" DEBUGEXPORT void pss() { // print all stacks - if (Thread::current_or_null() == nullptr) return; Command c("pss"); + if (!c.onThread()) return; Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true)); } @@ -534,12 +569,14 @@ extern "C" DEBUGEXPORT nmethod* findnm(intptr_t addr) { extern "C" DEBUGEXPORT void find(intptr_t x) { Command c("find"); + if (!c.onThread()) return; os::print_location(tty, x, false); } extern "C" DEBUGEXPORT void findpc(intptr_t x) { Command c("findpc"); + if (!c.onThread()) return; os::print_location(tty, x, true); } @@ -551,6 +588,7 @@ extern "C" DEBUGEXPORT void findpc(intptr_t x) { // call findmethod("*ang/Object*", "wait:(*J*)V", 0x1) -> list all "wait" methods in j.l.Object that have a long parameter extern "C" DEBUGEXPORT void findclass(const char* class_name_pattern, int flags) { Command c("findclass"); + if (!c.onThread()) return; ClassPrinter::print_flags_help(tty); ClassPrinter::print_classes(class_name_pattern, flags, tty); } @@ -558,6 +596,7 @@ extern "C" DEBUGEXPORT void findclass(const char* class_name_pattern, int flags) extern "C" DEBUGEXPORT void findmethod(const char* class_name_pattern, const char* method_pattern, int flags) { Command c("findmethod"); + if (!c.onThread()) return; ClassPrinter::print_flags_help(tty); ClassPrinter::print_methods(class_name_pattern, method_pattern, flags, tty); } @@ -644,6 +683,7 @@ void help() { #ifndef PRODUCT extern "C" DEBUGEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack Command c("pns"); + if (!c.onThread()) return; static char buf[O_BUFLEN]; // Call generic frame constructor (certain arguments may be ignored) frame fr(sp, fp, pc); @@ -662,6 +702,7 @@ extern "C" DEBUGEXPORT void pns(void* sp, void* fp, void* pc) { // print native // extern "C" DEBUGEXPORT void pns2() { // print native stack Command c("pns2"); + if (!c.onThread()) return; static char buf[O_BUFLEN]; address lastpc = nullptr; NativeStackPrinter nsp(Thread::current_or_null()); From 34c3ac0316dbd29ae670db51bd9230a1e77382d9 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Wed, 10 Sep 2025 16:00:28 +0000 Subject: [PATCH 025/120] 8162380: [TEST_BUG] MouseEvent/.../AltGraphModifierTest.java has only "Fail" button Reviewed-by: azvegint, aivanov --- test/jdk/ProblemList.txt | 1 - .../AltGraphModifierTest.java | 256 +++--------------- 2 files changed, 44 insertions(+), 213 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 475704f7e95..70e912d7e93 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -794,7 +794,6 @@ java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter_2.java 7131438,802 java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java 7187741 linux-all,macosx-all java/awt/xembed/server/TestXEmbedServerJava.java 8001150,8004031 generic-all java/awt/Modal/PrintDialogsTest/PrintDialogsTest.java 8068378 generic-all -java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java 8162380 generic-all java/awt/image/VolatileImage/VolatileImageConfigurationTest.java 8171069 macosx-all,linux-all java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java 8172245 linux-all java/awt/Frame/FrameStateTest/FrameStateTest.java 8203920 macosx-all,linux-all diff --git a/test/jdk/java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java b/test/jdk/java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java index 47d808f336d..c8730b28964 100644 --- a/test/jdk/java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java +++ b/test/jdk/java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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,51 +22,57 @@ */ /* - @test - @bug 8041928 8158616 - @requires (os.family != "mac") - @summary Confirm that the Alt-Gr Modifier bit is set correctly. - @run main/manual AltGraphModifierTest + * @test + * @bug 8041928 8158616 + * @requires (os.family != "mac") + * @summary Confirm that the Alt-Gr Modifier bit is set correctly. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual AltGraphModifierTest */ -import java.awt.Button; -import java.awt.Dialog; import java.awt.Frame; -import java.awt.Panel; -import java.awt.TextArea; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class AltGraphModifierTest { - private static void init() throws Exception { - String[] instructions - = { - "This test is for verifying Alt-Gr modifier of an event.", - "Linux :-", - "1. Please check if Alt-Gr key is present on keyboard.", - "2. If present, press the Alt-Gr key and perform", - " mouse click on the TestWindow.", - "3. Navigate to System Settings-> Keyboard-> Shortcuts->", - " Typing.", - "4. Select an option for the Alternative Characters Key", - " For example. Right Alt", - "5. Close the settings and navigate to test", - "6. Press Right Alt Key & perform mouse click on the", - " TestWindow", - "7. Test will exit by itself with appropriate result.", - " ", - }; - Sysout.createDialog(); - Sysout.printInstructions(instructions); + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test is for verifying Alt-Gr modifier of an event. + Please check if Alt-Gr key is present on keyboard. + If not present, press Pass. + On Windows: + Press Alt-Gr or Right Alt key and simultaneously + perform mouse click on the "TestWindow". + On Linux: + Navigate to + System Settings-> Keyboard-> Special Character Entry + Select "Right Alt" option for the "Alternate Characters Key" + Close the settings and navigate to test + Press Right Alt Key & simultaneously + perform mouse click on the "TestWindow". + + If the system does not have such setting, press Pass. + After the test, change the Setting of "Alternate Characters Key" + back to "Layout default". + + If "Alt-Gr Modifier bit is set" message is displayed in logArea, + press Pass else press Fail. + """; + + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(AltGraphModifierTest::initTestWindow) + .logArea() + .build() + .awaitAndCheck(); } - static Frame mainFrame; - public static void initTestWindow() { - mainFrame = new Frame(); + public static Frame initTestWindow() { + Frame mainFrame = new Frame(); mainFrame.setTitle("TestWindow"); mainFrame.setBounds(700, 10, 300, 300); mainFrame.addMouseListener(new MouseAdapter() { @@ -74,186 +80,12 @@ public class AltGraphModifierTest { public void mousePressed(MouseEvent e) { int ex = e.getModifiersEx(); if ((ex & InputEvent.ALT_GRAPH_DOWN_MASK) == 0) { - AltGraphModifierTest.fail("Alt-Gr Modifier bit is not set."); + PassFailJFrame.log("Alt-Gr Modifier bit is not set."); } else { - AltGraphModifierTest.pass(); + PassFailJFrame.log("Alt-Gr Modifier bit is set"); } } }); - mainFrame.setVisible(true); - } - - public static void dispose() { - Sysout.dispose(); - mainFrame.dispose(); - } - - /** - * *************************************************** - * Standard Test Machinery Section DO NOT modify anything in this section -- - * it's a standard chunk of code which has all of the synchronisation - * necessary for the test harness. By keeping it the same in all tests, it - * is easier to read and understand someone else's test, as well as insuring - * that all tests behave correctly with the test harness. There is a section - * following this for test-defined classes - * **************************************************** - */ - private static boolean theTestPassed = false; - private static boolean testGeneratedInterrupt = false; - private static String failureMessage = ""; - private static Thread mainThread = null; - final private static int sleepTime = 300000; - - public static void main(String args[]) throws Exception { - mainThread = Thread.currentThread(); - try { - init(); - initTestWindow(); - } catch (Exception e) { - e.printStackTrace(); - } - try { - mainThread.sleep(sleepTime); - } catch (InterruptedException e) { - dispose(); - if (testGeneratedInterrupt && !theTestPassed) { - throw new Exception(failureMessage); - } - } - if (!testGeneratedInterrupt) { - dispose(); - throw new RuntimeException("Timed out after " + sleepTime / 1000 - + " seconds"); - } - } - - public static synchronized void pass() { - theTestPassed = true; - testGeneratedInterrupt = true; - mainThread.interrupt(); - } - - public static synchronized void fail(String whyFailed) { - theTestPassed = false; - testGeneratedInterrupt = true; - failureMessage = whyFailed; - mainThread.interrupt(); - } -} - -// *********** End Standard Test Machinery Section ********** -/** - * ************************************************** - * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk - * of code whose purpose is to make user interaction uniform, and thereby make - * it simpler to read and understand someone else's test. - * ************************************************** - */ -/** - * This is part of the standard test machinery. It creates a dialog (with the - * instructions), and is the interface for sending text messages to the user. To - * print the instructions, send an array of strings to Sysout.createDialog - * WithInstructions method. Put one line of instructions per array entry. To - * display a message for the tester to see, simply call Sysout.println with the - * string to be displayed. This mimics System.out.println but works within the - * test harness as well as standalone. - */ -class Sysout { - private static TestDialog dialog; - private static Frame frame; - - public static void createDialog() { - frame = new Frame(); - dialog = new TestDialog(frame, "Instructions"); - String[] defInstr = {"Instructions will appear here. ", ""}; - dialog.printInstructions(defInstr); - dialog.show(); - println("Any messages for the tester will display here."); - } - - public static void printInstructions(String[] instructions) { - dialog.printInstructions(instructions); - } - - public static void println(String messageIn) { - dialog.displayMessage(messageIn); - } - - public static void dispose() { - dialog.dispose(); - frame.dispose(); - } -} - -/** - * This is part of the standard test machinery. It provides a place for the test - * instructions to be displayed, and a place for interactive messages to the - * user to be displayed. To have the test instructions displayed, see Sysout. To - * have a message to the user be displayed, see Sysout. Do not call anything in - * this dialog directly. - */ -class TestDialog extends Dialog implements ActionListener { - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - Panel buttonP; - Button failB; - - // DO NOT call this directly, go through Sysout - public TestDialog(Frame frame, String name) { - super(frame, name); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); - add("North", instructionsText); - - messageText = new TextArea("", 5, maxStringLength, scrollBoth); - add("Center", messageText); - - buttonP = new Panel(); - failB = new Button("Fail"); - failB.setActionCommand("fail"); - failB.addActionListener(this); - buttonP.add("Center", failB); - - add("South", buttonP); - pack(); - setVisible(true); - } - - // DO NOT call this directly, go through Sysout - public void printInstructions(String[] instructions) { - instructionsText.setText(""); - String printStr, remainingStr; - for (int i = 0; i < instructions.length; i++) { - remainingStr = instructions[i]; - while (remainingStr.length() > 0) { - if (remainingStr.length() >= maxStringLength) { - int posOfSpace = remainingStr. - lastIndexOf(' ', maxStringLength - 1); - - if (posOfSpace <= 0) { - posOfSpace = maxStringLength - 1; - } - - printStr = remainingStr.substring(0, posOfSpace + 1); - remainingStr = remainingStr.substring(posOfSpace + 1); - } - else { - printStr = remainingStr; - remainingStr = ""; - } - instructionsText.append(printStr + "\n"); - } - } - } - - public void displayMessage(String messageIn) { - messageText.append(messageIn + "\n"); - } - - public void actionPerformed(ActionEvent e) { - if (e.getActionCommand() == "fail") { - AltGraphModifierTest.fail("User Clicked Fail"); - } + return mainFrame; } } From af18ff8d7c8fdd6437304839caa2e49eb34b6caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 10 Sep 2025 16:43:40 +0000 Subject: [PATCH 026/120] 8367007: javadoc generation of JavaFX docs fails after fix for JDK-8350920 Reviewed-by: liach, nbenalla --- .../formats/html/AbstractMemberWriter.java | 2 +- .../doclets/formats/html/ClassWriter.java | 2 +- .../doclets/toolkit/PropertyUtils.java | 96 ++++++++++--------- .../javadoc/doclet/testJavaFX/TestJavaFX.java | 36 ++++++- .../jdk/javadoc/doclet/testJavaFX/pkg1/B.java | 27 ++++++ 5 files changed, 115 insertions(+), 48 deletions(-) create mode 100644 test/langtools/jdk/javadoc/doclet/testJavaFX/pkg1/B.java diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java index e2e286d5856..fabca0a894d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java @@ -319,7 +319,7 @@ public abstract class AbstractMemberWriter { inheritedHeader.add(links); if (utils.isIncluded(inheritedClass)) { - var pHelper = writer.getPropertyHelper(); + var pHelper = configuration.propertyUtils.getPropertyHelper(inheritedClass); Table table = createInheritedSummaryTable(inheritedClass); for (Element member : inheritedMembers) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java index d301dd6e283..f5a5a48222c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java @@ -96,7 +96,7 @@ public class ClassWriter extends SubWriterHolderWriter { this.typeElement = typeElement; this.classTree = classTree; - pHelper = new PropertyUtils.PropertyHelper(configuration, typeElement); + pHelper = configuration.propertyUtils.getPropertyHelper(typeElement); switch (typeElement.getKind()) { case ENUM -> setEnumDocumentation(typeElement); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/PropertyUtils.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/PropertyUtils.java index 823f172b360..8913be5b301 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/PropertyUtils.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/PropertyUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -54,6 +54,8 @@ import static jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable.Kind. */ public class PropertyUtils { + final BaseConfiguration configuration; + final TypeMirror jbObservableType; final Pattern fxMethodPatterns; @@ -62,7 +64,10 @@ public class PropertyUtils { final Types typeUtils; + final Map propertyHelpers = new HashMap<>(); + PropertyUtils(BaseConfiguration configuration) { + this.configuration = configuration; BaseOptions options = configuration.getOptions(); javafx = options.javafx(); @@ -82,30 +87,37 @@ public class PropertyUtils { : null; } + /** + * Returns a property helper for the given type element. + * @param typeElement a type element + * @return the property helper + */ + public PropertyHelper getPropertyHelper(TypeElement typeElement) { + return propertyHelpers.computeIfAbsent(typeElement, te -> new PropertyHelper(configuration, te)); + } + /** * Returns a base name for a property method. Supposing we * have {@code BooleanProperty acmeProperty()}, then "acme" * will be returned. - * @param propertyMethod + * @param propertyMethod a property method * @return the base name of a property method. */ public String getBaseName(ExecutableElement propertyMethod) { String name = propertyMethod.getSimpleName().toString(); - String baseName = name.substring(0, name.indexOf("Property")); - return baseName; + return name.substring(0, name.indexOf("Property")); } /** * Returns a property getter's name. Supposing we have a property * method {@code DoubleProperty acmeProperty()}, then "getAcme" * will be returned. - * @param propertyMethod + * @param propertyMethod a property method * @return the property getter's name. */ public String getGetName(ExecutableElement propertyMethod) { String baseName = getBaseName(propertyMethod); - String fnUppercased = "" + - Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1); + String fnUppercased = Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1); return "get" + fnUppercased; } @@ -113,20 +125,19 @@ public class PropertyUtils { * Returns an "is" method's name for a property method. Supposing * we have a property method {@code BooleanProperty acmeProperty()}, * then "isAcme" will be returned. - * @param propertyMethod + * @param propertyMethod a property method * @return the property is getter's name. */ public String getIsName(ExecutableElement propertyMethod) { String baseName = getBaseName(propertyMethod); - String fnUppercased = "" + - Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1); + String fnUppercased = Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1); return "is" + fnUppercased; } /** * Returns true if a property method could have an "is" method, meaning * {@code isAcme} could exist for a property method. - * @param propertyMethod + * @param propertyMethod a property method * @return true if the property could have an "is" method, false otherwise. */ public boolean hasIsMethod(ExecutableElement propertyMethod) { @@ -139,20 +150,19 @@ public class PropertyUtils { * Returns a property setter's name. Supposing we have a property * method {@code DoubleProperty acmeProperty()}, then "setAcme" * will be returned. - * @param propertyMethod + * @param propertyMethod a property method * @return the property setter's method name. */ public String getSetName(ExecutableElement propertyMethod) { String baseName = getBaseName(propertyMethod); - String fnUppercased = "" + - Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1); + String fnUppercased = Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1); return "set" + fnUppercased; } /** * Returns true if the given setter method is a valid property setter * method. - * @param setterMethod + * @param setterMethod a setter method * @return true if setter method, false otherwise. */ public boolean isValidSetterMethod(ExecutableElement setterMethod) { @@ -161,28 +171,28 @@ public class PropertyUtils { /** * Returns true if the method is a property method. - * @param propertyMethod + * @param method a method * @return true if the method is a property method, false otherwise. */ - public boolean isPropertyMethod(ExecutableElement propertyMethod) { + public boolean isPropertyMethod(ExecutableElement method) { if (!javafx || - !propertyMethod.getParameters().isEmpty() || - !propertyMethod.getTypeParameters().isEmpty()) { + !method.getParameters().isEmpty() || + !method.getTypeParameters().isEmpty()) { return false; } - String methodName = propertyMethod.getSimpleName().toString(); + String methodName = method.getSimpleName().toString(); if (!methodName.endsWith("Property") || fxMethodPatterns.matcher(methodName).matches()) { return false; } - TypeMirror returnType = propertyMethod.getReturnType(); + TypeMirror returnType = method.getReturnType(); if (jbObservableType == null) { // JavaFX references missing, make a lazy backward compatible check. return returnType.getKind() != TypeKind.VOID; } else { // Apply strict checks since JavaFX references are available - returnType = typeUtils.erasure(propertyMethod.getReturnType()); + returnType = typeUtils.erasure(method.getReturnType()); return typeUtils.isAssignable(returnType, jbObservableType); } } @@ -202,20 +212,13 @@ public class PropertyUtils { * method. If any method does not have a comment, one will be provided. */ public static class PropertyHelper { - private final BaseConfiguration configuration; - private final Utils utils; - private final TypeElement typeElement; + private Map classPropertiesMap = null; - private final Map classPropertiesMap = new HashMap<>(); - - public PropertyHelper(BaseConfiguration configuration, TypeElement typeElement) { - this.configuration = configuration; - this.utils = configuration.utils; - this.typeElement = typeElement; - computeProperties(); + private PropertyHelper(BaseConfiguration configuration, TypeElement typeElement) { + computeProperties(configuration, typeElement); } - private void computeProperties() { + private void computeProperties(BaseConfiguration configuration, TypeElement typeElement) { VisibleMemberTable vmt = configuration.getVisibleMemberTable(typeElement); List props = ElementFilter.methodsIn(vmt.getVisibleMembers(PROPERTIES)); for (ExecutableElement propertyMethod : props) { @@ -223,37 +226,42 @@ public class PropertyUtils { ExecutableElement setter = vmt.getPropertySetter(propertyMethod); VariableElement field = vmt.getPropertyField(propertyMethod); - addToPropertiesMap(propertyMethod, field, getter, setter); + addToPropertiesMap(configuration, propertyMethod, field, getter, setter); } } - private void addToPropertiesMap(ExecutableElement propertyMethod, + private void addToPropertiesMap(BaseConfiguration configuration, + ExecutableElement propertyMethod, VariableElement field, ExecutableElement getter, ExecutableElement setter) { // determine the preferred element from which to derive the property description - Element e = field == null || !utils.hasDocCommentTree(field) + Element e = field == null || !configuration.utils.hasDocCommentTree(field) ? propertyMethod : field; - if (e == field && utils.hasDocCommentTree(propertyMethod)) { + if (e == field && configuration.utils.hasDocCommentTree(propertyMethod)) { configuration.getReporter().print(Diagnostic.Kind.WARNING, propertyMethod, configuration.getDocResources().getText("doclet.duplicate.comment.for.property")); } - addToPropertiesMap(propertyMethod, e); - addToPropertiesMap(getter, e); - addToPropertiesMap(setter, e); + if (classPropertiesMap == null) { + classPropertiesMap = new HashMap<>(); + } + addToPropertiesMap(configuration, propertyMethod, e); + addToPropertiesMap(configuration, getter, e); + addToPropertiesMap(configuration, setter, e); } - private void addToPropertiesMap(Element propertyMethod, + private void addToPropertiesMap(BaseConfiguration configuration, + Element propertyMethod, Element commentSource) { Objects.requireNonNull(commentSource); if (propertyMethod == null) { return; } - DocCommentTree docTree = utils.hasDocCommentTree(propertyMethod) - ? utils.getDocCommentTree(propertyMethod) + DocCommentTree docTree = configuration.utils.hasDocCommentTree(propertyMethod) + ? configuration.utils.getDocCommentTree(propertyMethod) : null; /* The second condition is required for the property buckets. In @@ -271,7 +279,7 @@ public class PropertyUtils { * @return the element for the property documentation, null if there is none. */ public Element getPropertyElement(Element element) { - return classPropertiesMap.get(element); + return classPropertiesMap == null ? null : classPropertiesMap.get(element); } } } diff --git a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java index 4fa89ee0ead..04e032dbe05 100644 --- a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java +++ b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java @@ -25,7 +25,7 @@ * @test * @bug 7112427 8012295 8025633 8026567 8061305 8081854 8150130 8162363 * 8167967 8172528 8175200 8178830 8182257 8186332 8182765 8025091 - * 8203791 8184205 8249633 8261976 8350920 + * 8203791 8184205 8249633 8261976 8350920 8367007 * @summary Test of the JavaFX doclet features. * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -54,11 +54,18 @@ public class TestJavaFX extends JavadocTester { "-sourcepath", testSrc, "-javafx", "--disable-javafx-strict-checks", - "-Xdoclint:all,-missing", "-package", "pkg1"); checkExit(Exit.OK); + checkOutput(Output.OUT, true, + "C.java:78: warning: no comment"); + checkOutput(Output.OUT, false, + "C.java:59: warning: no comment", + "C.java:61: warning: no comment", + "C.java:63: warning: no comment", + "C.java:67: warning: no comment"); + checkOutput("pkg1/C.html", true, """

      See Also:
      @@ -266,6 +273,31 @@ public class TestJavaFX extends JavadocTester { """); checkOutput("pkg1/D.html", false, "shouldNotAppear"); + + // Test for inherited properties and property methods. + checkOrder("pkg1/B.html", + """ + Properties inherited from class C""", + """ +
      Defines if paused.
      """, + """ +
      Defines the direction/speed at which the Timeline is expected to + be played.
      """, + """ + Methods inherited from class C""", + """ +
      Gets the value of the rate property.
      """, + """ +
      Gets the value of the paused property.
      """, + """ +
      Defines if paused.
      """, + """ +
      Defines the direction/speed at which the Timeline is expected to + be played.
      """, + """ +
      Sets the value of the paused property.
      """, + """ +
      Sets the value of the rate property.
      """); } /* diff --git a/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg1/B.java b/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg1/B.java new file mode 100644 index 00000000000..2ec6f77833a --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testJavaFX/pkg1/B.java @@ -0,0 +1,27 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +public class B extends C { +} From 7a3025e3d7d33ed02db34c1485aa3c7b44b2d8ee Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 10 Sep 2025 17:24:53 +0000 Subject: [PATCH 027/120] 8367348: Enhance PassFailJFrame to support links in HTML Reviewed-by: aivanov --- .../awt/regtesthelpers/PassFailJFrame.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index c0a483056df..49e56493488 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -72,6 +72,7 @@ import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.Timer; import javax.swing.border.Border; +import javax.swing.event.HyperlinkListener; import javax.swing.text.JTextComponent; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.StyleSheet; @@ -98,7 +99,8 @@ import static javax.swing.SwingUtilities.isEventDispatchThread; * tester. The instructions can be either plain text or HTML. If the * text of the instructions starts with {@code ""}, the * instructions are displayed as HTML, as supported by Swing, which - * provides richer formatting options. + * provides richer formatting options. To handle navigating links in the + * instructions, call {@link Builder#hyperlinkListener} to install a listener. *

      * The instructions are displayed in a text component with word-wrapping * so that there's no horizontal scroll bar. If the text doesn't fit, a @@ -592,6 +594,7 @@ public final class PassFailJFrame { frame.add(createInstructionUIPanel(instructions, testTimeOut, rows, columns, + null, false, false, 0), BorderLayout.CENTER); @@ -610,6 +613,7 @@ public final class PassFailJFrame { createInstructionUIPanel(builder.instructions, builder.testTimeOut, builder.rows, builder.columns, + builder.hyperlinkListener, builder.screenCapture, builder.addLogArea, builder.logAreaRows); @@ -631,6 +635,7 @@ public final class PassFailJFrame { private static JComponent createInstructionUIPanel(String instructions, long testTimeOut, int rows, int columns, + HyperlinkListener hyperlinkListener, boolean enableScreenCapture, boolean addLogArea, int logAreaRows) { @@ -643,6 +648,9 @@ public final class PassFailJFrame { JTextComponent text = instructions.startsWith("") ? configureHTML(instructions, rows, columns) : configurePlainText(instructions, rows, columns); + if (hyperlinkListener != null && text instanceof JEditorPane ep) { + ep.addHyperlinkListener(hyperlinkListener); + } text.setEditable(false); text.setBorder(createTextBorder()); text.setCaretPosition(0); @@ -716,7 +724,7 @@ public final class PassFailJFrame { // Reduce the list default margins styles.addRule("ol, ul { margin-left-ltr: 30; margin-left-rtl: 30 }"); // Make the size of code (and other elements) the same as other text - styles.addRule("code, kbd, samp, pre { font-size: inherit }"); + styles.addRule("code, kbd, samp, pre { font-size: inherit; background: #DDD; }"); return text; } @@ -1398,6 +1406,7 @@ public final class PassFailJFrame { private int rows; private int columns; private boolean screenCapture; + private HyperlinkListener hyperlinkListener; private boolean addLogArea; private int logAreaRows = 10; @@ -1478,6 +1487,18 @@ public final class PassFailJFrame { return this; } + /** + * Sets a {@link HyperlinkListener} for navigating links inside + * the instructions pane. + * + * @param hyperlinkListener the listener + * @return this builder + */ + public Builder hyperlinkListener(HyperlinkListener hyperlinkListener) { + this.hyperlinkListener = hyperlinkListener; + return this; + } + public Builder screenCapture() { this.screenCapture = true; return this; From 4e2a85f7500876d65c36aeaf54f5361a1549e7f5 Mon Sep 17 00:00:00 2001 From: Man Cao Date: Wed, 10 Sep 2025 17:42:15 +0000 Subject: [PATCH 028/120] 8366118: DontCompileHugeMethods is not respected with -XX:-TieredCompilation Co-authored-by: Chuck Rasbold Co-authored-by: Justin King Reviewed-by: rasbold, iveresov, jiangli --- .../share/compiler/compilationPolicy.cpp | 39 +++--- .../runtime/TestDontCompileHugeMethods.java | 122 ++++++++++++++++++ 2 files changed, 142 insertions(+), 19 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/runtime/TestDontCompileHugeMethods.java diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index 5db6cb1b0cc..36b597b6e37 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -922,28 +922,29 @@ void CompilationPolicy::compile(const methodHandle& mh, int bci, CompLevel level return; } - if (!CompilationModeFlag::disable_intermediate()) { - // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling - // in the interpreter and then compile with C2 (the transition function will request that, - // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with - // pure C1. - if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) { - if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) { - compile(mh, bci, CompLevel_simple, THREAD); - } - return; + // Check if the method can be compiled. Additional logic for TieredCompilation: + // If it cannot be compiled with C1, continue profiling in the interpreter + // and then compile with C2 (the transition function will request that, + // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with + // pure C1. + if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) { + if (!CompilationModeFlag::disable_intermediate() && + level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) { + compile(mh, bci, CompLevel_simple, THREAD); } - if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) { - if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) { - nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false); - if (osr_nm != nullptr && osr_nm->comp_level() > CompLevel_simple) { - // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted. - osr_nm->make_not_entrant(nmethod::InvalidationReason::OSR_INVALIDATION_FOR_COMPILING_WITH_C1); - } - compile(mh, bci, CompLevel_simple, THREAD); + return; + } + if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) { + if (!CompilationModeFlag::disable_intermediate() && + level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) { + nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false); + if (osr_nm != nullptr && osr_nm->comp_level() > CompLevel_simple) { + // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted. + osr_nm->make_not_entrant(nmethod::InvalidationReason::OSR_INVALIDATION_FOR_COMPILING_WITH_C1); } - return; + compile(mh, bci, CompLevel_simple, THREAD); } + return; } if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) { return; diff --git a/test/hotspot/jtreg/compiler/runtime/TestDontCompileHugeMethods.java b/test/hotspot/jtreg/compiler/runtime/TestDontCompileHugeMethods.java new file mode 100644 index 00000000000..c5e035edbd0 --- /dev/null +++ b/test/hotspot/jtreg/compiler/runtime/TestDontCompileHugeMethods.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2025, Google LLC. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8366118 + * @summary Check that a huge method is not compiled under -XX:+DontCompileHugeMethods. + * @library /test/lib + * @run main compiler.runtime.TestDontCompileHugeMethods + */ +package compiler.runtime; + +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.io.IOException; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class TestDontCompileHugeMethods { + + private static final String HUGE_SWITCH_CLASS_NAME = "HugeSwitch"; + + private static void generateClass(Writer writer) throws IOException { + writer.write(""" + public class HugeSwitch { + private static int hugeSwitch(int x) { + switch (x) { + """); + for (int i = 0; i < 2000; i++) { + writer.write(" case " + i + ": return " + i + " + 1;\n"); + } + writer.write(""" + default: + return 0; + } + } + private static int shortMethod(int x) { + if (x % 3 == 0) { + return x - 1; + } + return x + 1; + } + public static void main(String[] args) { + int val = 0; + for (int i = 0; i < 100000; i++) { + val += hugeSwitch(shortMethod(i)); + } + System.out.println(val); + } + } + """); + } + + private static void compileClass(Path workDir, Path sourceFile) throws Exception { + JDKToolLauncher javac = JDKToolLauncher.create("javac").addToolArg("-d") + .addToolArg(workDir.toAbsolutePath().toString()).addToolArg("-cp") + .addToolArg(Utils.TEST_CLASS_PATH).addToolArg(sourceFile.toAbsolutePath().toString()); + + OutputAnalyzer output = ProcessTools.executeProcess(javac.getCommand()); + output.shouldHaveExitValue(0); + } + + private static void generateAndCompileClass(Path workDir) throws Exception { + Path sourceFile = workDir.resolve(HUGE_SWITCH_CLASS_NAME + ".java"); + try (Writer writer = Files.newBufferedWriter(sourceFile)) { + generateClass(writer); + } catch (IOException e) { + throw new RuntimeException(e); + } + compileClass(workDir, sourceFile); + } + + private static void runTest(Path workDir, List jvmArgs) throws Exception { + ArrayList command = new ArrayList<>(); + command.add("-XX:+PrintCompilation"); + command.add("-Xbatch"); + command.addAll(jvmArgs); + command.add("-cp"); + command.add(workDir.toAbsolutePath().toString()); + command.add(HUGE_SWITCH_CLASS_NAME); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(command); + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + analyzer.shouldHaveExitValue(0); + analyzer.shouldContain(" HugeSwitch::shortMethod ("); + analyzer.shouldNotContain(" HugeSwitch::hugeSwitch ("); + } + + public static void main(String[] args) throws Exception { + Path workDir = Paths.get(""); + generateAndCompileClass(workDir); + + runTest(workDir, List.of()); + runTest(workDir, List.of("-XX:-TieredCompilation")); + } +} From fdc11a1569248c9b671b66d547b4616aeb953ecf Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Wed, 10 Sep 2025 18:41:42 +0000 Subject: [PATCH 029/120] 8367131: Test com/sun/jdi/ThreadMemoryLeakTest.java fails on 32 bits Reviewed-by: lmesnik, cjplummer, shade --- test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java b/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java index 59168a4de7e..5431b8835a2 100644 --- a/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java +++ b/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java @@ -28,7 +28,7 @@ * * @comment Don't allow -Xcomp or -Xint as they impact memory useage and number of iterations. * Require compressed oops because not doing so increases memory usage. - * @requires (vm.compMode == "Xmixed") & vm.opt.final.UseCompressedOops + * @requires (vm.compMode == "Xmixed") & (vm.bits == 32 | vm.opt.final.UseCompressedOops) * @run build TestScaffold VMConnection TargetListener TargetAdapter * @run compile -g ThreadMemoryLeakTest.java * @comment run with -Xmx7m so any leak will quickly produce OOME From 85715e1050fa774c3267dbbe2f749717aeeec8ff Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Wed, 10 Sep 2025 19:21:00 +0000 Subject: [PATCH 030/120] 8317269: Store old classes in linked state in AOT cache Reviewed-by: coleenp, matsaave --- src/hotspot/share/cds/aotMetaspace.cpp | 20 +- src/hotspot/share/cds/aotMetaspace.hpp | 1 + src/hotspot/share/cds/archiveBuilder.cpp | 2 +- src/hotspot/share/cds/cdsConfig.cpp | 30 ++ src/hotspot/share/cds/cdsConfig.hpp | 9 + src/hotspot/share/cds/dumpTimeClassInfo.cpp | 13 +- src/hotspot/share/cds/dumpTimeClassInfo.hpp | 15 +- src/hotspot/share/cds/dynamicArchive.cpp | 6 + .../share/cds/lambdaProxyClassDictionary.cpp | 6 +- src/hotspot/share/cds/runTimeClassInfo.cpp | 10 +- src/hotspot/share/cds/runTimeClassInfo.hpp | 4 +- .../classfile/systemDictionaryShared.cpp | 316 +++++++++++++++--- .../classfile/systemDictionaryShared.hpp | 21 +- src/hotspot/share/oops/instanceKlass.cpp | 14 +- src/hotspot/share/oops/methodData.cpp | 5 +- src/hotspot/share/oops/trainingData.cpp | 9 +- src/hotspot/share/prims/jvm.cpp | 7 + src/hotspot/share/runtime/mutexLocker.cpp | 4 +- test/hotspot/jtreg/TEST.groups | 6 +- .../cds/appcds/aotCache/ExcludedClasses.java | 12 +- .../runtime/cds/appcds/aotCache/OldA.jasm | 38 +++ .../cds/appcds/aotCache/OldClassSupport.java | 162 +++++++++ ...dClassWithExcludedVerifierConstraints.jasm | 50 +++ .../OldClassWithVerifierConstraints.jasm | 50 +++ .../AOTClassLinkingVerification.java | 294 ++++++++++++++++ .../appcds/aotClassLinking/BadNewClass.jasm | 52 +++ .../appcds/aotClassLinking/BadNewClass2.jasm | 52 +++ .../appcds/aotClassLinking/BadNewClass3.jasm | 53 +++ .../appcds/aotClassLinking/BadNewClass4.jasm | 53 +++ .../appcds/aotClassLinking/BadOldClass.jasm | 52 +++ .../appcds/aotClassLinking/BadOldClass2.jasm | 52 +++ .../appcds/aotClassLinking/BadOldClass3.jasm | 53 +++ .../appcds/aotClassLinking/BadOldClass4.jasm | 53 +++ .../aotClassLinking/BulkLoaderTest.java | 2 +- .../appcds/aotClassLinking/GoodOldClass.jasm | 49 +++ 35 files changed, 1485 insertions(+), 90 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldA.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassSupport.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithExcludedVerifierConstraints.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithVerifierConstraints.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVerification.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass2.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass3.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass4.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass2.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass3.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass4.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GoodOldClass.jasm diff --git a/src/hotspot/share/cds/aotMetaspace.cpp b/src/hotspot/share/cds/aotMetaspace.cpp index c2d9d0193f5..cca82bed4f1 100644 --- a/src/hotspot/share/cds/aotMetaspace.cpp +++ b/src/hotspot/share/cds/aotMetaspace.cpp @@ -652,6 +652,8 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables(AOTClassLocationConfig*& } void VM_PopulateDumpSharedSpace::doit() { + CDSConfig::set_is_at_aot_safepoint(true); + if (!CDSConfig::is_dumping_final_static_archive()) { guarantee(!CDSConfig::is_using_archive(), "We should not be using an archive when we dump"); } @@ -717,6 +719,8 @@ void VM_PopulateDumpSharedSpace::doit() { _map_info->set_serialized_data(serialized_data); _map_info->set_cloned_vtables(CppVtables::vtables_serialized_base()); _map_info->header()->set_class_location_config(cl_config); + + CDSConfig::set_is_at_aot_safepoint(false); } class CollectClassesForLinking : public KlassClosure { @@ -773,12 +777,9 @@ bool AOTMetaspace::may_be_eagerly_linked(InstanceKlass* ik) { return true; } -void AOTMetaspace::link_shared_classes(TRAPS) { - AOTClassLinker::initialize(); - AOTClassInitializer::init_test_class(CHECK); - +void AOTMetaspace::link_all_loaded_classes(JavaThread* current) { while (true) { - ResourceMark rm(THREAD); + ResourceMark rm(current); CollectClassesForLinking collect_classes; bool has_linked = false; const GrowableArray* mirrors = collect_classes.mirrors(); @@ -786,7 +787,7 @@ void AOTMetaspace::link_shared_classes(TRAPS) { OopHandle mirror = mirrors->at(i); InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(mirror.resolve())); if (may_be_eagerly_linked(ik)) { - has_linked |= try_link_class(THREAD, ik); + has_linked |= try_link_class(current, ik); } } @@ -796,6 +797,13 @@ void AOTMetaspace::link_shared_classes(TRAPS) { // Class linking includes verification which may load more classes. // Keep scanning until we have linked no more classes. } +} + +void AOTMetaspace::link_shared_classes(TRAPS) { + AOTClassLinker::initialize(); + AOTClassInitializer::init_test_class(CHECK); + + link_all_loaded_classes(THREAD); // Eargerly resolve all string constants in constant pools { diff --git a/src/hotspot/share/cds/aotMetaspace.hpp b/src/hotspot/share/cds/aotMetaspace.hpp index 6c0ad37dbf7..1803199766d 100644 --- a/src/hotspot/share/cds/aotMetaspace.hpp +++ b/src/hotspot/share/cds/aotMetaspace.hpp @@ -135,6 +135,7 @@ public: } static bool try_link_class(JavaThread* current, InstanceKlass* ik); + static void link_all_loaded_classes(JavaThread* current); static void link_shared_classes(TRAPS) NOT_CDS_RETURN; static bool may_be_eagerly_linked(InstanceKlass* ik) NOT_CDS_RETURN_(false); diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index 42d575a012f..77f51443bb2 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -937,7 +937,7 @@ void ArchiveBuilder::make_klasses_shareable() { ADD_COUNT(num_enum_klasses); } - if (!ik->can_be_verified_at_dumptime()) { + if (CDSConfig::is_old_class_for_verifier(ik)) { ADD_COUNT(num_old_klasses); old = " old"; } diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 90b802731f0..d3048b9ee7a 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -56,6 +56,7 @@ bool CDSConfig::_has_temp_aot_config_file = false; bool CDSConfig::_old_cds_flags_used = false; bool CDSConfig::_new_aot_flags_used = false; bool CDSConfig::_disable_heap_dumping = false; +bool CDSConfig::_is_at_aot_safepoint = false; const char* CDSConfig::_default_archive_path = nullptr; const char* CDSConfig::_input_static_archive_path = nullptr; @@ -922,6 +923,35 @@ bool CDSConfig::is_dumping_lambdas_in_legacy_mode() { return !is_dumping_method_handles(); } +bool CDSConfig::is_preserving_verification_constraints() { + // Verification dependencies are classes used in assignability checks by the + // bytecode verifier. In the following example, the verification dependencies + // for X are A and B. + // + // class X { + // A getA() { return new B(); } + // } + // + // With the AOT cache, we can ensure that all the verification dependencies + // (A and B in the above example) are unconditionally loaded during the bootstrap + // of the production run. This means that if a class was successfully verified + // in the assembly phase, all of the verifier's assignability checks will remain + // valid in the production run, so we don't need to verify aot-linked classes again. + + if (is_dumping_preimage_static_archive()) { // writing AOT config + return AOTClassLinking; + } else if (is_dumping_final_static_archive()) { // writing AOT cache + return is_dumping_aot_linked_classes(); + } else { + // For simplicity, we don't support this optimization with the old CDS workflow. + return false; + } +} + +bool CDSConfig::is_old_class_for_verifier(const InstanceKlass* ik) { + return ik->major_version() < 50 /*JAVA_6_VERSION*/; +} + #if INCLUDE_CDS_JAVA_HEAP bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() { return check_options_incompatible_with_dumping_heap() != nullptr; diff --git a/src/hotspot/share/cds/cdsConfig.hpp b/src/hotspot/share/cds/cdsConfig.hpp index 1fd229ff34f..8361cf052db 100644 --- a/src/hotspot/share/cds/cdsConfig.hpp +++ b/src/hotspot/share/cds/cdsConfig.hpp @@ -30,6 +30,7 @@ #include "utilities/macros.hpp" class JavaThread; +class InstanceKlass; class CDSConfig : public AllStatic { #if INCLUDE_CDS @@ -43,6 +44,7 @@ class CDSConfig : public AllStatic { static bool _has_aot_linked_classes; static bool _is_single_command_training; static bool _has_temp_aot_config_file; + static bool _is_at_aot_safepoint; const static char* _default_archive_path; const static char* _input_static_archive_path; @@ -99,6 +101,9 @@ public: static const char* type_of_archive_being_written(); static void prepare_for_dumping(); + static bool is_at_aot_safepoint() { return CDS_ONLY(_is_at_aot_safepoint) NOT_CDS(false); } + static void set_is_at_aot_safepoint(bool value) { CDS_ONLY(_is_at_aot_safepoint = value); } + // --- Basic CDS features // archive(s) in general @@ -161,6 +166,10 @@ public: static bool is_using_aot_linked_classes() NOT_CDS_JAVA_HEAP_RETURN_(false); static void set_has_aot_linked_classes(bool has_aot_linked_classes) NOT_CDS_JAVA_HEAP_RETURN; + // Bytecode verification + static bool is_preserving_verification_constraints(); + static bool is_old_class_for_verifier(const InstanceKlass* ik); + // archive_path // Points to the classes.jsa in $JAVA_HOME (could be input or output) diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.cpp b/src/hotspot/share/cds/dumpTimeClassInfo.cpp index 8af762dba4d..0f5773a2729 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.cpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.cpp @@ -47,7 +47,7 @@ size_t DumpTimeClassInfo::runtime_info_bytesize() const { num_enum_klass_static_fields()); } -void DumpTimeClassInfo::add_verification_constraint(InstanceKlass* k, Symbol* name, +void DumpTimeClassInfo::add_verification_constraint(Symbol* name, Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) { if (_verifier_constraints == nullptr) { _verifier_constraints = new (mtClass) GrowableArray(4, mtClass); @@ -73,9 +73,14 @@ void DumpTimeClassInfo::add_verification_constraint(InstanceKlass* k, Symbol* na if (log_is_enabled(Trace, aot, verification)) { ResourceMark rm; - log_trace(aot, verification)("add_verification_constraint: %s: %s must be subclass of %s [0x%x] array len %d flags len %d", - k->external_name(), from_name->as_klass_external_name(), - name->as_klass_external_name(), c, vc_array->length(), vcflags_array->length()); + if (from_name != nullptr) { + log_trace(aot, verification)("add verification constraint: %s: %s must be subclass of %s [0x%x]", + _klass->external_name(), from_name->as_klass_external_name(), + name->as_klass_external_name(), c); + } else { + log_trace(aot, verification)("added old verification constraint: %s: %s", _klass->external_name(), + name->as_klass_external_name()); + } } } diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp index 0bc0f8bedda..c2f83b22337 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp @@ -88,7 +88,7 @@ class DumpTimeClassInfo: public CHeapObj { Symbol* _from_name; public: DTVerifierConstraint() : _name(nullptr), _from_name(nullptr) {} - DTVerifierConstraint(Symbol* n, Symbol* fn) : _name(n), _from_name(fn) { + DTVerifierConstraint(Symbol* n, Symbol* fn = nullptr) : _name(n), _from_name(fn) { Symbol::maybe_increment_refcount(_name); Symbol::maybe_increment_refcount(_from_name); } @@ -152,8 +152,9 @@ public: DumpTimeClassInfo& operator=(const DumpTimeClassInfo&) = delete; ~DumpTimeClassInfo(); - void add_verification_constraint(InstanceKlass* k, Symbol* name, - Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object); + // For old verifier: only name is saved; all other fields are null/false. + void add_verification_constraint(Symbol* name, + Symbol* from_name = nullptr, bool from_field_is_protected = false, bool from_is_array = false, bool from_is_object = false); void record_linking_constraint(Symbol* name, Handle loader1, Handle loader2); void add_enum_klass_static_field(int archived_heap_root_index); int enum_klass_static_field(int which_field); @@ -175,6 +176,14 @@ public: return array_length_or_zero(_verifier_constraint_flags); } + Symbol* verifier_constraint_name_at(int i) const { + return _verifier_constraints->at(i).name(); + } + + Symbol* verifier_constraint_from_name_at(int i) const { + return _verifier_constraints->at(i).from_name(); + } + int num_loader_constraints() const { return array_length_or_zero(_loader_constraints); } diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index d628a4e991f..58b354b9240 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -110,6 +110,12 @@ public: } void doit() { + CDSConfig::set_is_at_aot_safepoint(true); + doit_inner(); + CDSConfig::set_is_at_aot_safepoint(false); + } + + void doit_inner() { verify_universe("Before CDS dynamic dump"); DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm); diff --git a/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp b/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp index c8281ef497c..62b1b8c05f1 100644 --- a/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp +++ b/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp @@ -471,12 +471,12 @@ class LambdaProxyClassDictionary::CleanupDumpTimeLambdaProxyClassTable: StackObj // If the caller class and/or nest_host are excluded, the associated lambda proxy // must also be excluded. - bool always_exclude = SystemDictionaryShared::check_for_exclusion(caller_ik, nullptr) || - SystemDictionaryShared::check_for_exclusion(nest_host, nullptr); + bool always_exclude = SystemDictionaryShared::should_be_excluded(caller_ik) || + SystemDictionaryShared::should_be_excluded(nest_host); for (int i = info._proxy_klasses->length() - 1; i >= 0; i--) { InstanceKlass* ik = info._proxy_klasses->at(i); - if (always_exclude || SystemDictionaryShared::check_for_exclusion(ik, nullptr)) { + if (always_exclude || SystemDictionaryShared::should_be_excluded(ik)) { LambdaProxyClassDictionary::reset_registered_lambda_proxy_class(ik); info._proxy_klasses->remove_at(i); } diff --git a/src/hotspot/share/cds/runTimeClassInfo.cpp b/src/hotspot/share/cds/runTimeClassInfo.cpp index d93ef5e9c1d..832b0ce8932 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.cpp +++ b/src/hotspot/share/cds/runTimeClassInfo.cpp @@ -40,12 +40,18 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) { _num_verifier_constraints = info.num_verifier_constraints(); _num_loader_constraints = info.num_loader_constraints(); int i; + + if (CDSConfig::is_preserving_verification_constraints() && CDSConfig::is_dumping_final_static_archive()) { + // The production run doesn't need the verifier constraints, as we can guarantee that all classes checked by + // the verifier during AOT training/assembly phases cannot be replaced in the production run. + _num_verifier_constraints = 0; + } if (_num_verifier_constraints > 0) { RTVerifierConstraint* vf_constraints = verifier_constraints(); char* flags = verifier_constraint_flags(); for (i = 0; i < _num_verifier_constraints; i++) { - vf_constraints[i]._name = builder->any_to_offset_u4(info._verifier_constraints->at(i).name()); - vf_constraints[i]._from_name = builder->any_to_offset_u4(info._verifier_constraints->at(i).from_name()); + vf_constraints[i]._name = builder->any_to_offset_u4(info._verifier_constraints->at(i).name()); + vf_constraints[i]._from_name = builder->any_or_null_to_offset_u4(info._verifier_constraints->at(i).from_name()); } for (i = 0; i < _num_verifier_constraints; i++) { flags[i] = info._verifier_constraint_flags->at(i); diff --git a/src/hotspot/share/cds/runTimeClassInfo.hpp b/src/hotspot/share/cds/runTimeClassInfo.hpp index 29670f5ec51..371924f9065 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.hpp +++ b/src/hotspot/share/cds/runTimeClassInfo.hpp @@ -59,7 +59,9 @@ class RunTimeClassInfo { u4 _name; u4 _from_name; Symbol* name() { return ArchiveUtils::offset_to_archived_address(_name); } - Symbol* from_name() { return ArchiveUtils::offset_to_archived_address(_from_name); } + Symbol* from_name() { + return (_from_name == 0) ? nullptr : ArchiveUtils::offset_to_archived_address(_from_name); + } }; struct RTLoaderConstraint { diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 45a5dc2328c..eda823704ca 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -204,28 +204,156 @@ DumpTimeClassInfo* SystemDictionaryShared::get_info_locked(InstanceKlass* k) { return info; } -bool SystemDictionaryShared::check_for_exclusion(InstanceKlass* k, DumpTimeClassInfo* info) { - if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(k)) { - // We have reached a super type that's already in the base archive. Treat it - // as "not excluded". - return false; - } - - if (info == nullptr) { - info = _dumptime_table->get(k); - assert(info != nullptr, "supertypes of any classes in _dumptime_table must either be shared, or must also be in _dumptime_table"); - } +bool SystemDictionaryShared::should_be_excluded_impl(InstanceKlass* k, DumpTimeClassInfo* info) { + assert_lock_strong(DumpTimeTable_lock); if (!info->has_checked_exclusion()) { - if (check_for_exclusion_impl(k)) { - info->set_excluded(); - } - info->set_has_checked_exclusion(); + check_exclusion_for_self_and_dependencies(k); + assert(info->has_checked_exclusion(), "must be"); } return info->is_excluded(); } +// returns bool and takes a single parameter of Symbol* +// The return value indicates whether we want to keep on iterating or not. +template +void SystemDictionaryShared::iterate_verification_constraint_names(InstanceKlass* k, DumpTimeClassInfo* info, Function func) { + int n = info->num_verifier_constraints(); + bool cont; // continue iterating? + for (int i = 0; i < n; i++) { + cont = func(info->verifier_constraint_name_at(i)); + if (!cont) { + return; // early termination + } + Symbol* from_name = info->verifier_constraint_from_name_at(i); + if (from_name != nullptr) { + cont = func(from_name); + if (!cont) { + return; // early termination + } + } + } +} + +// This is a table of classes that need to be checked for exclusion. +class SystemDictionaryShared::ExclusionCheckCandidates + : public HashTable { + void add_candidate(InstanceKlass* k) { + if (contains(k)) { + return; + } + if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(k)) { + return; + } + + DumpTimeClassInfo* info = SystemDictionaryShared::get_info_locked(k); + if (info->has_checked_exclusion()) { + // We have check exclusion of k and all of its dependencies, so there's no need to check again. + return; + } + + put(k, info); + + if (!k->is_loaded()) { + // super types are not yet initialized for k. + return; + } + + InstanceKlass* super = k->java_super(); + if (super != nullptr) { + add_candidate(super); + } + + Array* interfaces = k->local_interfaces(); + int len = interfaces->length(); + for (int i = 0; i < len; i++) { + add_candidate(interfaces->at(i)); + } + + InstanceKlass* nest_host = k->nest_host_or_null(); + if (nest_host != nullptr && nest_host != k) { + add_candidate(nest_host); + } + + if (CDSConfig::is_preserving_verification_constraints()) { + SystemDictionaryShared::iterate_verification_constraint_names(k, info, [&] (Symbol* constraint_class_name) { + Klass* constraint_bottom_class = find_verification_constraint_bottom_class(k, constraint_class_name); + if (constraint_bottom_class != nullptr && constraint_bottom_class->is_instance_klass()) { + add_candidate(InstanceKlass::cast(constraint_bottom_class)); + } + return true; // Keep iterating. + }); + } + } + +public: + ExclusionCheckCandidates(InstanceKlass* k) { + add_candidate(k); + } +}; + +// A class X is excluded if check_self_exclusion() returns true for X or any of +// X's "exclusion dependency" classes, which include: +// - ik's super types +// - ik's nest host (if any) +// +// plus, if CDSConfig::is_preserving_verification_constraints()==true: +// - ik's verification constraints. These are the classes used in assignability checks +// when verifying ik's bytecodes. +// +// This method ensure that exclusion check is performed on X and all of its exclusion dependencies. +void SystemDictionaryShared::check_exclusion_for_self_and_dependencies(InstanceKlass* ik) { + assert_lock_strong(DumpTimeTable_lock); + ResourceMark rm; + + // This will recursively find ik and all of its exclusion dependencies that have not yet been checked. + ExclusionCheckCandidates candidates(ik); + + // (1) Check each class to see if it should be excluded due to its own problems + candidates.iterate_all([&] (InstanceKlass* k, DumpTimeClassInfo* info) { + if (check_self_exclusion(k)) { + info->set_excluded(); + } + }); + + // (2) Check each class to see if it should be excluded because of problems in a depeendency class + while (true) { + bool found_new_exclusion = false; + + candidates.iterate_all([&] (InstanceKlass* k, DumpTimeClassInfo* info) { + if (!info->is_excluded() && check_dependencies_exclusion(k, info)) { + info->set_excluded(); + found_new_exclusion = true; + } + }); + + // Algorithm notes: + // + // The dependencies form a directed graph, possibly cyclic. Class X is excluded + // if it has at least one directed path that reaches class Y, where + // check_self_exclusion(Y) returns true. + // + // Because of the possibility of cycles in the graph, we cannot use simple + // recursion. Otherwise we will either never terminate, or will miss some paths. + // + // Hence, we keep doing a linear scan of the candidates until we stop finding + // new exclusions. + // + // In the worst case, we find one exclusion per iteration of the while loop, + // so the while loop gets executed O(N^2) times. However, in reality we have + // very few exclusions, so in most cases the while loop executes only once, and we + // walk each edge in the dependencies graph exactly once. + if (!found_new_exclusion) { + break; + } + } + candidates.iterate_all([&] (InstanceKlass* k, DumpTimeClassInfo* info) { + // All candidates have been fully checked, so we don't need to check them again. + info->set_has_checked_exclusion(); + }); +} + // Returns true so the caller can do: return warn_excluded("....."); bool SystemDictionaryShared::warn_excluded(InstanceKlass* k, const char* reason) { ResourceMark rm; @@ -248,7 +376,8 @@ bool SystemDictionaryShared::is_early_klass(InstanceKlass* ik) { return (info != nullptr) ? info->is_early_klass() : false; } -bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { +bool SystemDictionaryShared::check_self_exclusion(InstanceKlass* k) { + assert_lock_strong(DumpTimeTable_lock); if (CDSConfig::is_dumping_final_static_archive() && k->defined_by_other_loaders() && k->in_aot_cache()) { return false; // Do not exclude: unregistered classes are passed from preimage to final image. @@ -301,9 +430,8 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { return warn_excluded(k, "Failed verification"); } else if (CDSConfig::is_dumping_aot_linked_classes()) { // Most loaded classes should have been speculatively linked by AOTMetaspace::link_class_for_cds(). - // However, we do not speculatively link old classes, as they are not recorded by - // SystemDictionaryShared::record_linking_constraint(). As a result, such an unlinked - // class may fail to verify in AOTLinkedClassBulkLoader::init_required_classes_for_loader(), + // Old classes may not be linked if CDSConfig::is_preserving_verification_constraints()==false. + // An unlinked class may fail to verify in AOTLinkedClassBulkLoader::init_required_classes_for_loader(), // causing the JVM to fail at bootstrap. return warn_excluded(k, "Unlinked class not supported by AOTClassLinking"); } else if (CDSConfig::is_dumping_preimage_static_archive()) { @@ -329,10 +457,13 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { return true; } - InstanceKlass* super = k->super(); - if (super != nullptr && check_for_exclusion(super, nullptr)) { - ResourceMark rm; - aot_log_warning(aot)("Skipping %s: super class %s is excluded", k->name()->as_C_string(), super->name()->as_C_string()); + return false; +} + +// Returns true if DumpTimeClassInfo::is_excluded() is true for at least one of k's exclusion dependencies. +bool SystemDictionaryShared::check_dependencies_exclusion(InstanceKlass* k, DumpTimeClassInfo* info) { + InstanceKlass* super = k->java_super(); + if (super != nullptr && is_dependency_excluded(k, super, "super")) { return true; } @@ -340,21 +471,87 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { int len = interfaces->length(); for (int i = 0; i < len; i++) { InstanceKlass* intf = interfaces->at(i); - if (check_for_exclusion(intf, nullptr)) { - ResourceMark rm; - aot_log_warning(aot)("Skipping %s: interface %s is excluded", k->name()->as_C_string(), intf->name()->as_C_string()); + if (is_dependency_excluded(k, intf, "interface")) { return true; } } InstanceKlass* nest_host = k->nest_host_or_null(); - if (nest_host != nullptr && nest_host != k && check_for_exclusion(nest_host, nullptr)) { - ResourceMark rm; - aot_log_warning(aot)("Skipping %s: nest_host class %s is excluded", k->name()->as_C_string(), nest_host->name()->as_C_string()); + if (nest_host != nullptr && nest_host != k && is_dependency_excluded(k, nest_host, "nest host class")) { return true; } - return false; // false == k should NOT be excluded + if (CDSConfig::is_preserving_verification_constraints()) { + bool excluded = false; + + iterate_verification_constraint_names(k, info, [&] (Symbol* constraint_class_name) { + if (check_verification_constraint_exclusion(k, constraint_class_name)) { + // If one of the verification constraint class has been excluded, the assignability checks + // by the verifier may no longer be valid in the production run. For safety, exclude this class. + excluded = true; + return false; // terminate iteration; k will be excluded + } else { + return true; // keep iterating + } + }); + + if (excluded) { + // At least one verification constraint class has been excluded + return true; + } + } + + return false; +} + +bool SystemDictionaryShared::is_dependency_excluded(InstanceKlass* k, InstanceKlass* dependency, const char* type) { + if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(dependency)) { + return false; + } + DumpTimeClassInfo* dependency_info = get_info_locked(dependency); + if (dependency_info->is_excluded()) { + ResourceMark rm; + aot_log_warning(aot)("Skipping %s: %s %s is excluded", k->name()->as_C_string(), type, dependency->name()->as_C_string()); + return true; + } + return false; +} + +bool SystemDictionaryShared::check_verification_constraint_exclusion(InstanceKlass* k, Symbol* constraint_class_name) { + Klass* constraint_bottom_class = find_verification_constraint_bottom_class(k, constraint_class_name); + if (constraint_bottom_class == nullptr) { + // We don't have a bottom class (constraint_class_name is a type array), or constraint_class_name + // has not been loaded. The latter case happens when the new verifier was checking + // if constraint_class_name is assignable to an interface, and found the answer without resolving + // constraint_class_name. + // + // Since this class is not even loaded, it surely cannot be excluded. + return false; + } else if (constraint_bottom_class->is_instance_klass()) { + if (is_dependency_excluded(k, InstanceKlass::cast(constraint_bottom_class), "verification constraint")) { + return true; + } + } else { + assert(constraint_bottom_class->is_typeArray_klass(), "must be"); + } + + return false; +} + +Klass* SystemDictionaryShared::find_verification_constraint_bottom_class(InstanceKlass* k, Symbol* constraint_class_name) { + Thread* current = Thread::current(); + Handle loader(current, k->class_loader()); + Klass* constraint_class = SystemDictionary::find_instance_or_array_klass(current, constraint_class_name, loader); + if (constraint_class == nullptr) { + return nullptr; + } + + if (constraint_class->is_objArray_klass()) { + constraint_class = ObjArrayKlass::cast(constraint_class)->bottom_klass(); + } + + precond(constraint_class->is_typeArray_klass() || constraint_class->is_instance_klass()); + return constraint_class; } bool SystemDictionaryShared::is_builtin_loader(ClassLoaderData* loader_data) { @@ -556,7 +753,7 @@ void SystemDictionaryShared::handle_class_unloading(InstanceKlass* klass) { void SystemDictionaryShared::init_dumptime_info_from_preimage(InstanceKlass* k) { init_dumptime_info(k); - copy_verification_constraints_from_preimage(k); + copy_verification_info_from_preimage(k); copy_linking_constraints_from_preimage(k); if (SystemDictionary::is_platform_class_loader(k->class_loader())) { @@ -651,16 +848,21 @@ public: // Returns true if the class should be excluded. This can be called by // AOTConstantPoolResolver before or after we enter the CDS safepoint. // When called before the safepoint, we need to link the class so that -// it can be checked by check_for_exclusion(). +// it can be checked by should_be_excluded_impl(). bool SystemDictionaryShared::should_be_excluded(Klass* k) { assert(CDSConfig::is_dumping_archive(), "sanity"); assert(CDSConfig::current_thread_is_vm_or_dumper(), "sanity"); - if (k->is_objArray_klass()) { - return should_be_excluded(ObjArrayKlass::cast(k)->bottom_klass()); + if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(k)) { + // We have reached a super type that's already in the base archive. Treat it + // as "not excluded". + return false; } - if (!k->is_instance_klass()) { + if (k->is_objArray_klass()) { + return should_be_excluded(ObjArrayKlass::cast(k)->bottom_klass()); + } else if (!k->is_instance_klass()) { + assert(k->is_typeArray_klass(), "must be"); return false; } else { InstanceKlass* ik = InstanceKlass::cast(k); @@ -672,7 +874,7 @@ bool SystemDictionaryShared::should_be_excluded(Klass* k) { if (!SafepointSynchronize::is_at_safepoint()) { if (!ik->is_linked()) { - // check_for_exclusion() below doesn't link unlinked classes. We come + // should_be_excluded_impl() below doesn't link unlinked classes. We come // here only when we are trying to aot-link constant pool entries, so // we'd better link the class. JavaThread* THREAD = JavaThread::current(); @@ -681,6 +883,10 @@ bool SystemDictionaryShared::should_be_excluded(Klass* k) { CLEAR_PENDING_EXCEPTION; return true; // linking failed -- let's exclude it } + + // Also link any classes that were loaded for the verification of ik or its supertypes. + // Otherwise we might miss the verification constraints of those classes. + AOTMetaspace::link_all_loaded_classes(THREAD); } MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); @@ -688,8 +894,17 @@ bool SystemDictionaryShared::should_be_excluded(Klass* k) { if (p->is_excluded()) { return true; } - return check_for_exclusion(ik, p); + return should_be_excluded_impl(ik, p); } else { + // When called within the CDS safepoint, the correctness of this function + // relies on the call to AOTMetaspace::link_all_loaded_classes() + // that happened right before we enter the CDS safepoint. + // + // Do not call this function in other types of safepoints. For example, if this + // is called in a GC safepoint, a klass may be improperly excluded because some + // of its verification constraints have not yet been linked. + assert(CDSConfig::is_at_aot_safepoint(), "Do not call this function in any other safepoint"); + // No need to check for is_linked() as all eligible classes should have // already been linked in AOTMetaspace::link_class_for_cds(). // Can't take the lock as we are in safepoint. @@ -697,12 +912,13 @@ bool SystemDictionaryShared::should_be_excluded(Klass* k) { if (p->is_excluded()) { return true; } - return check_for_exclusion(ik, p); + return should_be_excluded_impl(ik, p); } } } void SystemDictionaryShared::finish_exclusion_checks() { + assert_at_safepoint(); if (CDSConfig::is_dumping_dynamic_archive() || CDSConfig::is_dumping_preimage_static_archive()) { // Do this first -- if a base class is excluded due to duplication, // all of its subclasses will also be excluded. @@ -713,7 +929,7 @@ void SystemDictionaryShared::finish_exclusion_checks() { } _dumptime_table->iterate_all_live_classes([&] (InstanceKlass* k, DumpTimeClassInfo& info) { - SystemDictionaryShared::check_for_exclusion(k, &info); + SystemDictionaryShared::should_be_excluded_impl(k, &info); }); _dumptime_table->update_counts(); @@ -793,7 +1009,7 @@ void SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbo bool* skip_assignability_check) { assert(CDSConfig::is_dumping_archive(), "sanity"); DumpTimeClassInfo* info = get_info(k); - info->add_verification_constraint(k, name, from_name, from_field_is_protected, + info->add_verification_constraint(name, from_name, from_field_is_protected, from_is_array, from_is_object); if (CDSConfig::is_dumping_classic_static_archive() && !is_builtin(k)) { @@ -818,6 +1034,15 @@ void SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbo } } +// When the old verifier is verifying the class at dump time, it tries to resolve a +// class with the given . For the verification result to be valid at run time, we must +// ensure that resolves to the exact same Klass as in dump time. +void SystemDictionaryShared::add_old_verification_constraint(Thread* current, InstanceKlass* ik, Symbol* name) { + precond(CDSConfig::is_preserving_verification_constraints()); + DumpTimeClassInfo* info = get_info(ik); + info->add_verification_constraint(name); +} + void SystemDictionaryShared::add_enum_klass_static_field(InstanceKlass* ik, int root_index) { assert(CDSConfig::is_dumping_heap(), "sanity"); DumpTimeClassInfo* info = get_info_locked(ik); @@ -836,6 +1061,13 @@ void SystemDictionaryShared::check_verification_constraints(InstanceKlass* klass Symbol* name = vc->name(); Symbol* from_name = vc->from_name(); + if (from_name == nullptr) { + // This is for old verifier. No need to check, as we can guarantee that all classes checked by + // the old verifier during AOT training phase cannot be replaced in the asembly phase. + precond(CDSConfig::is_dumping_final_static_archive()); + continue; + } + if (log_is_enabled(Trace, aot, verification)) { ResourceMark rm(THREAD); log_trace(aot, verification)("check_verification_constraint: %s: %s must be subclass of %s [0x%x]", @@ -860,7 +1092,7 @@ void SystemDictionaryShared::check_verification_constraints(InstanceKlass* klass } } -void SystemDictionaryShared::copy_verification_constraints_from_preimage(InstanceKlass* klass) { +void SystemDictionaryShared::copy_verification_info_from_preimage(InstanceKlass* klass) { assert(CDSConfig::is_using_archive(), "called at run time with CDS enabled only"); DumpTimeClassInfo* dt_info = get_info(klass); RunTimeClassInfo* rt_info = RunTimeClassInfo::get_for(klass); // from preimage @@ -872,7 +1104,7 @@ void SystemDictionaryShared::copy_verification_constraints_from_preimage(Instanc Symbol* name = vc->name(); Symbol* from_name = vc->from_name(); - dt_info->add_verification_constraint(klass, name, from_name, + dt_info->add_verification_constraint(name, from_name, rt_info->from_field_is_protected(i), rt_info->from_is_array(i), rt_info->from_is_object(i)); } } diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index 30b38a5aa59..baad020cb61 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -146,7 +146,7 @@ class SystemDictionaryShared: public SystemDictionary { }; private: - + class ExclusionCheckCandidates; static DumpTimeSharedClassTable* _dumptime_table; static ArchiveInfo _static_archive; @@ -175,14 +175,27 @@ private: static void write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin); static bool is_jfr_event_class(InstanceKlass *k); - static bool check_for_exclusion_impl(InstanceKlass* k); + static bool should_be_excluded_impl(InstanceKlass* k, DumpTimeClassInfo* info); + + // exclusion checks + static void check_exclusion_for_self_and_dependencies(InstanceKlass *k); + static bool check_self_exclusion(InstanceKlass* k); + static bool check_dependencies_exclusion(InstanceKlass* k, DumpTimeClassInfo* info); + static bool check_verification_constraint_exclusion(InstanceKlass* k, Symbol* constraint_class_name); + static bool is_dependency_excluded(InstanceKlass* k, InstanceKlass* dependency, const char* type); + static bool is_excluded_verification_constraint(InstanceKlass* k, Symbol* constraint_class_name); + static Klass* find_verification_constraint_bottom_class(InstanceKlass* k, Symbol* constraint_class_name); + static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; static bool has_been_redefined(InstanceKlass* k); DEBUG_ONLY(static bool _class_loading_may_happen;) - static void copy_verification_constraints_from_preimage(InstanceKlass* klass); + static void copy_verification_info_from_preimage(InstanceKlass* klass); static void copy_linking_constraints_from_preimage(InstanceKlass* klass); + template + static void iterate_verification_constraint_names(InstanceKlass* k, DumpTimeClassInfo* info, Function func); + public: static bool is_early_klass(InstanceKlass* k); // Was k loaded while JvmtiExport::is_early_phase()==true static bool has_archived_enum_objs(InstanceKlass* ik); @@ -239,6 +252,7 @@ public: Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, bool* skip_assignability_check); + static void add_old_verification_constraint(Thread* current, InstanceKlass* k, Symbol* name); static void check_verification_constraints(InstanceKlass* klass, TRAPS) NOT_CDS_RETURN; static void add_enum_klass_static_field(InstanceKlass* ik, int root_index); @@ -258,7 +272,6 @@ public: static DumpTimeSharedClassTable* dumptime_table() { return _dumptime_table; } static bool should_be_excluded(Klass* k); - static bool check_for_exclusion(InstanceKlass* k, DumpTimeClassInfo* info); static void validate_before_archiving(InstanceKlass* k); static bool is_excluded_class(InstanceKlass* k); static void set_excluded(InstanceKlass* k); diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 1afc59d8da1..e0ebb92c7ae 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -2839,18 +2839,20 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl DEBUG_ONLY(FieldInfoStream::validate_search_table(_constants, _fieldinfo_stream, _fieldinfo_search_table)); } -// Check if a class or any of its supertypes has a version older than 50. -// CDS will not perform verification of old classes during dump time because -// without changing the old verifier, the verification constraint cannot be -// retrieved during dump time. -// Verification of archived old classes will be performed during run time. bool InstanceKlass::can_be_verified_at_dumptime() const { if (AOTMetaspace::in_aot_cache(this)) { // This is a class that was dumped into the base archive, so we know // it was verified at dump time. return true; } - if (major_version() < 50 /*JAVA_6_VERSION*/) { + + if (CDSConfig::is_preserving_verification_constraints()) { + return true; + } + + if (CDSConfig::is_old_class_for_verifier(this)) { + // The old verifier does not save verification constraints, so at run time + // SystemDictionaryShared::check_verification_constraints() will not work for this class. return false; } if (super() != nullptr && !super()->can_be_verified_at_dumptime()) { diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index 4c027e0839a..0463d8d9a81 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -323,9 +323,8 @@ void VirtualCallTypeData::post_initialize(BytecodeStream* stream, MethodData* md static bool is_excluded(Klass* k) { #if INCLUDE_CDS - if (SafepointSynchronize::is_at_safepoint() && - CDSConfig::is_dumping_archive() && - CDSConfig::current_thread_is_vm_or_dumper()) { + if (CDSConfig::is_at_aot_safepoint()) { + // Check for CDS exclusion only at CDS safe point. if (k->is_instance_klass() && !InstanceKlass::cast(k)->is_loaded()) { log_debug(aot, training)("Purged %s from MDO: unloaded class", k->name()->as_C_string()); return true; diff --git a/src/hotspot/share/oops/trainingData.cpp b/src/hotspot/share/oops/trainingData.cpp index 845dc20c0d0..8f906ae3d37 100644 --- a/src/hotspot/share/oops/trainingData.cpp +++ b/src/hotspot/share/oops/trainingData.cpp @@ -554,7 +554,11 @@ void KlassTrainingData::cleanup(Visitor& visitor) { } visitor.visit(this); if (has_holder()) { - bool is_excluded = !holder()->is_loaded() || SystemDictionaryShared::check_for_exclusion(holder(), nullptr); + bool is_excluded = !holder()->is_loaded(); + if (CDSConfig::is_at_aot_safepoint()) { + // Check for AOT exclusion only at AOT safe point. + is_excluded |= SystemDictionaryShared::should_be_excluded(holder()); + } if (is_excluded) { ResourceMark rm; log_debug(aot, training)("Cleanup KTD %s", name()->as_klass_external_name()); @@ -573,7 +577,8 @@ void MethodTrainingData::cleanup(Visitor& visitor) { } visitor.visit(this); if (has_holder()) { - if (SystemDictionaryShared::check_for_exclusion(holder()->method_holder(), nullptr)) { + if (CDSConfig::is_at_aot_safepoint() && SystemDictionaryShared::should_be_excluded(holder()->method_holder())) { + // Check for AOT exclusion only at AOT safe point. log_debug(aot, training)("Cleanup MTD %s::%s", name()->as_klass_external_name(), signature()->as_utf8()); if (_final_profile != nullptr && _final_profile->method() != _holder) { log_warning(aot, training)("Stale MDO for %s::%s", name()->as_klass_external_name(), signature()->as_utf8()); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 99c8a56c727..0651c173e7b 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -850,6 +850,13 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, log_debug(class, resolve)("%s %s (verification)", from_name, to); } +#if INCLUDE_CDS + if (CDSConfig::is_preserving_verification_constraints() && from_class->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(from_class); + SystemDictionaryShared::add_old_verification_constraint(THREAD, ik, h_name); + } +#endif + return result; JVM_END diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 0c604205939..e0eafbc416b 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -303,11 +303,11 @@ void mutex_init() { #endif MUTEX_DEFN(DumpTimeTable_lock , PaddedMutex , nosafepoint); MUTEX_DEFN(CDSLambda_lock , PaddedMutex , nosafepoint); - MUTEX_DEFN(DumpRegion_lock , PaddedMutex , nosafepoint); + MUTEX_DEFL(DumpRegion_lock , PaddedMutex , DumpTimeTable_lock); MUTEX_DEFN(ClassListFile_lock , PaddedMutex , nosafepoint); MUTEX_DEFN(UnregisteredClassesTable_lock , PaddedMutex , nosafepoint-1); MUTEX_DEFN(LambdaFormInvokers_lock , PaddedMutex , safepoint); - MUTEX_DEFN(ScratchObjects_lock , PaddedMutex , nosafepoint-1); // Holds DumpTimeTable_lock + MUTEX_DEFL(ScratchObjects_lock , PaddedMutex , DumpTimeTable_lock); MUTEX_DEFN(FinalImageRecipes_lock , PaddedMutex , nosafepoint); #endif // INCLUDE_CDS MUTEX_DEFN(Bootclasspath_lock , PaddedMutex , nosafepoint); diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index eeb5110b077..3af6548fe33 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -526,6 +526,7 @@ hotspot_aot_classlinking = \ -runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java \ -runtime/cds/appcds/cacheObject/ArchivedModuleCompareTest.java \ -runtime/cds/appcds/CDSandJFR.java \ + -runtime/cds/appcds/LambdaContainsOldInf.java \ -runtime/cds/appcds/customLoader/CustomClassListDump.java \ -runtime/cds/appcds/customLoader/HelloCustom_JFR.java \ -runtime/cds/appcds/customLoader/OldClassAndInf.java \ @@ -533,14 +534,17 @@ hotspot_aot_classlinking = \ -runtime/cds/appcds/customLoader/ParallelTestSingleFP.java \ -runtime/cds/appcds/customLoader/SameNameInTwoLoadersTest.java \ -runtime/cds/appcds/DumpClassListWithLF.java \ - -runtime/cds/appcds/dynamicArchive/ModulePath.java \ + -runtime/cds/appcds/dynamicArchive/LambdaContainsOldInf.java \ -runtime/cds/appcds/dynamicArchive/LambdaCustomLoader.java \ -runtime/cds/appcds/dynamicArchive/LambdaForOldInfInBaseArchive.java \ -runtime/cds/appcds/dynamicArchive/LambdaInBaseArchive.java \ -runtime/cds/appcds/dynamicArchive/LambdasInTwoArchives.java \ + -runtime/cds/appcds/dynamicArchive/ModulePath.java \ + -runtime/cds/appcds/dynamicArchive/NestHostOldInf.java \ -runtime/cds/appcds/dynamicArchive/OldClassAndInf.java \ -runtime/cds/appcds/dynamicArchive/OldClassInBaseArchive.java \ -runtime/cds/appcds/dynamicArchive/OldClassVerifierTrouble.java \ + -runtime/cds/appcds/dynamicArchive/RedefineCallerClassTest.java \ -runtime/cds/appcds/HelloExtTest.java \ -runtime/cds/appcds/javaldr/ExceptionDuringDumpAtObjectsInitPhase.java \ -runtime/cds/appcds/javaldr/GCDuringDump.java \ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java index f50a2d1f905..9a9524eb2f1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java @@ -99,7 +99,6 @@ public class ExcludedClasses { if (runMode == RunMode.ASSEMBLY) { out.shouldNotMatch("aot,resolve.*archived field.*TestApp.Foo => TestApp.Foo.ShouldBeExcluded.f:I"); } else if (runMode == RunMode.PRODUCTION) { - out.shouldContain("check_verification_constraint: TestApp$Foo$Taz: TestApp$Foo$ShouldBeExcludedChild must be subclass of TestApp$Foo$ShouldBeExcluded"); out.shouldContain("jdk.jfr.Event source: jrt:/jdk.jfr"); out.shouldMatch("TestApp[$]Foo[$]ShouldBeExcluded source: .*/app.jar"); out.shouldMatch("TestApp[$]Foo[$]ShouldBeExcludedChild source: .*/app.jar"); @@ -259,14 +258,9 @@ class TestApp { static class Taz { static ShouldBeExcluded m() { - // When verifying this method, we need to check the constraint that - // ShouldBeExcluded must be a supertype of ShouldBeExcludedChild. This information - // is checked by SystemDictionaryShared::check_verification_constraints() when the Taz - // class is linked during the production run. - // - // Because ShouldBeExcluded is excluded from the AOT archive, it must be loaded - // dynamically from app.jar inside SystemDictionaryShared::check_verification_constraints(). - // This must happen after the app class loader has been fully restored from the AOT cache. + // Taz should be excluded from the AOT cache because it has a verification constraint that + // "ShouldBeExcludedChild must be a subtype of ShouldBeExcluded", but ShouldBeExcluded is + // excluded from the AOT cache. return new ShouldBeExcludedChild(); } static void hotSpot4() { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldA.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldA.jasm new file mode 100644 index 00000000000..e0362eb0649 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldA.jasm @@ -0,0 +1,38 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class OldA + version 49:0 +{ + + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassSupport.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassSupport.java new file mode 100644 index 00000000000..42161b469bf --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassSupport.java @@ -0,0 +1,162 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary Store old classes linked state in AOT cache as long as their verification constraints are not excluded. + * @bug 8317269 + * @requires vm.cds.supports.aot.class.linking + * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @build OldClass OldA OldClassWithVerifierConstraints OldClassWithExcludedVerifierConstraints + * @build OldClassSupport + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar + * AppUsesOldClass MyIntf OldClass OldA NewB MyEvent MyEvent2 + * OldClassWithVerifierConstraints + * OldClassWithExcludedVerifierConstraints + * NewClassWithExcludedVerifierConstraints + * @run driver OldClassSupport + */ + +import jdk.jfr.Event; +import jdk.test.lib.cds.CDSAppTester; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class OldClassSupport { + static final String appJar = ClassFileInstaller.getJarPath("app.jar"); + static final String mainClass = "AppUsesOldClass"; + + public static void main(String[] args) throws Exception { + Tester tester = new Tester(); + tester.run(new String[] {"AOT", "--two-step-training"} ); + } + + static class Tester extends CDSAppTester { + public Tester() { + super(mainClass); + } + + @Override + public String classpath(RunMode runMode) { + return appJar; + } + + @Override + public String[] vmArgs(RunMode runMode) { + return new String[] { + "-Xlog:aot+class=debug", + "-Xlog:aot+resolve=trace", + }; + } + + @Override + public String[] appCommandLine(RunMode runMode) { + return new String[] {"-Xlog:cds+class=debug", mainClass}; + } + + @Override + public void checkExecution(OutputAnalyzer out, RunMode runMode) { + Class[] included = { + OldClass.class, + OldA.class, + NewB.class, + OldClassWithVerifierConstraints.class, + }; + + Class[] excluded = { + OldClassWithExcludedVerifierConstraints.class, + NewClassWithExcludedVerifierConstraints.class, + }; + + + if (runMode == RunMode.TRAINING) { + shouldInclude(out, false, included); + shouldNotInclude(out, excluded); + shouldSkip(out, excluded); + } else if (runMode == RunMode.ASSEMBLY) { + shouldInclude(out, true, included); + shouldNotInclude(out, excluded); + } + } + } + + static void shouldInclude(OutputAnalyzer out, boolean linked, Class[] classes) { + for (Class c : classes) { + out.shouldMatch("aot,class.* = 0x.* app *" + c.getName() + (linked ? " .*aot-linked" : "")); + } + } + + static void shouldNotInclude(OutputAnalyzer out, Class[] classes) { + for (Class c : classes) { + out.shouldNotMatch("aot,class.* = 0x.* app *" + c.getName()); + } + } + + static void shouldSkip(OutputAnalyzer out, Class[] classes) { + for (Class c : classes) { + out.shouldMatch("Skipping " + c.getName() + ": verification constraint .* is excluded"); + } + } +} + +class AppUsesOldClass { + public static void main(String args[]) { + System.out.println("Old Class Instance: " + new OldClass()); + + System.out.println(get_OldA_from_NewB()); + System.out.println(OldClassWithVerifierConstraints.get_OldA_from_NewB()); + System.out.println(OldClassWithExcludedVerifierConstraints.get_Event_from_MyEvent()); + System.out.println(NewClassWithExcludedVerifierConstraints.get_MyEvent_from_MyEvent2()); + System.out.println(new MyEvent()); + + // OldClassWithExcludedVerifierConstraints should still be excluded even it has been used + // in a lambda expression during the training run. + run((OldClassWithExcludedVerifierConstraints x) -> { + System.out.println(x); + }); + } + + static OldA get_OldA_from_NewB() { + return new NewB(); + } + + static void run(MyIntf intf) { + intf.function(new OldClassWithExcludedVerifierConstraints()); + } +} + +interface MyIntf { + public void function(OldClassWithExcludedVerifierConstraints x); +} + +class NewB extends OldA {} + +class MyEvent extends Event {} +class MyEvent2 extends MyEvent {} + +class NewClassWithExcludedVerifierConstraints { + static MyEvent get_MyEvent_from_MyEvent2() { + return new MyEvent2(); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithExcludedVerifierConstraints.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithExcludedVerifierConstraints.jasm new file mode 100644 index 00000000000..0c0556bf122 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithExcludedVerifierConstraints.jasm @@ -0,0 +1,50 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// This old class has a verification constraint that "MyEvent must be a subtype of Event". However, +// Event and all of its subtypes are excluded from the AOT cache, so this class must also be excluded. + +super public class OldClassWithExcludedVerifierConstraints + version 49:0 +{ + + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +static Method get_Event_from_MyEvent:"()Ljdk/jfr/Event;" + stack 2 locals 0 +{ + new class MyEvent; + dup; + invokespecial Method MyEvent."":"()V"; + areturn; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithVerifierConstraints.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithVerifierConstraints.jasm new file mode 100644 index 00000000000..946c51050a3 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/OldClassWithVerifierConstraints.jasm @@ -0,0 +1,50 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// This old class as a verification constraint that "NewB must be a subtype of OldA". Since both +// OldA and NewB are not excluded, then this class should be cached in aot-linked state. + +super public class OldClassWithVerifierConstraints + version 49:0 +{ + + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +static Method get_OldA_from_NewB:"()LOldA;" + stack 2 locals 0 +{ + new class NewB; + dup; + invokespecial Method NewB."":"()V"; + areturn; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVerification.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVerification.java new file mode 100644 index 00000000000..050f7d28585 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVerification.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8317269 + * @requires vm.cds + * @requires vm.cds.supports.aot.class.linking + * @summary Test for verification of classes that are aot-linked + * @library /test/jdk/lib/testlibrary + * /test/lib + * /test/hotspot/jtreg/runtime/cds/appcds + * /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @build GoodOldClass + * BadOldClass BadOldClass2 BadOldClass3 BadOldClass4 + * BadNewClass BadNewClass2 BadNewClass3 BadNewClass4 + * @build AOTClassLinkingVerification + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app1.jar + * AOTClassLinkingVerificationApp + * Unlinked UnlinkedSuper + * BadOldClass + * BadOldClass2 + * BadOldClass3 + * BadOldClass4 + * BadNewClass + * BadNewClass2 + * BadNewClass3 + * BadNewClass4 + * GoodOldClass Vehicle Car + * Util + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app2.jar + * Foo NotFoo + * UnlinkedSub + * @run driver AOTClassLinkingVerification + */ + +import java.io.File; +import java.lang.invoke.MethodHandles; +import jdk.test.lib.cds.CDSAppTester; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.whitebox.WhiteBox; + +public class AOTClassLinkingVerification { + static final String app1Jar = ClassFileInstaller.getJarPath("app1.jar"); + static final String app2Jar = ClassFileInstaller.getJarPath("app2.jar"); + static final String wbJar = TestCommon.getTestJar("WhiteBox.jar"); + static final String bootAppendWhiteBox = "-Xbootclasspath/a:" + wbJar; + static final String mainClass = AOTClassLinkingVerificationApp.class.getName(); + + static class Tester extends CDSAppTester { + public Tester(String testName) { + super(testName); + } + + @Override + public String[] vmArgs(RunMode runMode) { + if (runMode == RunMode.TRAINING || + runMode == RunMode.ASSEMBLY) { + return new String[] { + "-XX:+AOTClassLinking", "-Xlog:cds+class=debug", bootAppendWhiteBox, + }; + } else { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", bootAppendWhiteBox, + }; + } + } + + @Override + public String classpath(RunMode runMode) { + if (runMode == RunMode.TRAINING || + runMode == RunMode.ASSEMBLY) { + return app1Jar; + } else { + return app1Jar + File.pathSeparator + app2Jar; + } + } + + @Override + public String[] appCommandLine(RunMode runMode) { + if (runMode == RunMode.TRAINING || + runMode == RunMode.ASSEMBLY) { + return new String[] { + "AOTClassLinkingVerificationApp", app1Jar, "ASSEMBLY" + }; + } else { + return new String[] { + "AOTClassLinkingVerificationApp", app1Jar, "PRODUCTION" + }; + } + } + + @Override + public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception { + if (runMode == RunMode.TRAINING) { + out.shouldContain("Preload Warning: Verification failed for BadNewClass"); + out.shouldContain("Preload Warning: Verification failed for BadNewClass2"); + out.shouldContain("Preload Warning: Verification failed for BadNewClass3"); + out.shouldContain("Preload Warning: Verification failed for BadNewClass4"); + out.shouldContain("Preload Warning: Verification failed for BadOldClass"); + out.shouldContain("Preload Warning: Verification failed for BadOldClass2"); + out.shouldContain("Preload Warning: Verification failed for BadOldClass3"); + out.shouldContain("Preload Warning: Verification failed for BadOldClass4"); + out.shouldContain("Preload Warning: Verification failed for Unlinked"); + } + } + } + + public static void main(String[] args) throws Exception { + // Dump without app2.jar so: + // - Unlinked can be resolved, but UnlinkedSuper UnlinkedSub cannot be resolved, + // so Unlinked cannot be verified at dump time. + // - BadOldClass2 can be resolved, but Foo and NotFoo cannot be resolved, + // so BadOldClass2 cannot be verified at dump time. + // - BadNewClass2 can be resolved, but Foo and NotFoo cannot be resolved, + // so BadNewClass2 cannot be verified at dump time. + Tester t1 = new Tester("verification-aot-linked-classes"); + t1.run("AOT"); + } +} + +class AOTClassLinkingVerificationApp { + static WhiteBox wb = WhiteBox.getWhiteBox(); + static ClassLoader classLoader = AOTClassLinkingVerificationApp.class.getClassLoader(); + static File app1Jar; + static boolean isProduction; + public static void main(String[] args) throws Exception { + app1Jar = new File(args[0]); + isProduction = args[1].equals("PRODUCTION"); + if (isProduction) { + assertNotShared(UnlinkedSub.class); + assertShared(UnlinkedSuper.class); + assertNotShared(Unlinked.class); // failed verification during dump time + assertNotShared(Foo.class); + assertNotShared(NotFoo.class); + } + String s = null; + try { + s = Unlinked.doit(); + } catch (NoClassDefFoundError ncdfe) { + // UnlinkedSub is in app2Jar but only app1Jar is used during training + // and assembly phases. So NoClassDefFoundError is expected during + // during training and assembly phases. + if (isProduction) { + throw ncdfe; + } + } + if (isProduction && !s.equals("heyhey")) { + throw new RuntimeException("Unlinked.doit() returns wrong result: " + s); + } + + // =============================================================================== + + checkSimpleBadClass("BadOldClass"); + + Class cls_BadOldClass2 = Class.forName("BadOldClass2", false, classLoader); + if (isProduction) { + assertNotShared(cls_BadOldClass2); // failed verification during dump time + } + try { + cls_BadOldClass2.newInstance(); + throw new RuntimeException("BadOldClass2 cannot be verified"); + } catch (NoClassDefFoundError ncdfe) { + // BadOldClass2 loads Foo and NotFoo which is in app2Jar which is used + // only in production run. + if (isProduction) { + throw ncdfe; + } + } catch (VerifyError expected) {} + + checkSimpleBadClass("BadOldClass3"); + checkSimpleBadClass("BadOldClass4"); + + // =============================================================================== + + checkSimpleBadClass("BadNewClass"); + + Class cls_BadNewClass2 = Class.forName("BadNewClass2", false, classLoader); + if (isProduction) { + assertNotShared(cls_BadNewClass2); // failed verification during dump time + } + try { + cls_BadNewClass2.newInstance(); + throw new RuntimeException("BadNewClass2 cannot be verified"); + } catch (NoClassDefFoundError ncdfe) { + // BadNewClass2 loads Foo and NotFoo which is in app2Jar which is used + // only in production run. + if (isProduction) { + throw ncdfe; + } + } catch (VerifyError expected) {} + + checkSimpleBadClass("BadNewClass3"); + checkSimpleBadClass("BadNewClass4"); + + // =============================================================================== + + if (isProduction) { + assertAlreadyLoaded("Vehicle"); + assertAlreadyLoaded("Car"); + assertAlreadyLoaded("GoodOldClass"); + + assertShared(GoodOldClass.class); + assertShared(Vehicle.class); + assertShared(Car.class); + } + + GoodOldClass.doit(); // Should not fail + } + + static void checkSimpleBadClass(String className) throws Exception { + Class cls = Class.forName(className, false, classLoader); + if (isProduction) { + assertNotShared(cls); // failed verification during dump time + } + try { + cls.newInstance(); + throw new RuntimeException(className + " should not pass verification"); + } catch (VerifyError expected) {} + } + + static void assertShared(Class c) { + if (!wb.isSharedClass(c)) { + throw new RuntimeException("wb.isSharedClass(" + c.getName() + ") should be true"); + } + } + + static void assertNotShared(Class c) { + if (wb.isSharedClass(c)) { + throw new RuntimeException("wb.isSharedClass(" + c.getName() + ") should be false"); + } + } + + static void assertAlreadyLoaded(String className) throws Exception { + byte[] data = Util.getClassFileFromJar(app1Jar, className); + try { + MethodHandles.lookup().defineClass(data); + } catch (LinkageError e) { + if (e.getMessage().contains("duplicate class definition for " + className)) { + return; + } else { + throw e; + } + } + throw new RuntimeException(className + " must have already been loaded"); + } +} + + +class Unlinked { + static String doit() { + UnlinkedSuper sup = new UnlinkedSub(); + return sup.doit(); + } +} + +abstract class UnlinkedSuper { + abstract String doit(); +} + +class UnlinkedSub extends UnlinkedSuper { + String doit() { + return "heyhey"; + } +} + +class Foo {} +class NotFoo {} + +class Vehicle {} +class Car extends Vehicle {} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass.jasm new file mode 100644 index 00000000000..cf71d209819 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass.jasm @@ -0,0 +1,52 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadNewClass + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return an Object as a String. + * Verifier should fail. + */ +public Method doit:"()Ljava/lang/String;" + stack 2 locals 1 +{ + new class java/lang/Object; + dup; + invokespecial Method java/lang/Object."":"()V"; + astore_0; + aload_0; + areturn; // tries to return an Object as a String +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass2.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass2.jasm new file mode 100644 index 00000000000..c243d583484 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass2.jasm @@ -0,0 +1,52 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadNewClass2 + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return a NotFoo as a Foo. + * Verifier should fail. + */ +public Method doit:"()LFoo;" + stack 2 locals 1 +{ + new class NotFoo; + dup; + invokespecial Method NotFoo."":"()V"; + astore_0; + aload_0; + areturn; // tries to return a NotFoo as a Foo +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass3.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass3.jasm new file mode 100644 index 00000000000..afce8f76ed8 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass3.jasm @@ -0,0 +1,53 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadNewClass3 + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return a String[][] as an Integer[]. + * Verifier should fail. + * + * Note: the arrays must have different number of dimensions, or else + * the new verifier will just check the "bottom" classes. I.e., String and Integer + */ +public Method doit:"()[Ljava/lang/Integer;" + stack 2 locals 1 +{ + iconst_1; + iconst_1; + multianewarray class "[[Ljava/lang/String;", 2; + areturn; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass4.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass4.jasm new file mode 100644 index 00000000000..afebe3f1f8e --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadNewClass4.jasm @@ -0,0 +1,53 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadNewClass4 + version 52:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return a String[][] as an Integer[][]. + * Verifier should fail. + * + * Note: the new verifier looks up the Integer and String types, + * not the array types. + */ +public Method doit:"()[[Ljava/lang/Integer;" + stack 2 locals 1 +{ + iconst_1; + iconst_1; + multianewarray class "[[Ljava/lang/String;", 2; + areturn; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass.jasm new file mode 100644 index 00000000000..adc6a50d4ba --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass.jasm @@ -0,0 +1,52 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadOldClass + version 49:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return an Object as a String. + * Verifier should fail. + */ +public Method doit:"()Ljava/lang/String;" + stack 2 locals 1 +{ + new class java/lang/Object; + dup; + invokespecial Method java/lang/Object."":"()V"; + astore_0; + aload_0; + areturn; // tries to return an Object as a String +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass2.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass2.jasm new file mode 100644 index 00000000000..1808a019ace --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass2.jasm @@ -0,0 +1,52 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadOldClass2 + version 49:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return a NotFoo as a Foo. + * Verifier should fail. + */ +public Method doit:"()LFoo;" + stack 2 locals 1 +{ + new class NotFoo; + dup; + invokespecial Method NotFoo."":"()V"; + astore_0; + aload_0; + areturn; // tries to return a NotFoo as a Foo +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass3.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass3.jasm new file mode 100644 index 00000000000..6e943cf5afc --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass3.jasm @@ -0,0 +1,53 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadOldClass3 + version 49:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return a String[][] as an Integer[]. + * Verifier should fail. + * + * Note: the arrays have different number of dimensions. The old verifier + * rejects this immediately without looking up the String/Integer types. + */ +public Method doit:"()[Ljava/lang/Integer;" + stack 2 locals 1 +{ + iconst_1; + iconst_1; + multianewarray class "[[Ljava/lang/String;", 2; + areturn; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass4.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass4.jasm new file mode 100644 index 00000000000..56f2a8d299a --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BadOldClass4.jasm @@ -0,0 +1,53 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class BadOldClass4 + version 49:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + /* + * The following method tries to return a String[][] as an Integer[][]. + * Verifier should fail. + * + * Note: the old verifier looks up the Integer and String types, + * not the array types. + */ +public Method doit:"()[[Ljava/lang/Integer;" + stack 2 locals 1 +{ + iconst_1; + iconst_1; + multianewarray class "[[Ljava/lang/String;", 2; + areturn; +} + +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java index 0f7707edae3..e1f5f548593 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java @@ -147,7 +147,7 @@ public class BulkLoaderTest { @Override public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception { if (isAOTWorkflow() && runMode == RunMode.TRAINING) { - out.shouldContain("Skipping BadOldClassA: Unlinked class not supported by AOTConfiguration"); + out.shouldContain("Skipping BadOldClassA: Failed verification"); out.shouldContain("Skipping SimpleCusty: Duplicated unregistered class"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GoodOldClass.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GoodOldClass.jasm new file mode 100644 index 00000000000..92a79380d93 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GoodOldClass.jasm @@ -0,0 +1,49 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +super public class GoodOldClass + version 49:0 +{ + +public Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + + +public static Method doit:"()LVehicle;" + stack 2 locals 1 +{ + new class Car; + dup; + invokespecial Method Car."":"()V"; + astore_0; + aload_0; + areturn; // tries to return a Car as a Vehicle +} + +} From 85996572b61e789d7e45bd26b23d233a0a41e158 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Wed, 10 Sep 2025 21:23:45 +0000 Subject: [PATCH 031/120] 8365676: javac incorrectly allows calling interface static method via type variable Co-authored-by: Maurizio Cimadamore Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Attr.java | 16 ++++++++++++--- .../generics/typevars/8365676/T8365676.java | 20 +++++++++++++++++++ .../generics/typevars/8365676/T8365676.out | 4 ++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/langtools/tools/javac/generics/typevars/8365676/T8365676.java create mode 100644 test/langtools/tools/javac/generics/typevars/8365676/T8365676.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 9f32e7f6186..f780df025bd 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -4569,9 +4569,19 @@ public class Attr extends JCTree.Visitor { log.error(pos, Errors.TypeVarCantBeDeref); return syms.errSymbol; } else { - Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ? - rs.new AccessError(env, site, sym) : - sym; + // JLS 4.9 specifies the members are derived by inheritance. + // We skip inducing a whole class by filtering members that + // can never be inherited: + Symbol sym2; + if (sym.isPrivate()) { + // Private members + sym2 = rs.new AccessError(env, site, sym); + } else if (sym.owner.isInterface() && sym.kind == MTH && (sym.flags() & STATIC) != 0) { + // Interface static methods + sym2 = rs.new SymbolNotFoundError(ABSENT_MTH); + } else { + sym2 = sym; + } rs.accessBase(sym2, pos, location, site, name, true); return sym; } diff --git a/test/langtools/tools/javac/generics/typevars/8365676/T8365676.java b/test/langtools/tools/javac/generics/typevars/8365676/T8365676.java new file mode 100644 index 00000000000..f6b992cb47b --- /dev/null +++ b/test/langtools/tools/javac/generics/typevars/8365676/T8365676.java @@ -0,0 +1,20 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8365676 + * @summary Interface static methods should not be inherited by type variables + * @compile/fail/ref=T8365676.out -XDrawDiagnostics T8365676.java + */ + +import java.text.Collator; +import java.util.Comparator; + +class T8365676 { + // T and P should have equivalent members + , P extends Object & Comparator> + void test() { + Comparator.reverseOrder(); + Collator.reverseOrder(); // Fails + P.reverseOrder(); // Fails + T.reverseOrder(); // Should fail + } +} diff --git a/test/langtools/tools/javac/generics/typevars/8365676/T8365676.out b/test/langtools/tools/javac/generics/typevars/8365676/T8365676.out new file mode 100644 index 00000000000..214b1640d4a --- /dev/null +++ b/test/langtools/tools/javac/generics/typevars/8365676/T8365676.out @@ -0,0 +1,4 @@ +T8365676.java:16:17: compiler.err.cant.resolve.location.args: kindname.method, reverseOrder, , , (compiler.misc.location: kindname.class, java.text.Collator, null) +T8365676.java:17:10: compiler.err.cant.resolve.location.args: kindname.method, reverseOrder, , , (compiler.misc.location: kindname.type.variable.bound, java.lang.Object&java.util.Comparator, null) +T8365676.java:18:10: compiler.err.cant.resolve.location.args: kindname.method, reverseOrder, , , (compiler.misc.location: kindname.type.variable.bound, T, null) +3 errors From 7fcce27096605a27ca3b74349d1012bb0bd5963d Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 10 Sep 2025 22:12:04 +0000 Subject: [PATCH 032/120] 8365956: GenShen: Adaptive tenuring threshold algorithm may raise threshold prematurely Reviewed-by: kdnilsen, phh --- .../shenandoahGenerationalHeuristics.cpp | 16 +- .../heuristics/shenandoahGlobalHeuristics.cpp | 7 +- .../heuristics/shenandoahYoungHeuristics.cpp | 34 ++-- .../gc/shenandoah/shenandoahAgeCensus.cpp | 96 +++++++---- .../gc/shenandoah/shenandoahAgeCensus.hpp | 30 +++- .../gc/shenandoah/shenandoahCollectionSet.cpp | 3 +- .../gc/shenandoah/shenandoahGeneration.cpp | 8 +- .../shenandoahGenerationalEvacuationTask.cpp | 12 +- .../shenandoahGenerationalEvacuationTask.hpp | 1 - .../shenandoahGenerationalFullGC.cpp | 5 +- .../shenandoahGenerationalFullGC.hpp | 1 - .../shenandoah/shenandoahGenerationalHeap.cpp | 2 +- .../shenandoah/shenandoahGenerationalHeap.hpp | 1 + .../shenandoahGenerationalHeap.inline.hpp | 37 ++++ .../shenandoah/test_shenandoahAgeCensus.cpp | 159 ++++++++++++++++++ 15 files changed, 318 insertions(+), 94 deletions(-) create mode 100644 src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.inline.hpp create mode 100644 test/hotspot/gtest/gc/shenandoah/test_shenandoahAgeCensus.cpp diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp index 08fd4599346..dfae9040242 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp @@ -28,7 +28,7 @@ #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahEvacInfo.hpp" #include "gc/shenandoah/shenandoahGeneration.hpp" -#include "gc/shenandoah/shenandoahGenerationalHeap.hpp" +#include "gc/shenandoah/shenandoahGenerationalHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" #include "gc/shenandoah/shenandoahTrace.hpp" @@ -65,8 +65,6 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio size_t free = 0; size_t free_regions = 0; - const uint tenuring_threshold = heap->age_census()->tenuring_threshold(); - // This counts number of humongous regions that we intend to promote in this cycle. size_t humongous_regions_promoted = 0; // This counts number of regular regions that will be promoted in place. @@ -98,12 +96,12 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio bool is_candidate; // This is our candidate for later consideration. if (collection_set->is_preselected(i)) { - assert(region->age() >= tenuring_threshold, "Preselection filter"); + assert(heap->is_tenurable(region), "Preselection filter"); is_candidate = true; preselected_candidates++; // Set garbage value to maximum value to force this into the sorted collection set. garbage = region_size_bytes; - } else if (region->is_young() && (region->age() >= tenuring_threshold)) { + } else if (region->is_young() && heap->is_tenurable(region)) { // Note that for GLOBAL GC, region may be OLD, and OLD regions do not qualify for pre-selection // This region is old enough to be promoted but it was not preselected, either because its garbage is below @@ -142,7 +140,7 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio immediate_regions++; immediate_garbage += garbage; } else { - if (region->is_young() && region->age() >= tenuring_threshold) { + if (region->is_young() && heap->is_tenurable(region)) { oop obj = cast_to_oop(region->bottom()); size_t humongous_regions = ShenandoahHeapRegion::required_regions(obj->size() * HeapWordSize); humongous_regions_promoted += humongous_regions; @@ -246,10 +244,6 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio size_t ShenandoahGenerationalHeuristics::add_preselected_regions_to_collection_set(ShenandoahCollectionSet* cset, const RegionData* data, size_t size) const { -#ifdef ASSERT - const uint tenuring_threshold = ShenandoahGenerationalHeap::heap()->age_census()->tenuring_threshold(); -#endif - // cur_young_garbage represents the amount of memory to be reclaimed from young-gen. In the case that live objects // are known to be promoted out of young-gen, we count this as cur_young_garbage because this memory is reclaimed // from young-gen and becomes available to serve future young-gen allocation requests. @@ -257,7 +251,7 @@ size_t ShenandoahGenerationalHeuristics::add_preselected_regions_to_collection_s for (size_t idx = 0; idx < size; idx++) { ShenandoahHeapRegion* r = data[idx].get_region(); if (cset->is_preselected(r->index())) { - assert(r->age() >= tenuring_threshold, "Preselected regions must have tenure age"); + assert(ShenandoahGenerationalHeap::heap()->is_tenurable(r), "Preselected regions must have tenure age"); // Entire region will be promoted, This region does not impact young-gen or old-gen evacuation reserve. // This region has been pre-selected and its impact on promotion reserve is already accounted for. diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp index 4e12b1d41e8..331bd040575 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp @@ -25,7 +25,7 @@ #include "gc/shenandoah/heuristics/shenandoahGlobalHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" -#include "gc/shenandoah/shenandoahGenerationalHeap.hpp" +#include "gc/shenandoah/shenandoahGenerationalHeap.inline.hpp" #include "gc/shenandoah/shenandoahGlobalGeneration.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "utilities/quickSort.hpp" @@ -56,7 +56,6 @@ void ShenandoahGlobalHeuristics::choose_global_collection_set(ShenandoahCollecti size_t capacity = heap->soft_max_capacity(); size_t garbage_threshold = region_size_bytes * ShenandoahGarbageThreshold / 100; size_t ignore_threshold = region_size_bytes * ShenandoahIgnoreGarbageThreshold / 100; - const uint tenuring_threshold = heap->age_census()->tenuring_threshold(); size_t young_evac_reserve = heap->young_generation()->get_evacuation_reserve(); size_t old_evac_reserve = heap->old_generation()->get_evacuation_reserve(); @@ -100,7 +99,7 @@ void ShenandoahGlobalHeuristics::choose_global_collection_set(ShenandoahCollecti ShenandoahHeapRegion* r = data[idx].get_region(); assert(!cset->is_preselected(r->index()), "There should be no preselected regions during GLOBAL GC"); bool add_region = false; - if (r->is_old() || (r->age() >= tenuring_threshold)) { + if (r->is_old() || heap->is_tenurable(r)) { size_t new_cset = old_cur_cset + r->get_live_data_bytes(); if ((r->garbage() > garbage_threshold)) { while ((new_cset > max_old_cset) && (unaffiliated_young_regions > 0)) { @@ -114,7 +113,7 @@ void ShenandoahGlobalHeuristics::choose_global_collection_set(ShenandoahCollecti old_cur_cset = new_cset; } } else { - assert(r->is_young() && (r->age() < tenuring_threshold), "DeMorgan's law (assuming r->is_affiliated)"); + assert(r->is_young() && !heap->is_tenurable(r), "DeMorgan's law (assuming r->is_affiliated)"); size_t new_cset = young_cur_cset + r->get_live_data_bytes(); size_t region_garbage = r->garbage(); size_t new_garbage = cur_young_garbage + region_garbage; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp index fbb165858dc..d236be8c9e6 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp @@ -26,7 +26,7 @@ #include "gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahYoungHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" -#include "gc/shenandoah/shenandoahGenerationalHeap.hpp" +#include "gc/shenandoah/shenandoahGenerationalHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" #include "gc/shenandoah/shenandoahYoungGeneration.hpp" @@ -64,19 +64,18 @@ void ShenandoahYoungHeuristics::choose_young_collection_set(ShenandoahCollection size_t size, size_t actual_free, size_t cur_young_garbage) const { - auto heap = ShenandoahGenerationalHeap::heap(); + const auto heap = ShenandoahGenerationalHeap::heap(); - size_t capacity = heap->soft_max_capacity(); - size_t garbage_threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100; - size_t ignore_threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahIgnoreGarbageThreshold / 100; - const uint tenuring_threshold = heap->age_census()->tenuring_threshold(); + const size_t capacity = heap->soft_max_capacity(); + const size_t garbage_threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100; + const size_t ignore_threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahIgnoreGarbageThreshold / 100; // This is young-gen collection or a mixed evacuation. // If this is mixed evacuation, the old-gen candidate regions have already been added. - size_t max_cset = (size_t) (heap->young_generation()->get_evacuation_reserve() / ShenandoahEvacWaste); size_t cur_cset = 0; - size_t free_target = (capacity * ShenandoahMinFreeThreshold) / 100 + max_cset; - size_t min_garbage = (free_target > actual_free) ? (free_target - actual_free) : 0; + const size_t max_cset = (size_t) (heap->young_generation()->get_evacuation_reserve() / ShenandoahEvacWaste); + const size_t free_target = (capacity * ShenandoahMinFreeThreshold) / 100 + max_cset; + const size_t min_garbage = (free_target > actual_free) ? (free_target - actual_free) : 0; log_info(gc, ergo)( @@ -89,11 +88,15 @@ void ShenandoahYoungHeuristics::choose_young_collection_set(ShenandoahCollection if (cset->is_preselected(r->index())) { continue; } - if (r->age() < tenuring_threshold) { - size_t new_cset = cur_cset + r->get_live_data_bytes(); - size_t region_garbage = r->garbage(); - size_t new_garbage = cur_young_garbage + region_garbage; - bool add_regardless = (region_garbage > ignore_threshold) && (new_garbage < min_garbage); + + // Note that we do not add tenurable regions if they were not pre-selected. They were not preselected + // because there is insufficient room in old-gen to hold their to-be-promoted live objects or because + // they are to be promoted in place. + if (!heap->is_tenurable(r)) { + const size_t new_cset = cur_cset + r->get_live_data_bytes(); + const size_t region_garbage = r->garbage(); + const size_t new_garbage = cur_young_garbage + region_garbage; + const bool add_regardless = (region_garbage > ignore_threshold) && (new_garbage < min_garbage); assert(r->is_young(), "Only young candidates expected in the data array"); if ((new_cset <= max_cset) && (add_regardless || (region_garbage > garbage_threshold))) { cur_cset = new_cset; @@ -101,9 +104,6 @@ void ShenandoahYoungHeuristics::choose_young_collection_set(ShenandoahCollection cset->add_region(r); } } - // Note that we do not add aged regions if they were not pre-selected. The reason they were not preselected - // is because there is not sufficient room in old-gen to hold their to-be-promoted live objects or because - // they are to be promoted in place. } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp index 94c98b78f1b..bd66f55bd8f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp @@ -27,8 +27,15 @@ #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" -ShenandoahAgeCensus::ShenandoahAgeCensus() { +ShenandoahAgeCensus::ShenandoahAgeCensus() + : ShenandoahAgeCensus(ShenandoahHeap::heap()->max_workers()) +{ assert(ShenandoahHeap::heap()->mode()->is_generational(), "Only in generational mode"); +} + +ShenandoahAgeCensus::ShenandoahAgeCensus(uint max_workers) + : _max_workers(max_workers) +{ if (ShenandoahGenerationalMinTenuringAge > ShenandoahGenerationalMaxTenuringAge) { vm_exit_during_initialization( err_msg("ShenandoahGenerationalMinTenuringAge=%zu" @@ -39,6 +46,9 @@ ShenandoahAgeCensus::ShenandoahAgeCensus() { _global_age_table = NEW_C_HEAP_ARRAY(AgeTable*, MAX_SNAPSHOTS, mtGC); CENSUS_NOISE(_global_noise = NEW_C_HEAP_ARRAY(ShenandoahNoiseStats, MAX_SNAPSHOTS, mtGC);) _tenuring_threshold = NEW_C_HEAP_ARRAY(uint, MAX_SNAPSHOTS, mtGC); + CENSUS_NOISE(_skipped = 0); + NOT_PRODUCT(_counted = 0); + NOT_PRODUCT(_total = 0); for (int i = 0; i < MAX_SNAPSHOTS; i++) { // Note that we don't now get perfdata from age_table @@ -48,10 +58,9 @@ ShenandoahAgeCensus::ShenandoahAgeCensus() { _tenuring_threshold[i] = MAX_COHORTS; } if (ShenandoahGenerationalAdaptiveTenuring && !ShenandoahGenerationalCensusAtEvac) { - size_t max_workers = ShenandoahHeap::heap()->max_workers(); - _local_age_table = NEW_C_HEAP_ARRAY(AgeTable*, max_workers, mtGC); + _local_age_table = NEW_C_HEAP_ARRAY(AgeTable*, _max_workers, mtGC); CENSUS_NOISE(_local_noise = NEW_C_HEAP_ARRAY(ShenandoahNoiseStats, max_workers, mtGC);) - for (uint i = 0; i < max_workers; i++) { + for (uint i = 0; i < _max_workers; i++) { _local_age_table[i] = new AgeTable(false); CENSUS_NOISE(_local_noise[i].clear();) } @@ -61,6 +70,22 @@ ShenandoahAgeCensus::ShenandoahAgeCensus() { _epoch = MAX_SNAPSHOTS - 1; // see update_epoch() } +ShenandoahAgeCensus::~ShenandoahAgeCensus() { + for (uint i = 0; i < MAX_SNAPSHOTS; i++) { + delete _global_age_table[i]; + } + FREE_C_HEAP_ARRAY(AgeTable*, _global_age_table); + FREE_C_HEAP_ARRAY(uint, _tenuring_threshold); + CENSUS_NOISE(FREE_C_HEAP_ARRAY(ShenandoahNoiseStats, _global_noise)); + if (_local_age_table) { + for (uint i = 0; i < _max_workers; i++) { + delete _local_age_table[i]; + } + FREE_C_HEAP_ARRAY(AgeTable*, _local_age_table); + CENSUS_NOISE(FREE_C_HEAP_ARRAY(ShenandoahNoiseStats, _local_noise)); + } +} + CENSUS_NOISE(void ShenandoahAgeCensus::add(uint obj_age, uint region_age, uint region_youth, size_t size, uint worker_id) {) NO_CENSUS_NOISE(void ShenandoahAgeCensus::add(uint obj_age, uint region_age, size_t size, uint worker_id) {) if (obj_age <= markWord::max_age) { @@ -131,12 +156,11 @@ void ShenandoahAgeCensus::update_census(size_t age0_pop, AgeTable* pv1, AgeTable assert(pv1 == nullptr && pv2 == nullptr, "Error, check caller"); // Seed cohort 0 with population that may have been missed during // regular census. - _global_age_table[_epoch]->add((uint)0, age0_pop); + _global_age_table[_epoch]->add(0u, age0_pop); - size_t max_workers = ShenandoahHeap::heap()->max_workers(); // Merge data from local age tables into the global age table for the epoch, // clearing the local tables. - for (uint i = 0; i < max_workers; i++) { + for (uint i = 0; i < _max_workers; i++) { // age stats _global_age_table[_epoch]->merge(_local_age_table[i]); _local_age_table[i]->clear(); // clear for next census @@ -177,8 +201,7 @@ void ShenandoahAgeCensus::reset_local() { assert(_local_age_table == nullptr, "Error"); return; } - size_t max_workers = ShenandoahHeap::heap()->max_workers(); - for (uint i = 0; i < max_workers; i++) { + for (uint i = 0; i < _max_workers; i++) { _local_age_table[i]->clear(); CENSUS_NOISE(_local_noise[i].clear();) } @@ -204,8 +227,7 @@ bool ShenandoahAgeCensus::is_clear_local() { assert(_local_age_table == nullptr, "Error"); return true; } - size_t max_workers = ShenandoahHeap::heap()->max_workers(); - for (uint i = 0; i < max_workers; i++) { + for (uint i = 0; i < _max_workers; i++) { bool clear = _local_age_table[i]->is_clear(); CENSUS_NOISE(clear |= _local_noise[i].is_clear();) if (!clear) { @@ -246,7 +268,7 @@ void ShenandoahAgeCensus::update_tenuring_threshold() { _tenuring_threshold[_epoch] = tt; } print(); - log_trace(gc, age)("New tenuring threshold %zu (min %zu, max %zu)", + log_info(gc, age)("New tenuring threshold %zu (min %zu, max %zu)", (uintx) _tenuring_threshold[_epoch], ShenandoahGenerationalMinTenuringAge, ShenandoahGenerationalMaxTenuringAge); } @@ -279,13 +301,14 @@ uint ShenandoahAgeCensus::compute_tenuring_threshold() { uint upper_bound = ShenandoahGenerationalMaxTenuringAge; const uint prev_tt = previous_tenuring_threshold(); if (ShenandoahGenerationalCensusIgnoreOlderCohorts && prev_tt > 0) { - // We stay below the computed tenuring threshold for the last cycle plus 1, - // ignoring the mortality rates of any older cohorts. - upper_bound = MIN2(upper_bound, prev_tt + 1); + // We stay below the computed tenuring threshold for the last cycle, + // ignoring the mortality rates of any older cohorts (which may see + // higher mortality rates due to promotions). + upper_bound = MIN2(upper_bound, prev_tt); } upper_bound = MIN2(upper_bound, markWord::max_age); - const uint lower_bound = MAX2((uint)ShenandoahGenerationalMinTenuringAge, (uint)1); + const uint lower_bound = MAX2((uint)ShenandoahGenerationalMinTenuringAge, 1u); uint tenuring_threshold = upper_bound; for (uint i = upper_bound; i >= lower_bound; i--) { @@ -303,9 +326,9 @@ uint ShenandoahAgeCensus::compute_tenuring_threshold() { // cohorts are considered eligible for tenuring when all older // cohorts are. We return the next higher age as the tenuring threshold // so that we do not prematurely promote objects of this age. - assert(tenuring_threshold == i+1 || tenuring_threshold == upper_bound, "Error"); + assert(tenuring_threshold == i + 1 || tenuring_threshold == upper_bound, "Error"); assert(tenuring_threshold >= lower_bound && tenuring_threshold <= upper_bound, "Error"); - return tenuring_threshold; + return i + 1; } // Remember that we passed over this cohort, looking for younger cohorts // showing high mortality. We want to tenure cohorts of this age. @@ -335,6 +358,14 @@ double ShenandoahAgeCensus::mortality_rate(size_t prev_pop, size_t cur_pop) { } void ShenandoahAgeCensus::print() { + + const LogTarget(Debug, gc, age) lt; + if (!lt.is_enabled()) { + return; + } + + LogStream ls(lt); + // Print the population vector for the current epoch, and // for the previous epoch, as well as the computed mortality // ratio for each extant cohort. @@ -350,33 +381,32 @@ void ShenandoahAgeCensus::print() { for (uint i = 1; i < MAX_COHORTS; i++) { const size_t prev_pop = prev_pv->sizes[i-1]; // (i-1) OK because i >= 1 const size_t cur_pop = cur_pv->sizes[i]; - double mr = mortality_rate(prev_pop, cur_pop); + const double mr = mortality_rate(prev_pop, cur_pop); // Suppress printing when everything is zero if (prev_pop + cur_pop > 0) { - log_info(gc, age) - (" - age %3u: prev %10zu bytes, curr %10zu bytes, mortality %.2f ", - i, prev_pop*oopSize, cur_pop*oopSize, mr); + ls.print_cr(" - age %3u: prev %10zu bytes, curr %10zu bytes, mortality %.2f ", + i, prev_pop * oopSize, cur_pop * oopSize, mr); } total += cur_pop; if (i == tt) { // Underline the cohort for tenuring threshold (if < MAX_COHORTS) - log_info(gc, age)("----------------------------------------------------------------------------"); + ls.print_cr("----------------------------------------------------------------------------"); } } - CENSUS_NOISE(_global_noise[cur_epoch].print(total);) + CENSUS_NOISE(_global_noise[cur_epoch].print(ls, total);) } #ifdef SHENANDOAH_CENSUS_NOISE -void ShenandoahNoiseStats::print(size_t total) { +void ShenandoahNoiseStats::print(LogStream& ls, const size_t total) { if (total > 0) { - float f_skipped = (float)skipped/(float)total; - float f_aged = (float)aged/(float)total; - float f_clamped = (float)clamped/(float)total; - float f_young = (float)young/(float)total; - log_info(gc, age)("Skipped: %10zu (%.2f), R-Aged: %10zu (%.2f), " - "Clamped: %10zu (%.2f), R-Young: %10zu (%.2f)", - skipped*oopSize, f_skipped, aged*oopSize, f_aged, - clamped*oopSize, f_clamped, young*oopSize, f_young); + const float f_skipped = (float)skipped/(float)total; + const float f_aged = (float)aged/(float)total; + const float f_clamped = (float)clamped/(float)total; + const float f_young = (float)young/(float)total; + ls.print_cr("Skipped: %10zu (%.2f), R-Aged: %10zu (%.2f), " + "Clamped: %10zu (%.2f), R-Young: %10zu (%.2f)", + skipped*oopSize, f_skipped, aged*oopSize, f_aged, + clamped*oopSize, f_clamped, young*oopSize, f_young); } } #endif // SHENANDOAH_CENSUS_NOISE diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp index 89c68f7120b..90d188e1fca 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp @@ -37,6 +37,8 @@ #define CENSUS_NOISE(x) x #define NO_CENSUS_NOISE(x) +class LogStream; + struct ShenandoahNoiseStats { size_t skipped; // Volume of objects skipped size_t aged; // Volume of objects from aged regions @@ -67,7 +69,7 @@ struct ShenandoahNoiseStats { young += other.young; } - void print(size_t total); + void print(LogStream& ls, size_t total); }; #else // SHENANDOAH_CENSUS_NOISE #define CENSUS_NOISE(x) @@ -91,7 +93,7 @@ struct ShenandoahNoiseStats { // // In addition, this class also maintains per worker population vectors into which // census for the current minor GC is accumulated (during marking or, optionally, during -// evacuation). These are cleared after each marking (resectively, evacuation) cycle, +// evacuation). These are cleared after each marking (respectively, evacuation) cycle, // once the per-worker data is consolidated into the appropriate population vector // per minor collection. The _local_age_table is thus C x N, for N GC workers. class ShenandoahAgeCensus: public CHeapObj { @@ -111,10 +113,12 @@ class ShenandoahAgeCensus: public CHeapObj { size_t _total; // net size of objects encountered (counted or skipped) in census #endif - uint _epoch; // Current epoch (modulo max age) - uint *_tenuring_threshold; // An array of the last N tenuring threshold values we + uint _epoch; // Current epoch (modulo max age) + uint* _tenuring_threshold; // An array of the last N tenuring threshold values we // computed. + uint _max_workers; // Maximum number of workers for parallel tasks + // Mortality rate of a cohort, given its population in // previous and current epochs double mortality_rate(size_t prev_pop, size_t cur_pop); @@ -165,11 +169,22 @@ class ShenandoahAgeCensus: public CHeapObj { }; ShenandoahAgeCensus(); + ShenandoahAgeCensus(uint max_workers); + ~ShenandoahAgeCensus(); // Return the local age table (population vector) for worker_id. // Only used in the case of (ShenandoahGenerationalAdaptiveTenuring && !ShenandoahGenerationalCensusAtEvac) - AgeTable* get_local_age_table(uint worker_id) { - return (AgeTable*) _local_age_table[worker_id]; + AgeTable* get_local_age_table(uint worker_id) const { + return _local_age_table[worker_id]; + } + + // Return the most recently computed tenuring threshold. + // Visible for testing. Use is_tenurable for consistent tenuring comparisons. + uint tenuring_threshold() const { return _tenuring_threshold[_epoch]; } + + // Return true if this age is at or above the tenuring threshold. + bool is_tenurable(uint age) const { + return age >= tenuring_threshold(); } // Update the local age table for worker_id by size for @@ -201,9 +216,6 @@ class ShenandoahAgeCensus: public CHeapObj { // is 0, because the evacuated objects have all had their ages incremented. void update_census(size_t age0_pop, AgeTable* pv1 = nullptr, AgeTable* pv2 = nullptr); - // Return the most recently computed tenuring threshold - uint tenuring_threshold() const { return _tenuring_threshold[_epoch]; } - // Reset the epoch, clearing accumulated census history // Note: this isn't currently used, but reserved for planned // future usage. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp index 25b900f8d77..35faa40af77 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp @@ -27,6 +27,7 @@ #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" +#include "gc/shenandoah/shenandoahGenerationalHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" @@ -98,7 +99,7 @@ void ShenandoahCollectionSet::add_region(ShenandoahHeapRegion* r) { if (r->is_young()) { _young_bytes_to_evacuate += live; _young_available_bytes_collected += free; - if (ShenandoahHeap::heap()->mode()->is_generational() && r->age() >= ShenandoahGenerationalHeap::heap()->age_census()->tenuring_threshold()) { + if (ShenandoahHeap::heap()->mode()->is_generational() && ShenandoahGenerationalHeap::heap()->is_tenurable(r)) { _young_bytes_to_promote += live; } } else if (r->is_old()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp index f686334d3d5..7b3839dc198 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp @@ -28,9 +28,8 @@ #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahGeneration.hpp" -#include "gc/shenandoah/shenandoahGenerationalHeap.hpp" +#include "gc/shenandoah/shenandoahGenerationalHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionClosures.hpp" -#include "gc/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" #include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahScanRemembered.inline.hpp" @@ -534,7 +533,6 @@ size_t ShenandoahGeneration::select_aged_regions(size_t old_available) { bool* const candidate_regions_for_promotion_by_copy = heap->collection_set()->preselected_regions(); ShenandoahMarkingContext* const ctx = heap->marking_context(); - const uint tenuring_threshold = heap->age_census()->tenuring_threshold(); const size_t old_garbage_threshold = (ShenandoahHeapRegion::region_size_bytes() * ShenandoahOldGarbageThreshold) / 100; size_t old_consumed = 0; @@ -558,7 +556,7 @@ size_t ShenandoahGeneration::select_aged_regions(size_t old_available) { // skip over regions that aren't regular young with some live data continue; } - if (r->age() >= tenuring_threshold) { + if (heap->is_tenurable(r)) { if ((r->garbage() < old_garbage_threshold)) { // This tenure-worthy region has too little garbage, so we do not want to expend the copying effort to // reclaim the garbage; instead this region may be eligible for promotion-in-place to the @@ -613,7 +611,7 @@ size_t ShenandoahGeneration::select_aged_regions(size_t old_available) { // these regions. The likely outcome is that these regions will not be selected for evacuation or promotion // in the current cycle and we will anticipate that they will be promoted in the next cycle. This will cause // us to reserve more old-gen memory so that these objects can be promoted in the subsequent cycle. - if (heap->is_aging_cycle() && (r->age() + 1 == tenuring_threshold)) { + if (heap->is_aging_cycle() && heap->age_census()->is_tenurable(r->age() + 1)) { if (r->garbage() >= old_garbage_threshold) { promo_potential += r->get_live_data_bytes(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp index 29fd3258b6c..3a0d7926865 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp @@ -26,7 +26,7 @@ #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp" -#include "gc/shenandoah/shenandoahGenerationalHeap.hpp" +#include "gc/shenandoah/shenandoahGenerationalHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" #include "gc/shenandoah/shenandoahScanRemembered.inline.hpp" @@ -56,11 +56,9 @@ ShenandoahGenerationalEvacuationTask::ShenandoahGenerationalEvacuationTask(Shena _heap(heap), _regions(iterator), _concurrent(concurrent), - _only_promote_regions(only_promote_regions), - _tenuring_threshold(0) + _only_promote_regions(only_promote_regions) { shenandoah_assert_generational(); - _tenuring_threshold = _heap->age_census()->tenuring_threshold(); } void ShenandoahGenerationalEvacuationTask::work(uint worker_id) { @@ -138,7 +136,7 @@ void ShenandoahGenerationalEvacuationTask::evacuate_and_promote_regions() { void ShenandoahGenerationalEvacuationTask::maybe_promote_region(ShenandoahHeapRegion* r) { - if (r->is_young() && r->is_active() && (r->age() >= _tenuring_threshold)) { + if (r->is_young() && r->is_active() && _heap->is_tenurable(r)) { if (r->is_humongous_start()) { // We promote humongous_start regions along with their affiliated continuations during evacuation rather than // doing this work during a safepoint. We cannot put humongous regions into the collection set because that @@ -176,7 +174,7 @@ void ShenandoahGenerationalEvacuationTask::promote_in_place(ShenandoahHeapRegion assert(region->garbage_before_padded_for_promote() < old_garbage_threshold, "Region %zu has too much garbage for promotion", region->index()); assert(region->is_young(), "Only young regions can be promoted"); assert(region->is_regular(), "Use different service to promote humongous regions"); - assert(region->age() >= _tenuring_threshold, "Only promote regions that are sufficiently aged"); + assert(_heap->is_tenurable(region), "Only promote regions that are sufficiently aged"); assert(region->get_top_before_promote() == tams, "Region %zu has been used for allocations before promotion", region->index()); } @@ -259,7 +257,7 @@ void ShenandoahGenerationalEvacuationTask::promote_humongous(ShenandoahHeapRegio shenandoah_assert_generations_reconciled(); assert(region->is_young(), "Only young regions can be promoted"); assert(region->is_humongous_start(), "Should not promote humongous continuation in isolation"); - assert(region->age() >= _tenuring_threshold, "Only promote regions that are sufficiently aged"); + assert(_heap->is_tenurable(region), "Only promote regions that are sufficiently aged"); assert(marking_context->is_marked(obj), "promoted humongous object should be alive"); const size_t used_bytes = obj->size() * HeapWordSize; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp index abe2fc0110c..0c402d6c90a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp @@ -39,7 +39,6 @@ private: ShenandoahRegionIterator* _regions; bool _concurrent; bool _only_promote_regions; - uint _tenuring_threshold; public: ShenandoahGenerationalEvacuationTask(ShenandoahGenerationalHeap* sh, diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp index e2e3f0a4677..c4a7408e032 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp @@ -193,7 +193,6 @@ ShenandoahPrepareForGenerationalCompactionObjectClosure::ShenandoahPrepareForGen ShenandoahHeapRegion* from_region, uint worker_id) : _preserved_marks(preserved_marks), _heap(ShenandoahGenerationalHeap::heap()), - _tenuring_threshold(0), _empty_regions(empty_regions), _empty_regions_pos(0), _old_to_region(nullptr), @@ -212,8 +211,6 @@ ShenandoahPrepareForGenerationalCompactionObjectClosure::ShenandoahPrepareForGen _young_to_region = from_region; _young_compact_point = from_region->bottom(); } - - _tenuring_threshold = _heap->age_census()->tenuring_threshold(); } void ShenandoahPrepareForGenerationalCompactionObjectClosure::set_from_region(ShenandoahHeapRegion* from_region) { @@ -279,7 +276,7 @@ void ShenandoahPrepareForGenerationalCompactionObjectClosure::do_object(oop p) { bool promote_object = false; if ((_from_affiliation == ShenandoahAffiliation::YOUNG_GENERATION) && - (from_region_age + object_age >= _tenuring_threshold)) { + _heap->age_census()->is_tenurable(from_region_age + object_age)) { if ((_old_to_region != nullptr) && (_old_compact_point + obj_size > _old_to_region->end())) { finish_old_region(); _old_to_region = nullptr; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.hpp index 9240a056105..06080286f22 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.hpp @@ -90,7 +90,6 @@ class ShenandoahPrepareForGenerationalCompactionObjectClosure : public ObjectClo private: PreservedMarks* const _preserved_marks; ShenandoahGenerationalHeap* const _heap; - uint _tenuring_threshold; // _empty_regions is a thread-local list of heap regions that have been completely emptied by this worker thread's // compaction efforts. The worker thread that drives these efforts adds compacted regions to this list if the diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp index d05ae713645..0aca8f971e3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp @@ -216,7 +216,7 @@ oop ShenandoahGenerationalHeap::evacuate_object(oop p, Thread* thread) { if (mark.has_displaced_mark_helper()) { // We don't want to deal with MT here just to ensure we read the right mark word. // Skip the potential promotion attempt for this one. - } else if (r->age() + mark.age() >= age_census()->tenuring_threshold()) { + } else if (age_census()->is_tenurable(r->age() + mark.age())) { oop result = try_evacuate_object(p, thread, r, OLD_GENERATION); if (result != nullptr) { return result; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.hpp index f23e49735e9..6960562b31d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.hpp @@ -80,6 +80,7 @@ public: return _age_census; } + inline bool is_tenurable(const ShenandoahHeapRegion* r) const; // Ages regions that haven't been used for allocations in the current cycle. // Resets ages for regions that have been used for allocations. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.inline.hpp new file mode 100644 index 00000000000..8289b48185b --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.inline.hpp @@ -0,0 +1,37 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONALHEAP_INLINE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONALHEAP_INLINE_HPP + +#include "gc/shenandoah/shenandoahGenerationalHeap.hpp" + +#include "gc/shenandoah/shenandoahAgeCensus.hpp" +#include "gc/shenandoah/shenandoahHeapRegion.hpp" + +inline bool ShenandoahGenerationalHeap::is_tenurable(const ShenandoahHeapRegion* r) const { + return _age_census->is_tenurable(r->age()); +} + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONALHEAP_INLINE_HPP diff --git a/test/hotspot/gtest/gc/shenandoah/test_shenandoahAgeCensus.cpp b/test/hotspot/gtest/gc/shenandoah/test_shenandoahAgeCensus.cpp new file mode 100644 index 00000000000..c53d0a15554 --- /dev/null +++ b/test/hotspot/gtest/gc/shenandoah/test_shenandoahAgeCensus.cpp @@ -0,0 +1,159 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "gc/shenandoah/shenandoahAgeCensus.hpp" +#include "unittest.hpp" + +class ShenandoahAgeCensusTest : public ::testing::Test { +protected: + static constexpr size_t MinimumPopulationSize = 4*K; + static constexpr size_t InitialPopulationSize = MinimumPopulationSize * 1000; + + size_t _cohorts_count = ShenandoahAgeCensus::MAX_COHORTS; + double _mortality_rates[ShenandoahAgeCensus::MAX_COHORTS]; + size_t _cohort_populations[ShenandoahAgeCensus::MAX_COHORTS]; + + ShenandoahAgeCensusTest() + : _mortality_rates{0.9, 0.7, 0.5, 0.3, 0.09, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} + { + build_cohort_populations(_mortality_rates, _cohort_populations, _cohorts_count); + } + + static void add_population(ShenandoahAgeCensus& census, const uint age, const size_t population_words) { + CENSUS_NOISE(census.add(age, 0, 0, population_words, 0)); + NO_CENSUS_NOISE(census.add(age, 0, population_words, 0)); + } + + void update(ShenandoahAgeCensus& census, size_t cohorts) const { + for (uint i = 1; i < cohorts; i++) { + add_population(census, i, _cohort_populations[i]); + } + census.update_census(_cohort_populations[0]); + } + + void update(ShenandoahAgeCensus& census) const { + update(census, _cohorts_count); + } + + size_t get_total_population_older_than(const size_t min_cohort_age) const { + size_t total = 0; + for (size_t i = 0; i < _cohorts_count; i++) { + if (i >= min_cohort_age) { + total += _cohort_populations[i]; + } + } + return total; + } + + void promote_all_tenurable(const size_t tenuring_threshold) { + for (size_t i = 0; i < _cohorts_count; i++) { + if (i > tenuring_threshold) { + _cohort_populations[i] = 0; + } + } + } + + static void build_cohort_populations(const double mortality_rates[], size_t cohort_populations[], const size_t cohorts) { + cohort_populations[0] = InitialPopulationSize; + for (size_t i = 1; i < cohorts; i++) { + cohort_populations[i] = cohort_populations[i - 1] * (1.0 - mortality_rates[i - 1]); + } + } +}; + +TEST_F(ShenandoahAgeCensusTest, initialize) { + const ShenandoahAgeCensus census(1); + EXPECT_EQ(census.tenuring_threshold(), ShenandoahAgeCensus::MAX_COHORTS); +} + +TEST_F(ShenandoahAgeCensusTest, ignore_small_populations) { + // Small populations are ignored so we do not return early before reaching the youngest cohort. + ShenandoahAgeCensus census(1); + add_population(census,1, 32); + add_population(census,1, 32); + census.update_census(64); + EXPECT_EQ(1u, census.tenuring_threshold()); +} + +TEST_F(ShenandoahAgeCensusTest, find_high_mortality_rate) { + ShenandoahAgeCensus census(1); + + // Initial threshold, no data + EXPECT_EQ(16u, census.tenuring_threshold()); + + // Provide population data for 1st cohort. Previous epoch has no population data so our + // algorithm skips over all cohorts, leaving tenuring threshold at 1. + update(census, 1); + EXPECT_EQ(1u, census.tenuring_threshold()); + + // Mortality rate of 1st cohort at age 1 is 0.9, we don't want to promote here. Move threshold to 2. + update(census, 2); + EXPECT_EQ(2u, census.tenuring_threshold()); + + // Mortality rate of 1st cohort at age 2 is 0.7, we don't want to promote here. Move threshold to 3. + update(census, 3); + EXPECT_EQ(3u, census.tenuring_threshold()); + + // Mortality rate of 1st cohort at age 3 is 0.5, we don't want to promote here. Move threshold to 4. + update(census, 4); + EXPECT_EQ(4u, census.tenuring_threshold()); + + // Mortality rate of 1st cohort at age 4 is 0.3, we don't want to promote here. Move threshold to 5. + update(census, 5); + EXPECT_EQ(5u, census.tenuring_threshold()); + + // Mortality rate of 1st cohort at age 5 is 0.09, this is less than the mortality rate threshold. It + // is okay to tenure objects older than 5 now. Keep threshold at 5. + update(census, 6); + EXPECT_EQ(5u, census.tenuring_threshold()); + + // Mortality rate at this age is 0. Keep tenuring threshold at 5. + update(census, 7); + EXPECT_EQ(5u, census.tenuring_threshold()); +} + +TEST_F(ShenandoahAgeCensusTest, ignore_mortality_caused_by_promotions) { + ShenandoahAgeCensus census(1); + + // Simulate a sequence of censuses with the same mortality rate. Each one will see a + // mortality rate above the tenuring threshold and raise the tenuring threshold by one. + update(census, 1); + update(census, 2); + update(census, 3); + update(census, 4); + update(census, 5); + + EXPECT_EQ(5u, census.tenuring_threshold()); + + // Simulate the effect of promoting all objects above the tenuring threshold + // out of the young generation. This will look like a very high (100%) mortality + // rate for these cohorts. However, we do _not_ want to raise the threshold in + // this case because these objects haven't really "died", they have just been + // tenured. + promote_all_tenurable(census.tenuring_threshold()); + update(census); + + // We want this to stay at 5 - the mortality in 1st cohort at age 6 was caused by expected promotions. + EXPECT_EQ(5u, census.tenuring_threshold()); +} From 134c3ef41e774b483bcce32ce2fe0ef416017728 Mon Sep 17 00:00:00 2001 From: Dingli Zhang Date: Thu, 11 Sep 2025 00:05:02 +0000 Subject: [PATCH 033/120] 8367293: RISC-V: enable vectorapi test for VectorMask.laneIsSet Reviewed-by: fyang, epeter --- .../vectorapi/VectorMaskLaneIsSetTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java index b7f2103c56c..17d483f1b16 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java @@ -69,7 +69,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 6" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 6" }, applyIfCPUFeature = { "avx2", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 6" }, applyIfCPUFeatureOr = { "avx2", "true", "rvv", "true" }) public static void testVectorMaskLaneIsSetByte_const() { Asserts.assertEquals(ma[0], mask_b.laneIsSet(0)); Asserts.assertEquals(ma[0], mask_s.laneIsSet(0)); @@ -81,7 +81,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" }) public static boolean testVectorMaskLaneIsSet_Byte_variable(int i) { return mask_b.laneIsSet(i); } @@ -93,7 +93,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" }) public static boolean testVectorMaskLaneIsSet_Short_variable(int i) { return mask_s.laneIsSet(i); } @@ -105,7 +105,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" }) public static boolean testVectorMaskLaneIsSet_Int_variable(int i) { return mask_i.laneIsSet(i); } @@ -117,7 +117,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx2", "true", "rvv", "true" }) public static boolean testVectorMaskLaneIsSet_Long_variable(int i) { return mask_l.laneIsSet(i); } @@ -129,7 +129,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" }) public static boolean testVectorMaskLaneIsSet_Float_variable(int i) { return mask_f.laneIsSet(i); } @@ -141,7 +141,7 @@ public class VectorMaskLaneIsSetTest { @Test @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) - @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx2", "true", "rvv", "true" }) public static boolean testVectorMaskLaneIsSet_Double_variable(int i) { return mask_d.laneIsSet(i); } From eb9e04598db7a70347ada005035644012026f902 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Thu, 11 Sep 2025 04:59:07 +0000 Subject: [PATCH 034/120] 8361530: Test javax/swing/GraphicsConfigNotifier/StalePreferredSize.java timed out Reviewed-by: psadhukhan --- .../swing/GraphicsConfigNotifier/StalePreferredSize.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/jdk/javax/swing/GraphicsConfigNotifier/StalePreferredSize.java b/test/jdk/javax/swing/GraphicsConfigNotifier/StalePreferredSize.java index 371c6fb43ef..3be7d08870d 100644 --- a/test/jdk/javax/swing/GraphicsConfigNotifier/StalePreferredSize.java +++ b/test/jdk/javax/swing/GraphicsConfigNotifier/StalePreferredSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,9 +66,8 @@ import static javax.swing.UIManager.getInstalledLookAndFeels; * It is checked by SwingUtilities.updateComponentTreeUI(), if layout * was correct the call to updateComponentTreeUI() will be no-op. * @compile -encoding utf-8 StalePreferredSize.java - * @run main/othervm/timeout=600 StalePreferredSize - * @run main/othervm/timeout=600 -Dsun.java2d.uiScale=1 StalePreferredSize - * @run main/othervm/timeout=600 -Dsun.java2d.uiScale=2.25 StalePreferredSize + * @run main/othervm/timeout=420 StalePreferredSize + * @run main/othervm/timeout=420 -Dsun.java2d.uiScale=2.25 StalePreferredSize */ public final class StalePreferredSize { @@ -92,7 +91,7 @@ public final class StalePreferredSize { public static void main(final String[] args) throws Exception { for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { EventQueue.invokeAndWait(() -> setLookAndFeel(laf)); - for (typeFont = 0; typeFont < 3; typeFont++) { + for (typeFont = 0; typeFont < 1; typeFont++) { System.err.println("typeFont = " + typeFont); for (boolean usePopup : new boolean[]{true, false}) { addViaPopup = usePopup; From 4cc75be80e6a89e0ed293e2f8bbb6d0f94189468 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Thu, 11 Sep 2025 05:03:21 +0000 Subject: [PATCH 035/120] 8366702: C2 SuperWord: refactor VTransform vector nodes Reviewed-by: chagedorn, galder --- .../share/opto/superwordVTransformBuilder.cpp | 110 +++++---- .../share/opto/superwordVTransformBuilder.hpp | 4 +- src/hotspot/share/opto/vtransform.cpp | 211 +++++++++--------- src/hotspot/share/opto/vtransform.hpp | 139 ++++++++++-- 4 files changed, 286 insertions(+), 178 deletions(-) diff --git a/src/hotspot/share/opto/superwordVTransformBuilder.cpp b/src/hotspot/share/opto/superwordVTransformBuilder.cpp index b31f2eda9c0..dbc96c234a9 100644 --- a/src/hotspot/share/opto/superwordVTransformBuilder.cpp +++ b/src/hotspot/share/opto/superwordVTransformBuilder.cpp @@ -80,11 +80,13 @@ void SuperWordVTransformBuilder::build_inputs_for_vector_vtnodes(VectorSet& vtn_ vtn_memory_dependencies.clear(); // Add every memory dependency only once per vtn. if (p0->is_Load()) { + init_req_with_scalar(p0, vtn, MemNode::Control); init_req_with_scalar(p0, vtn, MemNode::Address); for (uint k = 0; k < pack->size(); k++) { add_memory_dependencies_of_node_to_vtnode(pack->at(k), vtn, vtn_memory_dependencies); } } else if (p0->is_Store()) { + init_req_with_scalar(p0, vtn, MemNode::Control); init_req_with_scalar(p0, vtn, MemNode::Address); init_req_with_vector(pack, vtn, MemNode::ValueIn); for (uint k = 0; k < pack->size(); k++) { @@ -93,26 +95,27 @@ void SuperWordVTransformBuilder::build_inputs_for_vector_vtnodes(VectorSet& vtn_ } else if (vtn->isa_ReductionVector() != nullptr) { init_req_with_scalar(p0, vtn, 1); // scalar init init_req_with_vector(pack, vtn, 2); // vector - } else { - assert(vtn->isa_ElementWiseVector() != nullptr, "all other vtnodes are handled above"); - if (VectorNode::is_scalar_rotate(p0) && - p0->in(2)->is_Con() && - Matcher::supports_vector_constant_rotates(p0->in(2)->get_int())) { - init_req_with_vector(pack, vtn, 1); - init_req_with_scalar(p0, vtn, 2); // constant rotation - } else if (VectorNode::is_roundopD(p0)) { - init_req_with_vector(pack, vtn, 1); - init_req_with_scalar(p0, vtn, 2); // constant rounding mode - } else if (p0->is_CMove()) { - // Cmp + Bool + CMove -> VectorMaskCmp + VectorBlend. - set_all_req_with_vectors(pack, vtn); - VTransformBoolVectorNode* vtn_mask_cmp = vtn->in_req(1)->isa_BoolVector(); - if (vtn_mask_cmp->test()._is_negated) { - vtn->swap_req(2, 3); // swap if test was negated. - } - } else { - set_all_req_with_vectors(pack, vtn); + } else if (VectorNode::is_scalar_rotate(p0) && + p0->in(2)->is_Con() && + Matcher::supports_vector_constant_rotates(p0->in(2)->get_int())) { + init_req_with_vector(pack, vtn, 1); + init_req_with_scalar(p0, vtn, 2); // constant rotation + } else if (VectorNode::is_roundopD(p0)) { + init_req_with_vector(pack, vtn, 1); + init_req_with_scalar(p0, vtn, 2); // constant rounding mode + } else if (p0->is_CMove()) { + // Cmp + Bool + CMove -> VectorMaskCmp + VectorBlend. + init_all_req_with_vectors(pack, vtn); + // Inputs must be permuted from (mask, blend1, blend2) -> (blend1, blend2, mask) + vtn->swap_req(1, 2); + vtn->swap_req(2, 3); + // If the test was negated: (blend1, blend2, mask) -> (blend2, blend1, mask) + VTransformBoolVectorNode* vtn_mask_cmp = vtn->in_req(3)->isa_BoolVector(); + if (vtn_mask_cmp->test()._is_negated) { + vtn->swap_req(1, 2); // swap if test was negated. } + } else { + init_all_req_with_vectors(pack, vtn); } } } @@ -139,51 +142,72 @@ void SuperWordVTransformBuilder::build_inputs_for_scalar_vtnodes(VectorSet& vtn_ init_req_with_scalar(n, vtn, 0); continue; } else { - set_all_req_with_scalars(n, vtn); + init_all_req_with_scalars(n, vtn); } } } // Create a vtnode for each pack. No in/out edges set yet. VTransformVectorNode* SuperWordVTransformBuilder::make_vector_vtnode_for_pack(const Node_List* pack) const { - uint pack_size = pack->size(); Node* p0 = pack->at(0); - int opc = p0->Opcode(); - VTransformVectorNode* vtn = nullptr; + const VTransformVectorNodeProperties properties = VTransformVectorNodeProperties::make_from_pack(pack, _vloop_analyzer); + const int sopc = properties.scalar_opcode(); + const uint vlen = properties.vector_length(); + const BasicType bt = properties.element_basic_type(); + VTransformVectorNode* vtn = nullptr; if (p0->is_Load()) { const VPointer& scalar_p = _vloop_analyzer.vpointers().vpointer(p0->as_Load()); - const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * pack_size)); - vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, pack_size, vector_p); + const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * vlen)); + vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, properties, vector_p, p0->adr_type()); } else if (p0->is_Store()) { const VPointer& scalar_p = _vloop_analyzer.vpointers().vpointer(p0->as_Store()); - const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * pack_size)); - vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, pack_size, vector_p); + const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * vlen)); + vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, properties, vector_p, p0->adr_type()); + } else if (p0->is_Cmp()) { + vtn = new (_vtransform.arena()) VTransformCmpVectorNode(_vtransform, properties); } else if (p0->is_Bool()) { VTransformBoolTest kind = _packset.get_bool_test(pack); - vtn = new (_vtransform.arena()) VTransformBoolVectorNode(_vtransform, pack_size, kind); + vtn = new (_vtransform.arena()) VTransformBoolVectorNode(_vtransform, properties, kind); + } else if (p0->is_CMove()) { + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), properties, Op_VectorBlend); } else if (_vloop_analyzer.reductions().is_marked_reduction(p0)) { - vtn = new (_vtransform.arena()) VTransformReductionVectorNode(_vtransform, pack_size); + vtn = new (_vtransform.arena()) VTransformReductionVectorNode(_vtransform, properties); } else if (VectorNode::is_muladds2i(p0)) { // A special kind of binary element-wise vector op: the inputs are "ints" a and b, // but reinterpreted as two "shorts" [a0, a1] and [b0, b1]: // v = MulAddS2I(a, b) = a0 * b0 + a1 + b1 assert(p0->req() == 5, "MulAddS2I should have 4 operands"); - vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, 3, pack_size); + int vopc = VectorNode::opcode(sopc, bt); + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, 3, properties, vopc); + } else if (VectorNode::is_convert_opcode(sopc)) { + assert(p0->req() == 2, "convert should have 2 operands"); + BasicType def_bt = _vloop_analyzer.types().velt_basic_type(p0->in(1)); + int vopc = VectorCastNode::opcode(sopc, def_bt); + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), properties, vopc); + } else if (VectorNode::is_reinterpret_opcode(sopc)) { + assert(p0->req() == 2, "reinterpret should have 2 operands"); + BasicType src_bt = _vloop_analyzer.types().velt_basic_type(p0->in(1)); + vtn = new (_vtransform.arena()) VTransformReinterpretVectorNode(_vtransform, properties, src_bt); + } else if (VectorNode::can_use_RShiftI_instead_of_URShiftI(p0, bt)) { + int vopc = VectorNode::opcode(Op_RShiftI, bt); + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), properties, vopc); + } else if (VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(sopc)) { + vtn = new (_vtransform.arena()) VTransformElementWiseLongOpWithCastToIntVectorNode(_vtransform, properties); } else { assert(p0->req() == 3 || - p0->is_CMove() || - VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(opc) || - VectorNode::is_convert_opcode(opc) || - VectorNode::is_reinterpret_opcode(opc) || - VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(opc) || - opc == Op_FmaD || - opc == Op_FmaF || - opc == Op_FmaHF || - opc == Op_SignumF || - opc == Op_SignumD, + VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(sopc) || + VectorNode::is_reinterpret_opcode(sopc) || + VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(sopc) || + sopc == Op_FmaD || + sopc == Op_FmaF || + sopc == Op_FmaHF || + sopc == Op_SignumF || + sopc == Op_SignumD, "pack type must be in this list"); - vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), pack_size); + assert(!VectorNode::is_roundopD(p0) || p0->in(2)->is_Con(), "rounding mode must be constant"); + int vopc = VectorNode::opcode(sopc, bt); + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), properties, vopc); } vtn->set_nodes(pack); return vtn; @@ -291,7 +315,7 @@ void SuperWordVTransformBuilder::init_req_with_vector(const Node_List* pack, VTr vtn->init_req(j, req); } -void SuperWordVTransformBuilder::set_all_req_with_scalars(Node* n, VTransformNode* vtn) { +void SuperWordVTransformBuilder::init_all_req_with_scalars(Node* n, VTransformNode* vtn) { assert(vtn->req() == n->req(), "scalars must have same number of reqs"); for (uint j = 0; j < n->req(); j++) { Node* def = n->in(j); @@ -300,7 +324,7 @@ void SuperWordVTransformBuilder::set_all_req_with_scalars(Node* n, VTransformNod } } -void SuperWordVTransformBuilder::set_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn) { +void SuperWordVTransformBuilder::init_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn) { Node* p0 = pack->at(0); assert(vtn->req() <= p0->req(), "must have at at most as many reqs"); // Vectors have no ctrl, so ignore it. diff --git a/src/hotspot/share/opto/superwordVTransformBuilder.hpp b/src/hotspot/share/opto/superwordVTransformBuilder.hpp index ea93bb60ffb..6ed8480209a 100644 --- a/src/hotspot/share/opto/superwordVTransformBuilder.hpp +++ b/src/hotspot/share/opto/superwordVTransformBuilder.hpp @@ -79,8 +79,8 @@ private: VTransformNode* get_vtnode_or_wrap_as_outer(Node* n); void init_req_with_scalar(Node* n, VTransformNode* vtn, const int index); void init_req_with_vector(const Node_List* pack, VTransformNode* vtn, const int index); - void set_all_req_with_scalars(Node* n, VTransformNode* vtn); - void set_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn); + void init_all_req_with_scalars(Node* n, VTransformNode* vtn); + void init_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn); void add_memory_dependencies_of_node_to_vtnode(Node* n, VTransformNode* vtn, VectorSet& vtn_memory_dependencies); }; diff --git a/src/hotspot/share/opto/vtransform.cpp b/src/hotspot/share/opto/vtransform.cpp index 2f77c1c2e37..8c1210a5a09 100644 --- a/src/hotspot/share/opto/vtransform.cpp +++ b/src/hotspot/share/opto/vtransform.cpp @@ -104,7 +104,7 @@ bool VTransformGraph::schedule() { } #ifndef PRODUCT - if (_trace._verbose) { + if (_trace._info) { print_schedule(); } #endif @@ -158,11 +158,9 @@ void VTransform::apply_speculative_alignment_runtime_checks() { const GrowableArray& vtnodes = _graph.vtnodes(); for (int i = 0; i < vtnodes.length(); i++) { - VTransformVectorNode* vtn = vtnodes.at(i)->isa_Vector(); + VTransformMemVectorNode* vtn = vtnodes.at(i)->isa_MemVector(); if (vtn == nullptr) { continue; } - MemNode* p0 = vtn->nodes().at(0)->isa_Mem(); - if (p0 == nullptr) { continue; } - const VPointer& vp = vpointer(p0); + const VPointer& vp = vtn->vpointer(); if (vp.mem_pointer().base().is_object()) { continue; } assert(vp.mem_pointer().base().is_native(), "VPointer base must be object or native"); @@ -720,41 +718,41 @@ Node* VTransformApplyState::transformed_node(const VTransformNode* vtn) const { } VTransformApplyResult VTransformMemopScalarNode::apply(VTransformApplyState& apply_state) const { - // This was just wrapped. Now we simply unwap without touching the inputs. + // This was just wrapped. Now we simply unwrap without touching the inputs. return VTransformApplyResult::make_scalar(_node); } VTransformApplyResult VTransformDataScalarNode::apply(VTransformApplyState& apply_state) const { - // This was just wrapped. Now we simply unwap without touching the inputs. + // This was just wrapped. Now we simply unwrap without touching the inputs. return VTransformApplyResult::make_scalar(_node); } VTransformApplyResult VTransformLoopPhiNode::apply(VTransformApplyState& apply_state) const { - // This was just wrapped. Now we simply unwap without touching the inputs. + // This was just wrapped. Now we simply unwrap without touching the inputs. return VTransformApplyResult::make_scalar(_node); } VTransformApplyResult VTransformCFGNode::apply(VTransformApplyState& apply_state) const { - // This was just wrapped. Now we simply unwap without touching the inputs. + // This was just wrapped. Now we simply unwrap without touching the inputs. return VTransformApplyResult::make_scalar(_node); } VTransformApplyResult VTransformOuterNode::apply(VTransformApplyState& apply_state) const { - // This was just wrapped. Now we simply unwap without touching the inputs. + // This was just wrapped. Now we simply unwrap without touching the inputs. return VTransformApplyResult::make_scalar(_node); } VTransformApplyResult VTransformReplicateNode::apply(VTransformApplyState& apply_state) const { Node* val = apply_state.transformed_node(in_req(1)); VectorNode* vn = VectorNode::scalar2vector(val, _vlen, _element_type); - register_new_node_from_vectorization(apply_state, vn, val); - return VTransformApplyResult::make_vector(vn, _vlen, vn->length_in_bytes()); + register_new_node_from_vectorization(apply_state, vn); + return VTransformApplyResult::make_vector(vn); } VTransformApplyResult VTransformConvI2LNode::apply(VTransformApplyState& apply_state) const { Node* val = apply_state.transformed_node(in_req(1)); Node* n = new ConvI2LNode(val); - register_new_node_from_vectorization(apply_state, n, val); + register_new_node_from_vectorization(apply_state, n); return VTransformApplyResult::make_scalar(n); } @@ -766,11 +764,11 @@ VTransformApplyResult VTransformShiftCountNode::apply(VTransformApplyState& appl // bits in a scalar shift operation. But vector shift does not truncate, so // we must apply the mask now. Node* shift_count_masked = new AndINode(shift_count_in, phase->intcon(_mask)); - register_new_node_from_vectorization(apply_state, shift_count_masked, shift_count_in); + register_new_node_from_vectorization(apply_state, shift_count_masked); // Now that masked value is "boadcast" (some platforms only set the lowest element). VectorNode* vn = VectorNode::shift_count(_shift_opcode, shift_count_masked, _vlen, _element_bt); - register_new_node_from_vectorization(apply_state, vn, shift_count_in); - return VTransformApplyResult::make_vector(vn, _vlen, vn->length_in_bytes()); + register_new_node_from_vectorization(apply_state, vn); + return VTransformApplyResult::make_vector(vn); } @@ -781,77 +779,62 @@ VTransformApplyResult VTransformPopulateIndexNode::apply(VTransformApplyState& a assert(VectorNode::is_populate_index_supported(_element_bt), "should support"); const TypeVect* vt = TypeVect::make(_element_bt, _vlen); VectorNode* vn = new PopulateIndexNode(val, phase->intcon(1), vt); - register_new_node_from_vectorization(apply_state, vn, val); - return VTransformApplyResult::make_vector(vn, _vlen, vn->length_in_bytes()); + register_new_node_from_vectorization(apply_state, vn); + return VTransformApplyResult::make_vector(vn); } VTransformApplyResult VTransformElementWiseVectorNode::apply(VTransformApplyState& apply_state) const { - Node* first = nodes().at(0); - uint vlen = nodes().length(); - int opc = first->Opcode(); - BasicType bt = apply_state.vloop_analyzer().types().velt_basic_type(first); - - if (first->is_Cmp()) { - // Cmp + Bool -> VectorMaskCmp - // Handled by Bool / VTransformBoolVectorNode, so we do not generate any nodes here. - return VTransformApplyResult::make_empty(); - } - assert(2 <= req() && req() <= 4, "Must have 1-3 inputs"); - VectorNode* vn = nullptr; + const TypeVect* vt = TypeVect::make(element_basic_type(), vector_length()); Node* in1 = apply_state.transformed_node(in_req(1)); Node* in2 = (req() >= 3) ? apply_state.transformed_node(in_req(2)) : nullptr; - Node* in3 = (req() >= 4) ? apply_state.transformed_node(in_req(3)) : nullptr; - if (first->is_CMove()) { - assert(req() == 4, "three inputs expected: mask, blend1, blend2"); - vn = new VectorBlendNode(/* blend1 */ in2, /* blend2 */ in3, /* mask */ in1); - } else if (VectorNode::is_convert_opcode(opc)) { - assert(first->req() == 2 && req() == 2, "only one input expected"); - int vopc = VectorCastNode::opcode(opc, in1->bottom_type()->is_vect()->element_basic_type()); - vn = VectorCastNode::make(vopc, in1, bt, vlen); - } else if (VectorNode::is_reinterpret_opcode(opc)) { - assert(first->req() == 2 && req() == 2, "only one input expected"); - const TypeVect* vt = TypeVect::make(bt, vlen); - vn = new VectorReinterpretNode(in1, in1->bottom_type()->is_vect(), vt); - } else if (VectorNode::can_use_RShiftI_instead_of_URShiftI(first, bt)) { - opc = Op_RShiftI; - vn = VectorNode::make(opc, in1, in2, vlen, bt); - } else if (VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(opc)) { - // The scalar operation was a long -> int operation. - // However, the vector operation is long -> long. - VectorNode* long_vn = VectorNode::make(opc, in1, nullptr, vlen, T_LONG); - register_new_node_from_vectorization(apply_state, long_vn, first); - // Cast long -> int, to mimic the scalar long -> int operation. - vn = VectorCastNode::make(Op_VectorCastL2X, long_vn, T_INT, vlen); - } else if (req() == 3 || - VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(opc)) { - assert(!VectorNode::is_roundopD(first) || in2->is_Con(), "rounding mode must be constant"); - vn = VectorNode::make(opc, in1, in2, vlen, bt); // unary and binary + VectorNode* vn = nullptr; + if (req() <= 3) { + vn = VectorNode::make(_vector_opcode, in1, in2, vt); // unary and binary } else { - assert(req() == 4, "three inputs expected"); - assert(opc == Op_FmaD || - opc == Op_FmaF || - opc == Op_FmaHF || - opc == Op_SignumF || - opc == Op_SignumD, - "element wise operation must be from this list"); - vn = VectorNode::make(opc, in1, in2, in3, vlen, bt); // ternary + Node* in3 = apply_state.transformed_node(in_req(3)); + vn = VectorNode::make(_vector_opcode, in1, in2, in3, vt); // ternary } register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); - return VTransformApplyResult::make_vector(vn, vlen, vn->length_in_bytes()); + return VTransformApplyResult::make_vector(vn); +} + +VTransformApplyResult VTransformElementWiseLongOpWithCastToIntVectorNode::apply(VTransformApplyState& apply_state) const { + uint vlen = vector_length(); + int sopc = scalar_opcode(); + Node* in1 = apply_state.transformed_node(in_req(1)); + + // The scalar operation was a long -> int operation. + // However, the vector operation is long -> long. + VectorNode* long_vn = VectorNode::make(sopc, in1, nullptr, vlen, T_LONG); + register_new_node_from_vectorization(apply_state, long_vn); + // Cast long -> int, to mimic the scalar long -> int operation. + VectorNode* vn = VectorCastNode::make(Op_VectorCastL2X, long_vn, T_INT, vlen); + register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); + return VTransformApplyResult::make_vector(vn); +} + +VTransformApplyResult VTransformReinterpretVectorNode::apply(VTransformApplyState& apply_state) const { + const TypeVect* dst_vt = TypeVect::make(element_basic_type(), vector_length()); + const TypeVect* src_vt = TypeVect::make(_src_bt, vector_length()); + assert(VectorNode::is_reinterpret_opcode(scalar_opcode()), "scalar opcode must be reinterpret"); + + Node* in1 = apply_state.transformed_node(in_req(1)); + VectorNode* vn = new VectorReinterpretNode(in1, src_vt, dst_vt); + + register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); + return VTransformApplyResult::make_vector(vn); } VTransformApplyResult VTransformBoolVectorNode::apply(VTransformApplyState& apply_state) const { - BoolNode* first = nodes().at(0)->as_Bool(); - uint vlen = nodes().length(); - BasicType bt = apply_state.vloop_analyzer().types().velt_basic_type(first); + const TypeVect* vt = TypeVect::make(element_basic_type(), vector_length()); + assert(scalar_opcode() == Op_Bool, ""); // Cmp + Bool -> VectorMaskCmp - VTransformElementWiseVectorNode* vtn_cmp = in_req(1)->isa_ElementWiseVector(); - assert(vtn_cmp != nullptr && vtn_cmp->nodes().at(0)->is_Cmp(), - "bool vtn expects cmp vtn as input"); + VTransformCmpVectorNode* vtn_cmp = in_req(1)->isa_CmpVector(); + assert(vtn_cmp != nullptr, "bool vtn expects cmp vtn as input"); Node* cmp_in1 = apply_state.transformed_node(vtn_cmp->in_req(1)); Node* cmp_in2 = apply_state.transformed_node(vtn_cmp->in_req(2)); @@ -859,35 +842,30 @@ VTransformApplyResult VTransformBoolVectorNode::apply(VTransformApplyState& appl PhaseIdealLoop* phase = apply_state.phase(); ConINode* mask_node = phase->intcon((int)mask); - const TypeVect* vt = TypeVect::make(bt, vlen); VectorNode* vn = new VectorMaskCmpNode(mask, cmp_in1, cmp_in2, mask_node, vt); register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); - return VTransformApplyResult::make_vector(vn, vlen, vn->vect_type()->length_in_bytes()); + return VTransformApplyResult::make_vector(vn); } VTransformApplyResult VTransformReductionVectorNode::apply(VTransformApplyState& apply_state) const { - Node* first = nodes().at(0); - uint vlen = nodes().length(); - int opc = first->Opcode(); - BasicType bt = first->bottom_type()->basic_type(); - Node* init = apply_state.transformed_node(in_req(1)); Node* vec = apply_state.transformed_node(in_req(2)); - ReductionNode* vn = ReductionNode::make(opc, nullptr, init, vec, bt); + ReductionNode* vn = ReductionNode::make(scalar_opcode(), nullptr, init, vec, element_basic_type()); register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); - return VTransformApplyResult::make_vector(vn, vlen, vn->vect_type()->length_in_bytes()); + return VTransformApplyResult::make_vector(vn, vn->vect_type()); } VTransformApplyResult VTransformLoadVectorNode::apply(VTransformApplyState& apply_state) const { + int sopc = scalar_opcode(); + uint vlen = vector_length(); + BasicType bt = element_basic_type(); + LoadNode* first = nodes().at(0)->as_Load(); - uint vlen = nodes().length(); - Node* ctrl = first->in(MemNode::Control); + Node* ctrl = apply_state.transformed_node(in_req(MemNode::Control)); + // first has the correct memory state, determined by VTransformGraph::apply_memops_reordering_with_schedule Node* mem = first->in(MemNode::Memory); - Node* adr = first->in(MemNode::Address); - int opc = first->Opcode(); - const TypePtr* adr_type = first->adr_type(); - BasicType bt = apply_state.vloop_analyzer().types().velt_basic_type(first); + Node* adr = apply_state.transformed_node(in_req(MemNode::Address)); // Set the memory dependency of the LoadVector as early as possible. // Walk up the memory chain, and ignore any StoreVector that provably @@ -902,34 +880,33 @@ VTransformApplyResult VTransformLoadVectorNode::apply(VTransformApplyState& appl } } - LoadVectorNode* vn = LoadVectorNode::make(opc, ctrl, mem, adr, adr_type, vlen, bt, + LoadVectorNode* vn = LoadVectorNode::make(sopc, ctrl, mem, adr, _adr_type, vlen, bt, control_dependency()); DEBUG_ONLY( if (VerifyAlignVector) { vn->set_must_verify_alignment(); } ) register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); - return VTransformApplyResult::make_vector(vn, vlen, vn->memory_size()); + return VTransformApplyResult::make_vector(vn, vn->vect_type()); } VTransformApplyResult VTransformStoreVectorNode::apply(VTransformApplyState& apply_state) const { + int sopc = scalar_opcode(); + uint vlen = vector_length(); + StoreNode* first = nodes().at(0)->as_Store(); - uint vlen = nodes().length(); - Node* ctrl = first->in(MemNode::Control); + Node* ctrl = apply_state.transformed_node(in_req(MemNode::Control)); + // first has the correct memory state, determined by VTransformGraph::apply_memops_reordering_with_schedule Node* mem = first->in(MemNode::Memory); - Node* adr = first->in(MemNode::Address); - int opc = first->Opcode(); - const TypePtr* adr_type = first->adr_type(); + Node* adr = apply_state.transformed_node(in_req(MemNode::Address)); Node* value = apply_state.transformed_node(in_req(MemNode::ValueIn)); - StoreVectorNode* vn = StoreVectorNode::make(opc, ctrl, mem, adr, adr_type, value, vlen); + StoreVectorNode* vn = StoreVectorNode::make(sopc, ctrl, mem, adr, _adr_type, value, vlen); DEBUG_ONLY( if (VerifyAlignVector) { vn->set_must_verify_alignment(); } ) register_new_node_from_vectorization_and_replace_scalar_nodes(apply_state, vn); - return VTransformApplyResult::make_vector(vn, vlen, vn->memory_size()); + return VTransformApplyResult::make_vector(vn, vn->vect_type()); } void VTransformVectorNode::register_new_node_from_vectorization_and_replace_scalar_nodes(VTransformApplyState& apply_state, Node* vn) const { PhaseIdealLoop* phase = apply_state.phase(); - Node* first = nodes().at(0); - - register_new_node_from_vectorization(apply_state, vn, first); + register_new_node_from_vectorization(apply_state, vn); for (int i = 0; i < _nodes.length(); i++) { Node* n = _nodes.at(i); @@ -937,9 +914,11 @@ void VTransformVectorNode::register_new_node_from_vectorization_and_replace_scal } } -void VTransformNode::register_new_node_from_vectorization(VTransformApplyState& apply_state, Node* vn, Node* old_node) const { +void VTransformNode::register_new_node_from_vectorization(VTransformApplyState& apply_state, Node* vn) const { PhaseIdealLoop* phase = apply_state.phase(); - phase->register_new_node_with_ctrl_of(vn, old_node); + // Using the cl is sometimes not the most accurate, but still correct. We do not have to be + // perfectly accurate, because we will set major_progress anyway. + phase->register_new_node(vn, apply_state.vloop().cl()); phase->igvn()._worklist.push(vn); VectorNode::trace_new_vector(vn, "AutoVectorization"); } @@ -1050,18 +1029,32 @@ void VTransformPopulateIndexNode::print_spec() const { } void VTransformVectorNode::print_spec() const { - tty->print("%d-pack[", _nodes.length()); - for (int i = 0; i < _nodes.length(); i++) { - Node* n = _nodes.at(i); - if (i > 0) { - tty->print(", "); - } - tty->print("%d %s", n->_idx, n->Name()); - } - tty->print("]"); + tty->print("Properties[orig=[%d %s] sopc=%s vlen=%d element_bt=%s]", + approximate_origin()->_idx, + approximate_origin()->Name(), + NodeClassNames[scalar_opcode()], + vector_length(), + type2name(element_basic_type())); if (is_load_or_store_in_loop()) { tty->print(" "); vpointer().print_on(tty, false); } } + +void VTransformElementWiseVectorNode::print_spec() const { + VTransformVectorNode::print_spec(); + tty->print(" vopc=%s", NodeClassNames[_vector_opcode]); +} + +void VTransformReinterpretVectorNode::print_spec() const { + VTransformVectorNode::print_spec(); + tty->print(" src_bt=%s", type2name(_src_bt)); +} + +void VTransformBoolVectorNode::print_spec() const { + VTransformVectorNode::print_spec(); + const BoolTest bt(_test._mask); + tty->print(" test="); + bt.dump_on(tty); +} #endif diff --git a/src/hotspot/share/opto/vtransform.hpp b/src/hotspot/share/opto/vtransform.hpp index 60b0b5d4f9d..9a4e4de01a2 100644 --- a/src/hotspot/share/opto/vtransform.hpp +++ b/src/hotspot/share/opto/vtransform.hpp @@ -26,6 +26,7 @@ #include "opto/node.hpp" #include "opto/vectorization.hpp" +#include "opto/vectornode.hpp" // VTransform: // - Models the transformation of the scalar loop to vectorized loop: @@ -67,6 +68,7 @@ class VTransformCFGNode; class VTransformOuterNode; class VTransformVectorNode; class VTransformElementWiseVectorNode; +class VTransformCmpVectorNode; class VTransformBoolVectorNode; class VTransformReductionVectorNode; class VTransformMemVectorNode; @@ -90,9 +92,12 @@ public: return VTransformApplyResult(n, 0, 0); } - static VTransformApplyResult make_vector(Node* n, uint vector_length, uint vector_width) { - assert(vector_length > 0 && vector_width > 0, "must have nonzero size"); - return VTransformApplyResult(n, vector_length, vector_width); + static VTransformApplyResult make_vector(VectorNode* vn) { + return VTransformApplyResult(vn, vn->length(), vn->length_in_bytes()); + } + + static VTransformApplyResult make_vector(Node* n, const TypeVect* vt) { + return VTransformApplyResult(n, vt->length(), vt->length_in_bytes()); } static VTransformApplyResult make_empty() { @@ -431,6 +436,7 @@ public: virtual VTransformOuterNode* isa_Outer() { return nullptr; } virtual VTransformVectorNode* isa_Vector() { return nullptr; } virtual VTransformElementWiseVectorNode* isa_ElementWiseVector() { return nullptr; } + virtual VTransformCmpVectorNode* isa_CmpVector() { return nullptr; } virtual VTransformBoolVectorNode* isa_BoolVector() { return nullptr; } virtual VTransformReductionVectorNode* isa_ReductionVector() { return nullptr; } virtual VTransformMemVectorNode* isa_MemVector() { return nullptr; } @@ -445,7 +451,7 @@ public: Node* find_transformed_input(int i, const GrowableArray& vnode_idx_to_transformed_node) const; - void register_new_node_from_vectorization(VTransformApplyState& apply_state, Node* vn, Node* old_node) const; + void register_new_node_from_vectorization(VTransformApplyState& apply_state, Node* vn) const; NOT_PRODUCT(virtual const char* name() const = 0;) NOT_PRODUCT(void print() const;) @@ -590,13 +596,52 @@ public: NOT_PRODUCT(virtual void print_spec() const override;) }; -// Base class for all vector vtnodes. +// Bundle the information needed for vector nodes. +class VTransformVectorNodeProperties : public StackObj { +private: + Node* _approximate_origin; // for proper propagation of node notes + const int _scalar_opcode; + const uint _vector_length; + const BasicType _element_basic_type; + + VTransformVectorNodeProperties(Node* approximate_origin, + int scalar_opcode, + uint vector_length, + BasicType element_basic_type) : + _approximate_origin(approximate_origin), + _scalar_opcode(scalar_opcode), + _vector_length(vector_length), + _element_basic_type(element_basic_type) {} + +public: + static VTransformVectorNodeProperties make_from_pack(const Node_List* pack, const VLoopAnalyzer& vloop_analyzer) { + Node* first = pack->at(0); + int opc = first->Opcode(); + int vlen = pack->size(); + BasicType bt = vloop_analyzer.types().velt_basic_type(first); + return VTransformVectorNodeProperties(first, opc, vlen, bt); + } + + Node* approximate_origin() const { return _approximate_origin; } + int scalar_opcode() const { return _scalar_opcode; } + uint vector_length() const { return _vector_length; } + BasicType element_basic_type() const { return _element_basic_type; } +}; + +// Abstract base class for all vector vtnodes. class VTransformVectorNode : public VTransformNode { private: + const VTransformVectorNodeProperties _properties; +protected: GrowableArray _nodes; public: - VTransformVectorNode(VTransform& vtransform, const uint req, const uint number_of_nodes) : - VTransformNode(vtransform, req), _nodes(vtransform.arena(), number_of_nodes, number_of_nodes, nullptr) {} + VTransformVectorNode(VTransform& vtransform, const uint req, const VTransformVectorNodeProperties properties) : + VTransformNode(vtransform, req), + _properties(properties), + _nodes(vtransform.arena(), + properties.vector_length(), + properties.vector_length(), + nullptr) {} void set_nodes(const Node_List* pack) { for (uint k = 0; k < pack->size(); k++) { @@ -604,20 +649,50 @@ public: } } - const GrowableArray& nodes() const { return _nodes; } virtual VTransformVectorNode* isa_Vector() override { return this; } void register_new_node_from_vectorization_and_replace_scalar_nodes(VTransformApplyState& apply_state, Node* vn) const; NOT_PRODUCT(virtual void print_spec() const override;) + +protected: + Node* approximate_origin() const { return _properties.approximate_origin(); } + int scalar_opcode() const { return _properties.scalar_opcode(); } + uint vector_length() const { return _properties.vector_length(); } + BasicType element_basic_type() const { return _properties.element_basic_type(); } }; // Catch all for all element-wise vector operations. class VTransformElementWiseVectorNode : public VTransformVectorNode { +private: + const int _vector_opcode; public: - VTransformElementWiseVectorNode(VTransform& vtransform, uint req, uint number_of_nodes) : - VTransformVectorNode(vtransform, req, number_of_nodes) {} + VTransformElementWiseVectorNode(VTransform& vtransform, uint req, const VTransformVectorNodeProperties properties, const int vector_opcode) : + VTransformVectorNode(vtransform, req, properties), _vector_opcode(vector_opcode) {} virtual VTransformElementWiseVectorNode* isa_ElementWiseVector() override { return this; } virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override; NOT_PRODUCT(virtual const char* name() const override { return "ElementWiseVector"; };) + NOT_PRODUCT(virtual void print_spec() const override;) +}; + +// The scalar operation was a long -> int operation. +// However, the vector operation is long -> long. +// Hence, we vectorize it as: long --long_op--> long --cast--> int +class VTransformElementWiseLongOpWithCastToIntVectorNode : public VTransformVectorNode { +public: + VTransformElementWiseLongOpWithCastToIntVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties) : + VTransformVectorNode(vtransform, 2, properties) {} + virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override; + NOT_PRODUCT(virtual const char* name() const override { return "ElementWiseLongOpWithCastToIntVector"; };) +}; + +class VTransformReinterpretVectorNode : public VTransformVectorNode { +private: + const BasicType _src_bt; +public: + VTransformReinterpretVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties, const BasicType src_bt) : + VTransformVectorNode(vtransform, 2, properties), _src_bt(src_bt) {} + virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override; + NOT_PRODUCT(virtual const char* name() const override { return "ReinterpretVector"; };) + NOT_PRODUCT(virtual void print_spec() const override;) }; struct VTransformBoolTest { @@ -628,23 +703,35 @@ struct VTransformBoolTest { _mask(mask), _is_negated(is_negated) {} }; -class VTransformBoolVectorNode : public VTransformElementWiseVectorNode { +// Cmp + Bool -> VectorMaskCmp +// The Bool node takes care of "apply". +class VTransformCmpVectorNode : public VTransformVectorNode { +public: + VTransformCmpVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties) : + VTransformVectorNode(vtransform, 3, properties) {} + virtual VTransformCmpVectorNode* isa_CmpVector() override { return this; } + virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override { return VTransformApplyResult::make_empty(); } + NOT_PRODUCT(virtual const char* name() const override { return "CmpVector"; };) +}; + +class VTransformBoolVectorNode : public VTransformVectorNode { private: const VTransformBoolTest _test; public: - VTransformBoolVectorNode(VTransform& vtransform, uint number_of_nodes, VTransformBoolTest test) : - VTransformElementWiseVectorNode(vtransform, 2, number_of_nodes), _test(test) {} + VTransformBoolVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties, VTransformBoolTest test) : + VTransformVectorNode(vtransform, 2, properties), _test(test) {} VTransformBoolTest test() const { return _test; } virtual VTransformBoolVectorNode* isa_BoolVector() override { return this; } virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override; NOT_PRODUCT(virtual const char* name() const override { return "BoolVector"; };) + NOT_PRODUCT(virtual void print_spec() const override;) }; class VTransformReductionVectorNode : public VTransformVectorNode { public: // req = 3 -> [ctrl, scalar init, vector] - VTransformReductionVectorNode(VTransform& vtransform, uint number_of_nodes) : - VTransformVectorNode(vtransform, 3, number_of_nodes) {} + VTransformReductionVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties) : + VTransformVectorNode(vtransform, 3, properties) {} virtual VTransformReductionVectorNode* isa_ReductionVector() override { return this; } virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override; NOT_PRODUCT(virtual const char* name() const override { return "ReductionVector"; };) @@ -653,12 +740,16 @@ public: class VTransformMemVectorNode : public VTransformVectorNode { private: const VPointer _vpointer; // with size of the vector +protected: + const TypePtr* _adr_type; public: - VTransformMemVectorNode(VTransform& vtransform, const uint req, uint number_of_nodes, const VPointer& vpointer) : - VTransformVectorNode(vtransform, req, number_of_nodes), - _vpointer(vpointer) {} + VTransformMemVectorNode(VTransform& vtransform, const uint req, const VTransformVectorNodeProperties properties, const VPointer& vpointer, const TypePtr* adr_type) : + VTransformVectorNode(vtransform, req, properties), + _vpointer(vpointer), + _adr_type(adr_type) {} + const GrowableArray& nodes() const { return _nodes; } virtual VTransformMemVectorNode* isa_MemVector() override { return this; } virtual bool is_load_or_store_in_loop() const override { return true; } virtual const VPointer& vpointer() const override { return _vpointer; } @@ -667,8 +758,8 @@ public: class VTransformLoadVectorNode : public VTransformMemVectorNode { public: // req = 3 -> [ctrl, mem, adr] - VTransformLoadVectorNode(VTransform& vtransform, uint number_of_nodes, const VPointer& vpointer) : - VTransformMemVectorNode(vtransform, 3, number_of_nodes, vpointer) {} + VTransformLoadVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties, const VPointer& vpointer, const TypePtr* adr_type) : + VTransformMemVectorNode(vtransform, 3, properties, vpointer, adr_type) {} LoadNode::ControlDependency control_dependency() const; virtual VTransformLoadVectorNode* isa_LoadVector() override { return this; } virtual bool is_load_in_loop() const override { return true; } @@ -679,8 +770,8 @@ public: class VTransformStoreVectorNode : public VTransformMemVectorNode { public: // req = 4 -> [ctrl, mem, adr, val] - VTransformStoreVectorNode(VTransform& vtransform, uint number_of_nodes, const VPointer& vpointer) : - VTransformMemVectorNode(vtransform, 4, number_of_nodes, vpointer) {} + VTransformStoreVectorNode(VTransform& vtransform, const VTransformVectorNodeProperties properties, const VPointer& vpointer, const TypePtr* adr_type) : + VTransformMemVectorNode(vtransform, 4, properties, vpointer, adr_type) {} virtual VTransformStoreVectorNode* isa_StoreVector() override { return this; } virtual bool is_load_in_loop() const override { return false; } virtual VTransformApplyResult apply(VTransformApplyState& apply_state) const override; @@ -703,8 +794,8 @@ void VTransformGraph::for_each_memop_in_schedule(Callback callback) const { callback(scalar->node()); } - VTransformVectorNode* vector = vtn->isa_Vector(); - if (vector != nullptr && vector->nodes().at(0)->is_Mem()) { + VTransformMemVectorNode* vector = vtn->isa_MemVector(); + if (vector != nullptr) { for (int j = 0; j < vector->nodes().length(); j++) { callback(vector->nodes().at(j)->as_Mem()); } From 2826d1702534783023802ac5c8d8ea575558f09f Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Thu, 11 Sep 2025 05:05:30 +0000 Subject: [PATCH 036/120] 8367243: Format issues with dist dump debug output in PhaseGVN::dead_loop_check Reviewed-by: thartmann --- src/hotspot/share/opto/phaseX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp index a4248cb2b91..00b36d0bf43 100644 --- a/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp @@ -780,7 +780,7 @@ void PhaseGVN::dead_loop_check( Node *n ) { } } } - if (!no_dead_loop) n->dump_bfs(100,nullptr,"#"); + if (!no_dead_loop) { n->dump_bfs(100, nullptr, ""); } assert(no_dead_loop, "dead loop detected"); } } From 7690a45f77a2da47fa912fe7a2b2faa589f259f0 Mon Sep 17 00:00:00 2001 From: Mikhail Yankelevich Date: Thu, 11 Sep 2025 06:55:32 +0000 Subject: [PATCH 037/120] 8366342: Key generator and key pair generator tests skipping, but showing as passed Reviewed-by: weijun --- .../security/pkcs11/KeyGenerator/DESParity.java | 11 ++++++----- .../sun/security/pkcs11/KeyGenerator/TestAES.java | 14 +++++++------- .../security/pkcs11/KeyGenerator/TestChaCha20.java | 7 ++++--- .../pkcs11/KeyGenerator/TestKeyGenerator.java | 2 +- .../pkcs11/KeyPairGenerator/TestDH2048.java | 7 ++++--- .../TestDefaultDHPrivateExpSize.java | 9 ++++----- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/test/jdk/sun/security/pkcs11/KeyGenerator/DESParity.java b/test/jdk/sun/security/pkcs11/KeyGenerator/DESParity.java index 59f58ca525e..f9da78df0e2 100644 --- a/test/jdk/sun/security/pkcs11/KeyGenerator/DESParity.java +++ b/test/jdk/sun/security/pkcs11/KeyGenerator/DESParity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, 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 @@ -32,6 +32,8 @@ * @run main/othervm DESParity */ +import jtreg.SkippedException; + import java.security.Provider; import java.util.Random; import javax.crypto.SecretKey; @@ -45,8 +47,7 @@ public class DESParity extends PKCS11Test { @Override public void main(Provider p) throws Exception { if (p.getService("SecretKeyFactory", "DES") == null) { - System.out.println("Not supported by provider, skipping"); - return; + throw new SkippedException("Not supported by provider, skipping"); } Random random = new Random(); SecretKeyFactory kf; @@ -57,7 +58,7 @@ public class DESParity extends PKCS11Test { random.nextBytes(b); SecretKeySpec spec = new SecretKeySpec(b, "DES"); SecretKey key = kf.generateSecret(spec); - if (DESKeySpec.isParityAdjusted(key.getEncoded(), 0) == false) { + if (!DESKeySpec.isParityAdjusted(key.getEncoded(), 0)) { throw new Exception("DES key not parity adjusted"); } } @@ -68,7 +69,7 @@ public class DESParity extends PKCS11Test { random.nextBytes(b); SecretKeySpec spec = new SecretKeySpec(b, "DESede"); SecretKey key = kf.generateSecret(spec); - if (DESedeKeySpec.isParityAdjusted(key.getEncoded(), 0) == false) { + if (!DESedeKeySpec.isParityAdjusted(key.getEncoded(), 0)) { throw new Exception("DESede key not parity adjusted"); } } diff --git a/test/jdk/sun/security/pkcs11/KeyGenerator/TestAES.java b/test/jdk/sun/security/pkcs11/KeyGenerator/TestAES.java index e74007a65e3..66078be30bd 100644 --- a/test/jdk/sun/security/pkcs11/KeyGenerator/TestAES.java +++ b/test/jdk/sun/security/pkcs11/KeyGenerator/TestAES.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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,13 +30,14 @@ * @library /test/lib .. * @run main TestAES */ +import jtreg.SkippedException; +import sun.security.util.SecurityProviderConstants; + import java.security.Provider; -import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.NoSuchAlgorithmException; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; -import static sun.security.util.SecurityProviderConstants.*; public class TestAES extends PKCS11Test { @@ -53,17 +54,16 @@ public class TestAES extends PKCS11Test { try { kg = KeyGenerator.getInstance(ALGO, p); } catch (NoSuchAlgorithmException nsae) { - System.out.println("Skip; no support for " + ALGO); - return; + throw new SkippedException("Skip; no support for " + ALGO, nsae); } // first try w/o setting a key length and check if the generated key // length matches SecretKey key = kg.generateKey(); byte[] keyValue = key.getEncoded(); - if (key.getEncoded().length != getDefAESKeySize() >> 3) { + if (key.getEncoded().length != SecurityProviderConstants.getDefAESKeySize() >> 3) { throw new RuntimeException("Default AES key length should be " + - getDefAESKeySize()); + SecurityProviderConstants.getDefAESKeySize()); } for (int keySize : new int[] { 16, 32, 64, 128, 256, 512, 1024 }) { diff --git a/test/jdk/sun/security/pkcs11/KeyGenerator/TestChaCha20.java b/test/jdk/sun/security/pkcs11/KeyGenerator/TestChaCha20.java index a21571cd957..0eaab538655 100644 --- a/test/jdk/sun/security/pkcs11/KeyGenerator/TestChaCha20.java +++ b/test/jdk/sun/security/pkcs11/KeyGenerator/TestChaCha20.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -29,6 +29,8 @@ * @library /test/lib .. * @run main/othervm TestChaCha20 */ +import jtreg.SkippedException; + import java.security.Provider; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; @@ -54,8 +56,7 @@ public class TestChaCha20 extends PKCS11Test { try { kg = KeyGenerator.getInstance(ALGO, p); } catch (NoSuchAlgorithmException nsae) { - System.out.println("Skip; no support for " + ALGO); - return; + throw new SkippedException("Skip; no support for " + ALGO, nsae); } try { diff --git a/test/jdk/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java b/test/jdk/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java index 15d0ee87fe4..50886a7aba3 100644 --- a/test/jdk/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java +++ b/test/jdk/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, 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 diff --git a/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java b/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java index b05861ff3ae..06a9fa67afe 100644 --- a/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java +++ b/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -31,6 +31,8 @@ * @run main/othervm TestDH2048 */ +import jtreg.SkippedException; + import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -50,8 +52,7 @@ public class TestDH2048 extends PKCS11Test { @Override public void main(Provider p) throws Exception { if (p.getService("KeyPairGenerator", "DH") == null) { - System.out.println("KPG for DH not supported, skipping"); - return; + throw new SkippedException("KPG for DH not supported, skipping"); } KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", p); kpg.initialize(512); diff --git a/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDefaultDHPrivateExpSize.java b/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDefaultDHPrivateExpSize.java index cb93a96fdd2..3f19a59423b 100644 --- a/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDefaultDHPrivateExpSize.java +++ b/test/jdk/sun/security/pkcs11/KeyPairGenerator/TestDefaultDHPrivateExpSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -21,12 +21,12 @@ * questions. */ -import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Provider; -import java.security.PrivateKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.interfaces.DHPrivateKey; + +import jtreg.SkippedException; import sun.security.util.SecurityProviderConstants; import sun.security.provider.ParameterCache; @@ -47,8 +47,7 @@ public class TestDefaultDHPrivateExpSize extends PKCS11Test { System.out.println("Testing " + p.getName()); if (p.getService("KeyPairGenerator", "DH") == null) { - System.out.println("Skip, no support for DH KeyPairGenerator"); - return; + throw new SkippedException("Skip, no support for DH KeyPairGenerator"); } KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", p); From 8ba0db0de8b79f64cbfa56683f660f888c880182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Thu, 11 Sep 2025 07:42:39 +0000 Subject: [PATCH 038/120] 8366951: Test runtime/logging/StressAsyncUL.java is timing out Reviewed-by: ayang, lkorinth, dholmes, syan --- test/hotspot/jtreg/runtime/logging/StressAsyncUL.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/runtime/logging/StressAsyncUL.java b/test/hotspot/jtreg/runtime/logging/StressAsyncUL.java index 2967507fa64..479f62d6c30 100644 --- a/test/hotspot/jtreg/runtime/logging/StressAsyncUL.java +++ b/test/hotspot/jtreg/runtime/logging/StressAsyncUL.java @@ -45,12 +45,12 @@ public class StressAsyncUL { } } public static void main(String[] args) throws Exception { - analyze_output(false, "-Xlog:async:drop", "-Xlog:all=trace", InnerClass.class.getName()); - analyze_output(true, "-Xlog:async:stall", "-Xlog:all=trace", InnerClass.class.getName()); + analyze_output(false, "-Xlog:async:drop", "-Xlog:all=debug", InnerClass.class.getName()); + analyze_output(true, "-Xlog:async:stall", "-Xlog:all=debug", InnerClass.class.getName()); // Stress test with a very small buffer. Note: Any valid buffer size must be able to hold a flush token. // Therefore the size of the buffer cannot be zero. - analyze_output(false, "-Xlog:async:drop", "-Xlog:all=trace", "-XX:AsyncLogBufferSize=192", InnerClass.class.getName()); - analyze_output(true, "-Xlog:async:stall", "-Xlog:all=trace", "-XX:AsyncLogBufferSize=192", InnerClass.class.getName()); + analyze_output(false, "-Xlog:async:drop", "-Xlog:all=debug", "-XX:AsyncLogBufferSize=192", InnerClass.class.getName()); + analyze_output(true, "-Xlog:async:stall", "-Xlog:all=debug", "-XX:AsyncLogBufferSize=192", InnerClass.class.getName()); } public static class InnerClass { From 0b3a303053d0eb5a98ed3d9df42c659db148b470 Mon Sep 17 00:00:00 2001 From: Hamlin Li Date: Thu, 11 Sep 2025 08:07:25 +0000 Subject: [PATCH 039/120] 8367066: RISC-V: refine register selection in MacroAssembler:: decode_klass_not_null Reviewed-by: fyang, fjiang --- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 13 +++++-------- src/hotspot/cpu/riscv/riscv.ad | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 1436bc02113..8f136135a89 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3402,6 +3402,8 @@ void MacroAssembler::decode_klass_not_null(Register r, Register tmp) { void MacroAssembler::decode_klass_not_null(Register dst, Register src, Register tmp) { assert(UseCompressedClassPointers, "should only be used for compressed headers"); + assert_different_registers(dst, tmp); + assert_different_registers(src, tmp); if (CompressedKlassPointers::base() == nullptr) { if (CompressedKlassPointers::shift() != 0) { @@ -3412,18 +3414,13 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src, Register return; } - Register xbase = dst; - if (dst == src) { - xbase = tmp; - } + Register xbase = tmp; - assert_different_registers(src, xbase); mv(xbase, (uintptr_t)CompressedKlassPointers::base()); if (CompressedKlassPointers::shift() != 0) { - Register t = src == dst ? dst : t0; - assert_different_registers(t, xbase); - shadd(dst, src, xbase, t, CompressedKlassPointers::shift()); + // dst = (src << shift) + xbase + shadd(dst, src, xbase, dst /* temporary, dst != xbase */, CompressedKlassPointers::shift()); } else { add(dst, xbase, src); } diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 0c4dd7b71e2..739a525c9a4 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -8938,7 +8938,7 @@ instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src, iRegPNoSp tmp) %{ match(Set dst (DecodeNKlass src)); - effect(TEMP tmp); + effect(TEMP_DEF dst, TEMP tmp); ins_cost(ALU_COST); format %{ "decode_klass_not_null $dst, $src\t#@decodeKlass_not_null" %} From 3d679087b0376c221d536780cee387dc2dd8019e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Sikstr=C3=B6m?= Date: Thu, 11 Sep 2025 08:53:09 +0000 Subject: [PATCH 040/120] 8367268: Remove unused os::numa_topology_changed() Reviewed-by: ayang, dholmes --- src/hotspot/os/aix/os_aix.cpp | 4 ---- src/hotspot/os/bsd/os_bsd.cpp | 2 -- src/hotspot/os/linux/os_linux.cpp | 2 -- src/hotspot/os/windows/os_windows.cpp | 1 - src/hotspot/share/runtime/os.hpp | 1 - 5 files changed, 10 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index aa119210f47..2dd60b51119 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1753,10 +1753,6 @@ void os::numa_make_global(char *addr, size_t bytes) { void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { } -bool os::numa_topology_changed() { - return false; -} - size_t os::numa_get_groups_num() { return 1; } diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 4f5fed2c8c0..8b75c0dcdd8 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -1599,8 +1599,6 @@ void os::numa_make_global(char *addr, size_t bytes) { void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { } -bool os::numa_topology_changed() { return false; } - size_t os::numa_get_groups_num() { return 1; } diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index d133813feb0..9f896d62d4d 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2988,8 +2988,6 @@ void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { Linux::numa_tonode_memory(addr, bytes, lgrp_hint); } -bool os::numa_topology_changed() { return false; } - size_t os::numa_get_groups_num() { // Return just the number of nodes in which it's possible to allocate memory // (in numa terminology, configured nodes). diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 09d8b542a10..4061ccf9dac 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -3794,7 +3794,6 @@ size_t os::pd_pretouch_memory(void* first, void* last, size_t page_size) { void os::numa_make_global(char *addr, size_t bytes) { } void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { } -bool os::numa_topology_changed() { return false; } size_t os::numa_get_groups_num() { return MAX2(numa_node_list_holder.get_count(), 1); } int os::numa_get_group_id() { return 0; } size_t os::numa_get_leaf_groups(uint *ids, size_t size) { diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 9db4380fc07..4f6830daa4c 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -540,7 +540,6 @@ class os: AllStatic { static void numa_make_global(char *addr, size_t bytes); static size_t numa_get_groups_num(); static size_t numa_get_leaf_groups(uint *ids, size_t size); - static bool numa_topology_changed(); static int numa_get_group_id(); static int numa_get_group_id_for_address(const void* address); static bool numa_get_group_ids_for_range(const void** addresses, int* lgrp_ids, size_t count); From 3355a9d3fa3e57d489f716ebc1c885c1391274ea Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 11 Sep 2025 10:43:25 +0000 Subject: [PATCH 041/120] 8285150: Improve tab completion for annotations Reviewed-by: liach --- .../jshell/tool/ConsoleIOContext.java | 19 +- .../jdk/jshell/SourceCodeAnalysisImpl.java | 262 ++++++++++++++++-- .../jdk/jshell/CompletionSuggestionTest.java | 43 +++ .../jdk/jshell/ToolTabSnippetTest.java | 20 ++ 4 files changed, 323 insertions(+), 21 deletions(-) diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index 5cf301efac5..1662f81710a 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -394,9 +394,9 @@ class ConsoleIOContext extends IOContext { .reduce(ConsoleIOContext::commonPrefix); String prefix = - prefixOpt.orElse("").substring(cursor - anchor[0]); + prefixOpt.orElse(""); - if (!prefix.isEmpty() && !command) { + if (prefix.length() > cursor - anchor[0] && !command) { //the completion will fill in the prefix, which will invalidate //the documentation, avoid adding documentation tasks into the //todo list: @@ -405,6 +405,7 @@ class ConsoleIOContext extends IOContext { ordinaryCompletion = new OrdinaryCompletionTask(ordinaryCompletionToShow, + anchor[0], prefix, !command && !doc.isEmpty(), hasBoth); @@ -609,15 +610,18 @@ class ConsoleIOContext extends IOContext { private final class OrdinaryCompletionTask implements CompletionTask { private final List toShow; + private final int anchor; private final String prefix; private final boolean cont; private final boolean showSmart; public OrdinaryCompletionTask(List toShow, + int anchor, String prefix, boolean cont, boolean showSmart) { this.toShow = toShow; + this.anchor = anchor; this.prefix = prefix; this.cont = cont; this.showSmart = showSmart; @@ -630,7 +634,14 @@ class ConsoleIOContext extends IOContext { @Override public Result perform(String text, int cursor) throws IOException { - in.putString(prefix); + String existingPrefix = in.getBuffer().substring(anchor, cursor); + + if (prefix.startsWith(existingPrefix)) { + in.putString(prefix.substring(existingPrefix.length())); + } else { + in.getBuffer().backspace(existingPrefix.length()); + in.putString(prefix); + } boolean showItems = toShow.size() > 1 || showSmart; @@ -639,7 +650,7 @@ class ConsoleIOContext extends IOContext { printColumns(toShow); } - if (!prefix.isEmpty()) + if (prefix.length() > existingPrefix.length()) return showItems ? Result.FINISH : Result.SKIP_NOREPAINT; return cont ? Result.CONTINUE : Result.FINISH; diff --git a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java index fffdfd5b33c..045734d9f55 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java @@ -38,6 +38,7 @@ import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.ModifiersTree; +import com.sun.source.tree.NewArrayTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Scope; import com.sun.source.tree.Tree; @@ -111,6 +112,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -310,13 +312,19 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { default -> proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code)); }; String[] requiredPrefix = new String[] {identifier}; - return computeSuggestions(codeWrap, cursor, requiredPrefix, anchor).stream() - .filter(s -> s.continuation().startsWith(requiredPrefix[0]) && !s.continuation().equals(REPL_DOESNOTMATTER_CLASS_NAME)) + return computeSuggestions(codeWrap, code, cursor, requiredPrefix, anchor).stream() + .filter(s -> filteringText(s).startsWith(requiredPrefix[0]) && !s.continuation().equals(REPL_DOESNOTMATTER_CLASS_NAME)) .sorted(Comparator.comparing(Suggestion::continuation)) .toList(); } - private List computeSuggestions(OuterWrap code, int cursor, String[] requiredPrefix, int[] anchor) { + private static String filteringText(Suggestion suggestion) { + return suggestion instanceof SuggestionImpl impl + ? impl.filteringText + : suggestion.continuation(); + } + + private List computeSuggestions(OuterWrap code, String inputCode, int cursor, String[] requiredPrefix, int[] anchor) { return proc.taskFactory.analyze(code, at -> { SourcePositions sp = at.trees().getSourcePositions(); CompilationUnitTree topLevel = at.firstCuTree(); @@ -479,6 +487,19 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { addScopeElements(at, scope, IDENTITY, accept, IS_PACKAGE.negate().and(smartTypeFilter), result); break; } + if (isAnnotation(tp)) { + if (getAnnotationAttributeNameOrNull(tp.getParentPath(), true) != null) { + //nested annotation + result = completionSuggestionsImpl(inputCode, cursor - 1, anchor); + requiredPrefix[0] = "@" + requiredPrefix[0]; + return result; + } + + Predicate accept = accessibility.and(STATIC_ONLY) + .and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE)); + addScopeElements(at, scope, IDENTITY, accept, IS_PACKAGE.negate().and(smartTypeFilter), result); + break; + } ImportTree it = findImport(tp); if (it != null) { if (it.isModule()) { @@ -512,6 +533,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { case ERRONEOUS: { boolean staticOnly = ReplResolve.isStatic(((JavacScope)scope).getEnv()); Predicate accept = accessibility.and(staticOnly ? STATIC_ONLY : TRUE); + boolean insertPrimitiveTypes = true; if (isClass(tp)) { ClassTree clazz = (ClassTree) tp.getParentPath().getLeaf(); if (clazz.getExtendsClause() == tp.getLeaf()) { @@ -539,20 +561,101 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { if (var.getType() == tp.getLeaf()) { accept = accept.and(IS_TYPE); } + } else if (tp.getParentPath().getLeaf().getKind() == Kind.ANNOTATION) { + AnnotationTree annotation = (AnnotationTree) tp.getParentPath().getLeaf(); + Element annotationType = at.trees().getElement(tp.getParentPath()); + Set present = annotation.getArguments() + .stream() + .filter(expr -> expr.getKind() == Kind.ASSIGNMENT) + .map(expr -> (AssignmentTree) expr) + .map(assign -> assign.getVariable()) + .filter(var -> var.getKind() == Kind.IDENTIFIER) + .map(var -> ((IdentifierTree) var).getName().toString()) + .collect(Collectors.toSet()); + addElements(ElementFilter.methodsIn(annotationType.getEnclosedElements()), el -> !present.contains(el.getSimpleName().toString()), TRUE, _ -> " = ", result); + break; + } else if (getAnnotationAttributeNameOrNull(tp, true) instanceof String attributeName) { + Element annotationType = tp.getParentPath().getParentPath().getLeaf().getKind() == Kind.ANNOTATION + ? at.trees().getElement(tp.getParentPath().getParentPath()) + : at.trees().getElement(tp.getParentPath().getParentPath().getParentPath()); + if (sp.getEndPosition(topLevel, tp.getParentPath().getLeaf()) == (-1)) { + //synthetic 'value': + addElements(ElementFilter.methodsIn(annotationType.getEnclosedElements()), TRUE, TRUE, _ -> " = ", result); + boolean hasValue = findAnnotationAttributeIfAny(annotationType, "value").isPresent(); + if (!hasValue) { + break; + } + } + Optional ee = findAnnotationAttributeIfAny(annotationType, attributeName); + if (ee.isEmpty()) { + break; + } + TypeMirror relevantAttributeType = ee.orElseThrow().getReturnType(); + if (relevantAttributeType.getKind() == TypeKind.ARRAY) { + relevantAttributeType = ((ArrayType) relevantAttributeType).getComponentType(); + } + if (relevantAttributeType.getKind() == TypeKind.DECLARED && + at.getTypes().asElement(relevantAttributeType) instanceof Element attributeTypeEl) { + if (attributeTypeEl.getKind() == ElementKind.ANNOTATION_TYPE) { + boolean hasAnyAttributes = + ElementFilter.methodsIn(attributeTypeEl.getEnclosedElements()) + .stream() + .anyMatch(attribute -> attribute.getParameters().isEmpty()); + String paren = hasAnyAttributes ? "(" : ""; + String name = scopeContent(at, scope, IDENTITY).contains(attributeTypeEl) + ? attributeTypeEl.getSimpleName().toString() //simple name ought to be enough: + : ((TypeElement) attributeTypeEl).getQualifiedName().toString(); + result.add(new SuggestionImpl("@" + name + paren, true)); + break; + } else if (attributeTypeEl.getKind() == ElementKind.ENUM) { + String typeName = scopeContent(at, scope, IDENTITY).contains(attributeTypeEl) + ? attributeTypeEl.getSimpleName().toString() //simple name ought to be enough: + : ((TypeElement) attributeTypeEl).getQualifiedName().toString(); + result.add(new SuggestionImpl(typeName, true)); + result.addAll(ElementFilter.fieldsIn(attributeTypeEl.getEnclosedElements()) + .stream() + .filter(e -> e.getKind() == ElementKind.ENUM_CONSTANT) + .map(c -> new SuggestionImpl(scopeContent(at, scope, IDENTITY).contains(c) + ? c.getSimpleName().toString() + : typeName + "." + c.getSimpleName(), c.getSimpleName().toString(), + true)) + .toList()); + break; + } + } + accept = accessibility.and(el -> { + return switch (el.getKind()) { + case PACKAGE, ANNOTATION_TYPE, ENUM, INTERFACE, RECORD, ENUM_CONSTANT -> true; + case CLASS -> !((TypeElement) el).asType().getKind().isPrimitive(); + case FIELD -> isPermittedAnnotationAttributeFieldType(at, el.asType()); + default -> false; + }; + }); + insertPrimitiveTypes = false; } addScopeElements(at, scope, IDENTITY, accept, smartFilter, result); - Tree parent = tp.getParentPath().getLeaf(); - accept = switch (parent.getKind()) { - case VARIABLE -> ((VariableTree) parent).getType() == tp.getLeaf() ? - IS_VOID.negate() : - TRUE; - case PARAMETERIZED_TYPE -> FALSE; // TODO: JEP 218: Generics over Primitive Types - case TYPE_PARAMETER, CLASS, INTERFACE, ENUM, RECORD -> FALSE; - default -> TRUE; - }; - addElements(primitivesOrVoid(at), accept, smartFilter, result); + if (insertPrimitiveTypes) { + Tree parent = tp.getParentPath().getLeaf(); + accept = switch (parent.getKind()) { + case VARIABLE -> ((VariableTree) parent).getType() == tp.getLeaf() ? + IS_VOID.negate() : + TRUE; + case PARAMETERIZED_TYPE -> FALSE; // TODO: JEP 218: Generics over Primitive Types + case TYPE_PARAMETER, CLASS, INTERFACE, ENUM, RECORD -> FALSE; + default -> TRUE; + }; + addElements(primitivesOrVoid(at), accept, smartFilter, result); + } + + boolean hasBooleanSmartType = targetTypes != null && + StreamSupport.stream(targetTypes.spliterator(), false) + .anyMatch(tm -> tm.getKind() == TypeKind.BOOLEAN); + if (hasBooleanSmartType) { + result.add(new SuggestionImpl("true", true)); + result.add(new SuggestionImpl("false", true)); + } break; } } @@ -917,6 +1020,12 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { long start = sp.getStartPosition(topLevel, tree); long end = sp.getEndPosition(topLevel, tree); + if (end == (-1) && tree.getKind() == Kind.ASSIGNMENT && + getCurrentPath() != null && + getCurrentPath().getLeaf().getKind() == Kind.ANNOTATION) { + //the assignment is synthetically generated, take the end pos of the nested tree: + end = sp.getEndPosition(topLevel, ((AssignmentTree) tree).getExpression()); + } if (start <= wrapEndPos && wrapEndPos <= end && (deepest[0] == null || deepest[0].getLeaf() == getCurrentPath().getLeaf())) { deepest[0] = new TreePath(getCurrentPath(), tree); @@ -946,6 +1055,12 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { ((MethodTree)parent).getThrows().contains(tp.getLeaf()); } + private boolean isAnnotation(TreePath tp) { + Tree parent = tp.getParentPath().getLeaf(); + return parent.getKind() == Kind.ANNOTATION && + ((AnnotationTree)parent).getAnnotationType().equals(tp.getLeaf()); + } + private boolean isClass(TreePath tp) { return tp.getParentPath() != null && CLASS_KINDS.contains(tp.getParentPath().getLeaf().getKind()); @@ -961,6 +1076,39 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { tp.getParentPath().getLeaf().getKind() == Kind.VARIABLE; } + private String getAnnotationAttributeNameOrNull(TreePath tp, boolean acceptArray) { + if (tp.getParentPath() == null) { + return null; + } + if (tp.getParentPath().getLeaf().getKind() == Kind.NEW_ARRAY && + ((NewArrayTree) tp.getParentPath().getLeaf()).getInitializers().contains(tp.getLeaf())) { + if (acceptArray) { + return getAnnotationAttributeNameOrNull(tp.getParentPath(), false); + } else { + return null; + } + } + if (tp.getParentPath().getParentPath() == null || + tp.getParentPath().getLeaf().getKind() != Kind.ASSIGNMENT || + tp.getParentPath().getParentPath().getLeaf().getKind() != Kind.ANNOTATION) { + return null; + } + AssignmentTree assign = (AssignmentTree) tp.getParentPath().getLeaf(); + if (assign.getVariable().getKind() != Kind.IDENTIFIER) { + return null; + } + return ((IdentifierTree) assign.getVariable()).getName().toString(); + } + + private Optional findAnnotationAttributeIfAny(Element annotationType, + String attributeName) { + return ElementFilter.methodsIn(annotationType.getEnclosedElements()) + .stream() + .filter(ee -> ee.getSimpleName().contentEquals(attributeName)) + .filter(ee -> ee.getParameters().isEmpty()) + .findAny(); + } + private ImportTree findImport(TreePath tp) { while (tp != null && tp.getLeaf().getKind() != Kind.IMPORT) { tp = tp.getParentPath(); @@ -987,6 +1135,17 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { }; } + private boolean isPermittedAnnotationAttributeFieldType(AnalyzeTask at, TypeMirror type) { + if (type.getKind().isPrimitive()) { + return true; + } + if (type.getKind() == TypeKind.DECLARED) { + Element el = ((DeclaredType) type).asElement(); + return el.getKind() == ElementKind.ENUM || el.equals(at.getElements().getTypeElement("java.lang.String")); + } + return false; + } + private final Predicate TRUE = el -> true; private final Predicate FALSE = TRUE.negate(); private final Predicate IS_STATIC = el -> el.getModifiers().contains(Modifier.STATIC); @@ -1237,7 +1396,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { return new VarSymbol(Flags.PUBLIC | Flags.STATIC | Flags.FINAL, _class, classType, erasedSite.tsym); } - private Iterable scopeContent(AnalyzeTask at, Scope scope, Function> elementConvertor) { + private Collection scopeContent(AnalyzeTask at, Scope scope, Function> elementConvertor) { Iterable scopeIterable = () -> new Iterator() { private Scope currentScope = scope; @Override @@ -1306,11 +1465,54 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { Tree current = forPath.getLeaf(); + if (current.getKind() == Kind.ANNOTATION) { + Element type = at.trees().getElement(forPath); + if (type != null) { + Optional valueAttr = + ElementFilter.methodsIn(type.getEnclosedElements()) + .stream() + .filter(ee -> ee.getSimpleName().contentEquals("value")) + .findAny(); + if (valueAttr.isPresent()) { + TypeMirror returnType = valueAttr.orElseThrow().getReturnType(); + + if (returnType.getKind() == TypeKind.ARRAY) { + returnType = ((ArrayType) returnType).getComponentType(); + } + + return Collections.singletonList(returnType); + } + } + } + switch (forPath.getParentPath().getLeaf().getKind()) { + case NEW_ARRAY: + if (getAnnotationAttributeNameOrNull(forPath, true) != null) { + forPath = forPath.getParentPath(); + current = forPath.getLeaf(); + //fall-through + } else { + break; + } case ASSIGNMENT: { AssignmentTree tree = (AssignmentTree) forPath.getParentPath().getLeaf(); - if (tree.getExpression() == current) - return Collections.singletonList(at.trees().getTypeMirror(new TreePath(forPath.getParentPath(), tree.getVariable()))); + if (tree.getExpression() == current) { + if (forPath.getParentPath().getParentPath().getLeaf().getKind() == Kind.ANNOTATION) { + Element method = at.trees().getElement(new TreePath(forPath.getParentPath(), tree.getVariable())); + if (method != null && method.getKind() == ElementKind.METHOD) { + TypeMirror returnType = ((ExecutableElement) method).getReturnType(); + + if (returnType.getKind() == TypeKind.ARRAY) { + returnType = ((ArrayType) returnType).getComponentType(); + } + + return Collections.singletonList(returnType); + } + return null; + } else { + return Collections.singletonList(at.trees().getTypeMirror(new TreePath(forPath.getParentPath(), tree.getVariable()))); + } + } break; } case VARIABLE: { @@ -1558,7 +1760,8 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { TreePath prevPath = null; while (tp != null && tp.getLeaf().getKind() != Kind.METHOD_INVOCATION && tp.getLeaf().getKind() != Kind.NEW_CLASS && tp.getLeaf().getKind() != Kind.IDENTIFIER && - tp.getLeaf().getKind() != Kind.MEMBER_SELECT) { + tp.getLeaf().getKind() != Kind.MEMBER_SELECT && + tp.getLeaf().getKind() != Kind.ANNOTATION) { prevPath = tp; tp = tp.getParentPath(); } @@ -1611,6 +1814,18 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { } elements = Stream.of(el); + } else if (tp.getLeaf().getKind() == Kind.ANNOTATION) { + Element el = at.trees().getElement(tp); + + if (el == null || + el.getKind() != ElementKind.ANNOTATION_TYPE) { + //erroneous state: + return Collections.emptyList(); + } + + elements = ElementFilter.methodsIn(el.getEnclosedElements()) + .stream() + .map(ee -> (Element) ee); } else { return Collections.emptyList(); } @@ -2220,6 +2435,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { private static class SuggestionImpl implements Suggestion { private final String continuation; + private final String filteringText; private final boolean matchesType; /** @@ -2229,7 +2445,19 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { * @param matchesType does the candidate match the target type */ public SuggestionImpl(String continuation, boolean matchesType) { + this(continuation, continuation, matchesType); + } + + /** + * Create a {@code Suggestion} instance. + * + * @param continuation a candidate continuation of the user's input + * @param filteringText a text that should be used for filtering + * @param matchesType does the candidate match the target type + */ + public SuggestionImpl(String continuation, String filteringText, boolean matchesType) { this.continuation = continuation; + this.filteringText = filteringText; this.matchesType = matchesType; } diff --git a/test/langtools/jdk/jshell/CompletionSuggestionTest.java b/test/langtools/jdk/jshell/CompletionSuggestionTest.java index a710f60aec4..19f7b89a1b3 100644 --- a/test/langtools/jdk/jshell/CompletionSuggestionTest.java +++ b/test/langtools/jdk/jshell/CompletionSuggestionTest.java @@ -898,4 +898,47 @@ public class CompletionSuggestionTest extends KullaTesting { assertCompletion("p1.|", "p2.", "p3."); } + + @Test + public void testAnnotation() { + assertCompletion("@Deprec|", "Deprecated"); + assertCompletion("@Deprecated(|", "forRemoval = ", "since = "); + assertCompletion("@Deprecated(forRemoval = |", true, "false", "true"); + assertCompletion("@Deprecated(forRemoval = true, |", "since = "); + assertEval("import java.lang.constant.ConstantDescs;"); + assertEval("import static java.lang.constant.ConstantDescs.*;"); + assertEval("@interface Ann1 { public String test(); }"); + assertCompletionIncludesExcludes("@Ann1(test = |", Set.of("java.", "ConstantDescs", "INIT_NAME"), Set.of("CD_char", "byte")); + assertEval("@interface Ann2 { public String[] test(); }"); + assertCompletionIncludesExcludes("@Ann2(test = {|", Set.of("java.", "ConstantDescs", "INIT_NAME"), Set.of("CD_char", "byte")); + assertCompletionIncludesExcludes("@Ann2(test = {|", true, Set.of("INIT_NAME"), Set.of("java.", "ConstantDescs", "CD_char", "byte")); + assertEval("@interface Ann3 { public String value(); }"); + assertCompletionIncludesExcludes("@Ann3(|", Set.of("java.", "ConstantDescs", "INIT_NAME", "value = "), Set.of("CD_char", "byte")); + assertCompletionIncludesExcludes("@Ann3(|", true, Set.of("INIT_NAME", "value = "), Set.of("java.", "ConstantDescs", "CD_char", "byte")); + assertSignature("@Deprecated(|", "boolean Deprecated.forRemoval()", "String Deprecated.since()"); + assertEval("@interface Ann4 { public String[] value(); }"); + assertCompletionIncludesExcludes("@Ann4({|", Set.of("java.", "ConstantDescs", "INIT_NAME"), Set.of("value = ")); + assertEval("@interface Ann5 { public Ann4[] value(); }"); + assertCompletion("@Ann5(|", true, "@Ann4(", "value = "); + assertCompletion("@Ann5({|", true, "@Ann4("); + assertCompletion("@Ann5(|", false); + assertCompletion("@Ann5({|", false); + assertCompletion("@Ann5(@|", true, "@Ann4("); + assertCompletion("@Ann5(v|", true, "value = "); + assertEval("@interface Ann6 { public java.lang.annotation.Retention[] value(); }"); + assertCompletion("@Ann6(|", true, "@java.lang.annotation.Retention(", "value = "); + assertEval("@interface Ann7 { }"); //no attributes + assertEval("@interface Ann8 { public Ann7[] value(); }"); + assertCompletion("@Ann8(|", true, "@Ann7", "value = "); + assertEval("enum En { AA, BB, EE; }"); + assertEval("@interface Ann9 { public En[] value(); }"); + assertCompletion("@Ann9(|", true, "En", "En.AA", "En.BB", "En.EE", "value = "); + assertCompletion("@Ann9(A|", true, "En.AA"); + assertCompletion("@Ann9(E|", true, "En", "En.EE"); + assertCompletionIncludesExcludes("@Ann9(En.|", Set.of("AA", "BB", "EE"), Set.of()); + assertEval("@interface AnnA { public java.lang.annotation.RetentionPolicy[] value(); }"); + assertCompletion("@AnnA(C|", true, "java.lang.annotation.RetentionPolicy.CLASS"); + assertEval("import static java.lang.annotation.RetentionPolicy.*;"); + assertCompletion("@AnnA(C|", true, "CLASS"); + } } diff --git a/test/langtools/jdk/jshell/ToolTabSnippetTest.java b/test/langtools/jdk/jshell/ToolTabSnippetTest.java index 39189da8686..968935b0814 100644 --- a/test/langtools/jdk/jshell/ToolTabSnippetTest.java +++ b/test/langtools/jdk/jshell/ToolTabSnippetTest.java @@ -344,4 +344,24 @@ public class ToolTabSnippetTest extends UITesting { waitOutput(out, PROMPT + "new InstantiationE"); }); } + + @Test + public void testAnnotation() throws Exception { + doRunTest((inputSink, out) -> { + inputSink.write("@interface Ann1 { public java.lang.annotation.Retention[] value(); }\n"); + waitOutput(out, "\n\\u001B\\[\\?2004h" + PROMPT); + + //-> + inputSink.write("@Ann1(" + TAB); + waitOutput(out, ".*@java.lang.annotation.Retention\\(.*value =.*" + + REDRAW_PROMPT + "@Ann1\\("); + inputSink.write("@" + TAB); + waitOutput(out, "^@java.lang.annotation.Retention\\("); + inputSink.write(TAB); + waitOutput(out, ".*java.lang.annotation.RetentionPolicy.*java.lang.annotation.RetentionPolicy.CLASS.*" + + REDRAW_PROMPT + "@Ann1\\(@java.lang.annotation.Retention\\("); + inputSink.write("CL" + TAB); + waitOutput(out, "CL\\u001B\\[2Djava.lang.annotation.RetentionPolicy.CLASS \\u0008"); + }); + } } From 063f970f0f5e851d72dad0112735692761d6ba36 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Thu, 11 Sep 2025 11:22:12 +0000 Subject: [PATCH 042/120] 8367401: Parallel: Remove unused field in PSKeepAliveClosure Reviewed-by: stefank, fandreuzzi --- src/hotspot/share/gc/parallel/psScavenge.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 3a47d5864f3..ced84061ec5 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -148,15 +148,10 @@ public: PSIsAliveClosure PSScavenge::_is_alive_closure; class PSKeepAliveClosure: public OopClosure { -protected: - MutableSpace* _to_space; PSPromotionManager* _promotion_manager; public: PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) { - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - _to_space = heap->young_gen()->to_space(); - assert(_promotion_manager != nullptr, "Sanity"); } From a2d272a02a079e2413d10ad2decb04681ce2f961 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Thu, 11 Sep 2025 11:22:29 +0000 Subject: [PATCH 043/120] 8367339: Parallel: Remove PSScavenge::should_scavenge Reviewed-by: tschatzl, fandreuzzi --- src/hotspot/share/gc/parallel/psCardTable.cpp | 1 - .../share/gc/parallel/psClosure.inline.hpp | 16 ++--- .../share/gc/parallel/psPromotionManager.cpp | 11 +--- .../share/gc/parallel/psPromotionManager.hpp | 3 - .../gc/parallel/psPromotionManager.inline.hpp | 8 +-- src/hotspot/share/gc/parallel/psScavenge.cpp | 2 +- src/hotspot/share/gc/parallel/psScavenge.hpp | 9 --- .../share/gc/parallel/psScavenge.inline.hpp | 63 ------------------- 8 files changed, 13 insertions(+), 100 deletions(-) delete mode 100644 src/hotspot/share/gc/parallel/psScavenge.inline.hpp diff --git a/src/hotspot/share/gc/parallel/psCardTable.cpp b/src/hotspot/share/gc/parallel/psCardTable.cpp index 22a38d816f6..3c40726b721 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.cpp +++ b/src/hotspot/share/gc/parallel/psCardTable.cpp @@ -26,7 +26,6 @@ #include "gc/parallel/parallelScavengeHeap.inline.hpp" #include "gc/parallel/psCardTable.hpp" #include "gc/parallel/psPromotionManager.inline.hpp" -#include "gc/parallel/psScavenge.inline.hpp" #include "gc/parallel/psYoungGen.hpp" #include "memory/iterator.inline.hpp" #include "oops/access.inline.hpp" diff --git a/src/hotspot/share/gc/parallel/psClosure.inline.hpp b/src/hotspot/share/gc/parallel/psClosure.inline.hpp index 914a16e77a6..825612d598a 100644 --- a/src/hotspot/share/gc/parallel/psClosure.inline.hpp +++ b/src/hotspot/share/gc/parallel/psClosure.inline.hpp @@ -28,7 +28,7 @@ // No psClosure.hpp #include "gc/parallel/psPromotionManager.inline.hpp" -#include "gc/parallel/psScavenge.inline.hpp" +#include "gc/parallel/psScavenge.hpp" #include "memory/iterator.hpp" #include "oops/access.inline.hpp" #include "oops/oop.inline.hpp" @@ -39,8 +39,9 @@ public: virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } virtual void do_oop(oop* p) { - if (PSScavenge::should_scavenge(p)) { - oop o = RawAccess::oop_load(p); + oop o = RawAccess<>::oop_load(p); + if (PSScavenge::is_obj_in_young(o)) { + assert(!PSScavenge::is_obj_in_to_space(o), "Revisiting roots?"); assert(o->is_forwarded(), "Objects are already forwarded before weak processing"); oop new_obj = o->forwardee(); if (log_develop_is_enabled(Trace, gc, scavenge)) { @@ -89,12 +90,11 @@ public: void do_oop(narrowOop* p) { ShouldNotReachHere(); } void do_oop(oop* p) { - ParallelScavengeHeap* psh = ParallelScavengeHeap::heap(); - assert(!psh->is_in_reserved(p), "GC barrier needed"); - if (PSScavenge::should_scavenge(p)) { - assert(PSScavenge::should_scavenge(p, true), "revisiting object?"); + assert(!ParallelScavengeHeap::heap()->is_in_reserved(p), "GC barrier needed"); - oop o = RawAccess::oop_load(p); + oop o = RawAccess<>::oop_load(p); + if (PSScavenge::is_obj_in_young(o)) { + assert(!PSScavenge::is_obj_in_to_space(o), "Revisiting roots?"); oop new_obj = _pm->copy_to_survivor_space(o); RawAccess::oop_store(p, new_obj); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index 0a463ab7516..90914d87ba4 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -27,7 +27,7 @@ #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/psOldGen.hpp" #include "gc/parallel/psPromotionManager.inline.hpp" -#include "gc/parallel/psScavenge.inline.hpp" +#include "gc/parallel/psScavenge.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" #include "gc/shared/gcTrace.hpp" #include "gc/shared/partialArraySplitter.inline.hpp" @@ -86,15 +86,6 @@ void PSPromotionManager::initialize() { } } -// Helper functions to get around the circular dependency between -// psScavenge.inline.hpp and psPromotionManager.inline.hpp. -bool PSPromotionManager::should_scavenge(oop* p, bool check_to_space) { - return PSScavenge::should_scavenge(p, check_to_space); -} -bool PSPromotionManager::should_scavenge(narrowOop* p, bool check_to_space) { - return PSScavenge::should_scavenge(p, check_to_space); -} - PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(uint index) { assert(index < ParallelGCThreads, "index out of range"); assert(_manager_array != nullptr, "Sanity"); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.hpp index f1169c8ad63..20fe3c74a46 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.hpp @@ -167,9 +167,6 @@ class PSPromotionManager { inline void process_popped_location_depth(ScannerTask task, bool stolen); - static bool should_scavenge(oop* p, bool check_to_space = false); - static bool should_scavenge(narrowOop* p, bool check_to_space = false); - template void copy_and_push_safe_barrier(T* p); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp index 6154abf1b1c..31c1c445a32 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp @@ -31,7 +31,7 @@ #include "gc/parallel/parMarkBitMap.inline.hpp" #include "gc/parallel/psOldGen.hpp" #include "gc/parallel/psPromotionLAB.inline.hpp" -#include "gc/parallel/psScavenge.inline.hpp" +#include "gc/parallel/psScavenge.hpp" #include "gc/parallel/psStringDedup.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" #include "gc/shared/taskqueue.inline.hpp" @@ -139,7 +139,8 @@ inline void PSPromotionManager::push_contents_bounded(oop obj, HeapWord* left, H template inline oop PSPromotionManager::copy_to_survivor_space(oop o) { - assert(should_scavenge(&o), "Sanity"); + assert(PSScavenge::is_obj_in_young(o), "precondition"); + assert(!PSScavenge::is_obj_in_to_space(o), "precondition"); // NOTE! We must be very careful with any methods that access the mark // in o. There may be multiple threads racing on it, and it may be forwarded @@ -235,8 +236,6 @@ inline HeapWord* PSPromotionManager::allocate_in_old_gen(Klass* klass, template inline oop PSPromotionManager::copy_unmarked_to_survivor_space(oop o, markWord test_mark) { - assert(should_scavenge(&o), "Sanity"); - oop new_obj = nullptr; bool new_obj_is_tenured = false; @@ -334,7 +333,6 @@ inline oop PSPromotionManager::copy_unmarked_to_survivor_space(oop o, template inline void PSPromotionManager::copy_and_push_safe_barrier(T* p) { assert(ParallelScavengeHeap::heap()->is_in_reserved(p), "precondition"); - assert(should_scavenge(p, true), "revisiting object?"); oop o = RawAccess::oop_load(p); oop new_obj = copy_to_survivor_space(o); diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index ced84061ec5..62d382b40f0 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -33,7 +33,7 @@ #include "gc/parallel/psParallelCompact.inline.hpp" #include "gc/parallel/psPromotionManager.inline.hpp" #include "gc/parallel/psRootType.hpp" -#include "gc/parallel/psScavenge.inline.hpp" +#include "gc/parallel/psScavenge.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcId.hpp" diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp index 8da555a8bb4..c297a46a46e 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.hpp +++ b/src/hotspot/share/gc/parallel/psScavenge.hpp @@ -100,15 +100,6 @@ class PSScavenge: AllStatic { // Return true iff a young-gc is completed without promotion-failure. static bool invoke(bool clear_soft_refs); - template static inline bool should_scavenge(T* p); - - // These call should_scavenge() above and, if it returns true, also check that - // the object was not newly copied into to_space. The version with the bool - // argument is a convenience wrapper that fetches the to_space pointer from - // the heap and calls the other version (if the arg is true). - template static inline bool should_scavenge(T* p, MutableSpace* to_space); - template static inline bool should_scavenge(T* p, bool check_to_space); - // Is an object in the young generation // This assumes that the 'o' is in the heap, // so it only checks one side of the complete predicate. diff --git a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp b/src/hotspot/share/gc/parallel/psScavenge.inline.hpp deleted file mode 100644 index af3ff4c6165..00000000000 --- a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_PSSCAVENGE_INLINE_HPP -#define SHARE_GC_PARALLEL_PSSCAVENGE_INLINE_HPP - -#include "gc/parallel/psScavenge.hpp" - -#include "gc/parallel/parallelScavengeHeap.hpp" -#include "logging/log.hpp" -#include "memory/iterator.hpp" -#include "memory/resourceArea.hpp" -#include "oops/access.inline.hpp" -#include "oops/oop.inline.hpp" -#include "utilities/globalDefinitions.hpp" - -template inline bool PSScavenge::should_scavenge(T* p) { - T heap_oop = RawAccess<>::oop_load(p); - return PSScavenge::is_obj_in_young(heap_oop); -} - -template -inline bool PSScavenge::should_scavenge(T* p, MutableSpace* to_space) { - if (should_scavenge(p)) { - oop obj = RawAccess::oop_load(p); - // Skip objects copied to to_space since the scavenge started. - HeapWord* const addr = cast_from_oop(obj); - return addr < to_space->bottom() || addr >= to_space->end(); - } - return false; -} - -template -inline bool PSScavenge::should_scavenge(T* p, bool check_to_space) { - if (check_to_space) { - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - return should_scavenge(p, heap->young_gen()->to_space()); - } - return should_scavenge(p); -} - -#endif // SHARE_GC_PARALLEL_PSSCAVENGE_INLINE_HPP From 56f2f7a3af0574357d5d3f99dcd908721ac710e9 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Thu, 11 Sep 2025 13:22:20 +0000 Subject: [PATCH 044/120] 8367138: JNI exception pending in os_getCmdlineAndUserInfo of ProcessHandleImpl_macosx.c Reviewed-by: bpb, naoto, jpai, lancea --- src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c b/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c index 9e1d092c57d..2db64ef37b5 100644 --- a/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c +++ b/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -263,6 +263,7 @@ void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { // on other platforms like Linux/Solaris/AIX where the uid comes from the // same source like the command line info. unix_getUserInfo(env, jinfo, getUID(pid)); + JNU_CHECK_EXCEPTION(env); // Get the maximum size of the arguments mib[0] = CTL_KERN; From 4ea8979b93f80e9ecbc197ee12ceb523ef8da6aa Mon Sep 17 00:00:00 2001 From: Artur Barashev Date: Thu, 11 Sep 2025 13:53:08 +0000 Subject: [PATCH 045/120] 8365953: Key manager returns no certificates when handshakeSession is not an ExtendedSSLSession Reviewed-by: djelinski, wetmore --- .../ssl/X509KeyManagerCertChecking.java | 47 +- .../AlgorithmConstraintsCheck.java | 28 +- ...xtendedSSLSessionAlgorithmConstraints.java | 405 ++++++++++++++++++ 3 files changed, 436 insertions(+), 44 deletions(-) create mode 100644 test/jdk/sun/security/ssl/X509KeyManager/NonExtendedSSLSessionAlgorithmConstraints.java diff --git a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerCertChecking.java b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerCertChecking.java index 00a7ae84352..6f18b80395a 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerCertChecking.java +++ b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerCertChecking.java @@ -167,25 +167,17 @@ abstract class X509KeyManagerCertChecking extends X509ExtendedKeyManager { return null; } - if (socket != null && socket.isConnected() && - socket instanceof SSLSocket sslSocket) { - + if (socket instanceof SSLSocket sslSocket && sslSocket.isConnected()) { SSLSession session = sslSocket.getHandshakeSession(); - if (session != null) { - if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) { - String[] peerSupportedSignAlgs = null; - - if (session instanceof ExtendedSSLSession extSession) { - // Peer supported certificate signature algorithms - // sent with "signature_algorithms_cert" TLS extension. - peerSupportedSignAlgs = - extSession.getPeerSupportedSignatureAlgorithms(); - } - - return SSLAlgorithmConstraints.forSocket( - sslSocket, peerSupportedSignAlgs, true); - } + if (session instanceof ExtendedSSLSession extSession + && ProtocolVersion.useTLS12PlusSpec( + extSession.getProtocol())) { + // Use peer supported certificate signature algorithms + // sent with "signature_algorithms_cert" TLS extension. + return SSLAlgorithmConstraints.forSocket(sslSocket, + extSession.getPeerSupportedSignatureAlgorithms(), + true); } return SSLAlgorithmConstraints.forSocket(sslSocket, true); @@ -203,20 +195,15 @@ abstract class X509KeyManagerCertChecking extends X509ExtendedKeyManager { if (engine != null) { SSLSession session = engine.getHandshakeSession(); - if (session != null) { - if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) { - String[] peerSupportedSignAlgs = null; - if (session instanceof ExtendedSSLSession extSession) { - // Peer supported certificate signature algorithms - // sent with "signature_algorithms_cert" TLS extension. - peerSupportedSignAlgs = - extSession.getPeerSupportedSignatureAlgorithms(); - } - - return SSLAlgorithmConstraints.forEngine( - engine, peerSupportedSignAlgs, true); - } + if (session instanceof ExtendedSSLSession extSession + && ProtocolVersion.useTLS12PlusSpec( + extSession.getProtocol())) { + // Use peer supported certificate signature algorithms + // sent with "signature_algorithms_cert" TLS extension. + return SSLAlgorithmConstraints.forEngine(engine, + extSession.getPeerSupportedSignatureAlgorithms(), + true); } } diff --git a/test/jdk/sun/security/ssl/X509KeyManager/AlgorithmConstraintsCheck.java b/test/jdk/sun/security/ssl/X509KeyManager/AlgorithmConstraintsCheck.java index 997fde5a07a..4caa7b6b944 100644 --- a/test/jdk/sun/security/ssl/X509KeyManager/AlgorithmConstraintsCheck.java +++ b/test/jdk/sun/security/ssl/X509KeyManager/AlgorithmConstraintsCheck.java @@ -57,31 +57,31 @@ import sun.security.x509.X500Name; * @modules java.base/sun.security.x509 * java.base/sun.security.util * @library /test/lib - * @run main/othervm AlgorithmConstraintsCheck false SunX509 SHA256withRSA - * @run main/othervm AlgorithmConstraintsCheck true SunX509 SHA256withRSA - * @run main/othervm AlgorithmConstraintsCheck false PKIX SHA256withRSA - * @run main/othervm AlgorithmConstraintsCheck true PKIX SHA256withRSA + * @run main/othervm AlgorithmConstraintsCheck false SunX509 + * @run main/othervm AlgorithmConstraintsCheck true SunX509 + * @run main/othervm AlgorithmConstraintsCheck false PKIX + * @run main/othervm AlgorithmConstraintsCheck true PKIX */ public class AlgorithmConstraintsCheck { - private static final String CERT_ALIAS = "testalias"; - private static final String KEY_TYPE = "RSA"; + protected static final String CERT_ALIAS = "testalias"; + protected static final String KEY_TYPE = "EC"; + protected static final String CERT_SIG_ALG = "SHA256withECDSA"; public static void main(String[] args) throws Exception { - if (args.length != 3) { + if (args.length != 2) { throw new RuntimeException("Wrong number of arguments"); } String enabled = args[0]; String kmAlg = args[1]; - String certSignatureAlg = args[2]; System.setProperty("jdk.tls.SunX509KeyManager.certChecking", enabled); - SecurityUtils.addToDisabledTlsAlgs(certSignatureAlg); + SecurityUtils.addToDisabledTlsAlgs(CERT_SIG_ALG); X509ExtendedKeyManager km = (X509ExtendedKeyManager) getKeyManager( - kmAlg, certSignatureAlg); + kmAlg, KEY_TYPE, CERT_SIG_ALG); String serverAlias = km.chooseServerAlias(KEY_TYPE, null, null); String engineServerAlias = km.chooseEngineServerAlias( KEY_TYPE, null, null); @@ -108,13 +108,13 @@ public class AlgorithmConstraintsCheck { } // PKIX KeyManager adds a cache prefix to an alias. - private static String normalizeAlias(String alias) { + protected static String normalizeAlias(String alias) { return alias.substring(alias.lastIndexOf(".") + 1); } - private static X509KeyManager getKeyManager(String kmAlg, - String certSignatureAlg) throws Exception { - KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_TYPE); + protected static X509KeyManager getKeyManager(String kmAlg, + String keyAlg, String certSignatureAlg) throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlg); KeyPair caKeys = kpg.generateKeyPair(); KeyPair endpointKeys = kpg.generateKeyPair(); diff --git a/test/jdk/sun/security/ssl/X509KeyManager/NonExtendedSSLSessionAlgorithmConstraints.java b/test/jdk/sun/security/ssl/X509KeyManager/NonExtendedSSLSessionAlgorithmConstraints.java new file mode 100644 index 00000000000..30ec655f7b2 --- /dev/null +++ b/test/jdk/sun/security/ssl/X509KeyManager/NonExtendedSSLSessionAlgorithmConstraints.java @@ -0,0 +1,405 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8365953 + * @summary Key manager returns no certificates when handshakeSession is not + * an ExtendedSSLSession + * @modules java.base/sun.security.x509 + * java.base/sun.security.util + * @library /test/lib + * @run main/othervm NonExtendedSSLSessionAlgorithmConstraints + */ + +import static jdk.test.lib.Asserts.assertEquals; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.security.Principal; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSessionContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.X509ExtendedKeyManager; + +/* + * Make sure Key Managers return the certificates when SSLSocket or SSLEngine + * use an SSLSession which is not extending ExtendedSSLSession. + */ +public class NonExtendedSSLSessionAlgorithmConstraints extends + AlgorithmConstraintsCheck { + + public static void main(String[] args) throws Exception { + new NonExtendedSSLSessionAlgorithmConstraints().runTest(); + } + + private void runTest() throws Exception { + for (String kmAlg : new String[]{"SunX509", "PKIX"}) { + + X509ExtendedKeyManager km = + (X509ExtendedKeyManager) getKeyManager( + kmAlg, KEY_TYPE, CERT_SIG_ALG); + var testSocket = new TestHandshakeSessionSSLSocket(); + var testEngine = new TestHandshakeSessionSSLEngine(); + + // Test SSLSocket + assertEquals(CERT_ALIAS, normalizeAlias(km.chooseServerAlias( + KEY_TYPE, null, testSocket))); + assertEquals(CERT_ALIAS, normalizeAlias(km.chooseClientAlias( + new String[]{KEY_TYPE}, null, testSocket))); + + // Test SSLEngine + assertEquals(CERT_ALIAS, normalizeAlias(km.chooseEngineServerAlias( + KEY_TYPE, null, testEngine))); + assertEquals(CERT_ALIAS, normalizeAlias(km.chooseEngineClientAlias( + new String[]{KEY_TYPE}, null, testEngine))); + } + } + + private static class TestHandshakeSessionSSLSocket extends SSLSocket { + + TestHandshakeSessionSSLSocket() { + } + + @Override + public SSLSession getHandshakeSession() { + return new TestSSLSession(); + } + + @Override + public boolean isConnected() { + return true; + } + + @Override + public SSLSession getSession() { + return null; + } + + @Override + public String[] getSupportedCipherSuites() { + return null; + } + + @Override + public String[] getSupportedProtocols() { + return null; + } + + @Override + public String[] getEnabledCipherSuites() { + return null; + } + + @Override + public void setEnabledCipherSuites(String[] suites) { + } + + @Override + public String[] getEnabledProtocols() { + return null; + } + + @Override + public void setEnabledProtocols(String[] protocols) { + } + + @Override + public void addHandshakeCompletedListener + (HandshakeCompletedListener listener) { + } + + @Override + public void removeHandshakeCompletedListener + (HandshakeCompletedListener listener) { + } + + @Override + public void startHandshake() throws IOException { + } + + @Override + public void setUseClientMode(boolean mode) { + } + + @Override + public boolean getUseClientMode() { + return false; + } + + @Override + public void setNeedClientAuth(boolean need) { + } + + @Override + public boolean getNeedClientAuth() { + return false; + } + + @Override + public void setWantClientAuth(boolean want) { + } + + @Override + public boolean getWantClientAuth() { + return false; + } + + @Override + public void setEnableSessionCreation(boolean flag) { + } + + @Override + public boolean getEnableSessionCreation() { + return true; + } + } + + private static class TestHandshakeSessionSSLEngine extends SSLEngine { + + @Override + public SSLSession getHandshakeSession() { + return new TestSSLSession(); + } + + @Override + public String[] getEnabledProtocols() { + return null; + } + + @Override + public SSLEngineResult wrap(ByteBuffer[] src, int off, int len, + ByteBuffer dst) throws SSLException { + return null; + } + + @Override + public SSLEngineResult unwrap(ByteBuffer src, + ByteBuffer[] dst, int off, int len) + throws SSLException { + return null; + } + + @Override + public Runnable getDelegatedTask() { + return null; + } + + @Override + public void closeInbound() { + } + + @Override + public boolean isInboundDone() { + return false; + } + + @Override + public void closeOutbound() { + } + + @Override + public boolean isOutboundDone() { + return false; + } + + @Override + public String[] getEnabledCipherSuites() { + return null; + } + + @Override + public String[] getSupportedCipherSuites() { + return null; + } + + @Override + public void setEnabledCipherSuites(String[] suites) { + } + + @Override + public String[] getSupportedProtocols() { + return null; + } + + @Override + public void setEnabledProtocols(String[] protocols) { + } + + @Override + public SSLSession getSession() { + return null; + } + + @Override + public void beginHandshake() { + } + + @Override + public SSLEngineResult.HandshakeStatus getHandshakeStatus() { + return null; + } + + @Override + public void setUseClientMode(boolean mode) { + } + + @Override + public boolean getUseClientMode() { + return false; + } + + public void setNeedClientAuth(boolean need) { + } + + @Override + public boolean getNeedClientAuth() { + return false; + } + + @Override + public void setWantClientAuth(boolean need) { + } + + @Override + public boolean getWantClientAuth() { + return false; + } + + @Override + public void setEnableSessionCreation(boolean flag) { + } + + @Override + public boolean getEnableSessionCreation() { + return false; + } + } + + public static class TestSSLSession implements SSLSession { + + TestSSLSession() { + } + + @Override + public String getProtocol() { + return "TLSv1.3"; + } + + @Override + public byte[] getId() { + return null; + } + + @Override + public SSLSessionContext getSessionContext() { + return null; + } + + @Override + public long getCreationTime() { + return 0; + } + + @Override + public long getLastAccessedTime() { + return 0; + } + + @Override + public void invalidate() { + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public void putValue(String name, Object value) { + } + + @Override + public Object getValue(String name) { + return null; + } + + @Override + public void removeValue(String name) { + } + + @Override + public String[] getValueNames() { + return null; + } + + @Override + public java.security.cert.Certificate[] getPeerCertificates() { + return new java.security.cert.Certificate[0]; + } + + @Override + public java.security.cert.Certificate[] getLocalCertificates() { + return new java.security.cert.Certificate[0]; + } + + @Override + public Principal getPeerPrincipal() { + return null; + } + + @Override + public Principal getLocalPrincipal() { + return null; + } + + @Override + public String getCipherSuite() { + return null; + } + + @Override + public String getPeerHost() { + return null; + } + + @Override + public int getPeerPort() { + return 0; + } + + @Override + public int getPacketBufferSize() { + return 0; + } + + @Override + public int getApplicationBufferSize() { + return 0; + } + } +} From 781f2b2f8188c02a6af220ebcc5bc8158fe8423e Mon Sep 17 00:00:00 2001 From: Pasam Soujanya Date: Thu, 11 Sep 2025 13:58:51 +0000 Subject: [PATCH 046/120] 8366278: Form control element + + + """; + Document doc = kit.createDefaultDocument(); + editorPane.setDocument(doc); + editorPane.setText(htmlString); + + frame.add(scrollPane, BorderLayout.CENTER); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(new Dimension(400, 200)); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static boolean containsAlt(Container container) { + for (Component c : container.getComponents()) { + if (c instanceof JButton button) { + return "Logo".equals(button.getText()); + } else if (c instanceof Container cont) { + return containsAlt(cont); + } + } + return false; + } +} From 64155dfac068cf01bcab6adb401b360499f33a5f Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Mon, 15 Sep 2025 21:10:26 +0000 Subject: [PATCH 089/120] 8367237: Thread-Safety Usage Warning for java.text.Collator Classes Reviewed-by: iris, naoto --- src/java.base/share/classes/java/text/Collator.java | 9 +++++++-- .../share/classes/java/text/RuleBasedCollator.java | 11 ++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/java/text/Collator.java b/src/java.base/share/classes/java/text/Collator.java index 276a66cdc07..5e576cd800f 100644 --- a/src/java.base/share/classes/java/text/Collator.java +++ b/src/java.base/share/classes/java/text/Collator.java @@ -111,8 +111,13 @@ import sun.util.locale.provider.LocaleServiceProviderPool; *
      * @apiNote {@code CollationKey}s from different * {@code Collator}s can not be compared. See the class description - * for {@link CollationKey} - * for an example using {@code CollationKey}s. + * for {@link CollationKey} for an example using {@code CollationKey}s. + * + * @implNote Significant thread contention may occur during concurrent usage + * of the JDK Reference Implementation's {@link RuleBasedCollator}, which is the + * subtype returned by the default provider of the {@link #getInstance()} factory + * methods. As such, users should consider retrieving a separate instance for + * each thread when used in multithreaded environments. * * @see RuleBasedCollator * @see CollationKey diff --git a/src/java.base/share/classes/java/text/RuleBasedCollator.java b/src/java.base/share/classes/java/text/RuleBasedCollator.java index dc45dafb846..af1b6b62bdf 100644 --- a/src/java.base/share/classes/java/text/RuleBasedCollator.java +++ b/src/java.base/share/classes/java/text/RuleBasedCollator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, 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 @@ -38,10 +38,6 @@ package java.text; -import java.text.Normalizer; -import java.util.Vector; -import java.util.Locale; - /** * The {@code RuleBasedCollator} class is a concrete subclass of * {@code Collator} that provides a simple, data-driven, table @@ -239,6 +235,11 @@ import java.util.Locale; * * * + * @implNote For this implementation, concurrent usage of this class may + * lead to significant thread contention since {@code synchronized} is employed + * to ensure thread-safety. As such, users of this class should consider creating + * a separate instance for each thread when used in multithreaded environments. + * * @see Collator * @see CollationElementIterator * @author Helena Shih, Laura Werner, Richard Gillam From 242558484985cb954b0e658776fd59cbca1be1db Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Tue, 16 Sep 2025 01:04:48 +0000 Subject: [PATCH 090/120] 8367142: Avoid InstanceKlass::cast when converting java mirror to InstanceKlass Reviewed-by: dholmes, coleenp --- src/hotspot/share/cds/aotMetaspace.cpp | 4 +- src/hotspot/share/cds/unregisteredClasses.cpp | 2 +- src/hotspot/share/classfile/javaClasses.cpp | 27 +++--- src/hotspot/share/classfile/javaClasses.hpp | 12 +-- .../share/classfile/javaClasses.inline.hpp | 6 ++ .../share/classfile/systemDictionary.cpp | 4 +- .../jfr/leakprofiler/chains/edgeUtils.cpp | 2 +- src/hotspot/share/jvmci/jvmciRuntime.cpp | 2 +- src/hotspot/share/prims/jni.cpp | 2 +- src/hotspot/share/prims/jvm.cpp | 82 +++++++------------ src/hotspot/share/prims/methodHandles.cpp | 2 +- src/hotspot/share/prims/unsafe.cpp | 2 +- src/hotspot/share/prims/whitebox.cpp | 26 +++--- src/hotspot/share/runtime/reflection.cpp | 4 +- src/hotspot/share/runtime/sharedRuntime.cpp | 4 +- 15 files changed, 80 insertions(+), 101 deletions(-) diff --git a/src/hotspot/share/cds/aotMetaspace.cpp b/src/hotspot/share/cds/aotMetaspace.cpp index 01bc4708eb5..b3f859fc4a8 100644 --- a/src/hotspot/share/cds/aotMetaspace.cpp +++ b/src/hotspot/share/cds/aotMetaspace.cpp @@ -785,7 +785,7 @@ void AOTMetaspace::link_all_loaded_classes(JavaThread* current) { const GrowableArray* mirrors = collect_classes.mirrors(); for (int i = 0; i < mirrors->length(); i++) { OopHandle mirror = mirrors->at(i); - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(mirror.resolve())); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror.resolve()); if (may_be_eagerly_linked(ik)) { has_linked |= try_link_class(current, ik); } @@ -812,7 +812,7 @@ void AOTMetaspace::link_shared_classes(TRAPS) { const GrowableArray* mirrors = collect_classes.mirrors(); for (int i = 0; i < mirrors->length(); i++) { OopHandle mirror = mirrors->at(i); - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(mirror.resolve())); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror.resolve()); AOTConstantPoolResolver::preresolve_string_cp_entries(ik, CHECK); } } diff --git a/src/hotspot/share/cds/unregisteredClasses.cpp b/src/hotspot/share/cds/unregisteredClasses.cpp index 31cfbd15d67..51b35899599 100644 --- a/src/hotspot/share/cds/unregisteredClasses.cpp +++ b/src/hotspot/share/cds/unregisteredClasses.cpp @@ -94,7 +94,7 @@ InstanceKlass* UnregisteredClasses::load_class(Symbol* name, const char* path, T CHECK_NULL); assert(result.get_type() == T_OBJECT, "just checking"); - return InstanceKlass::cast(java_lang_Class::as_Klass(result.get_oop())); + return java_lang_Class::as_InstanceKlass(result.get_oop()); } bool UnregisteredClasses::check_for_exclusion(const InstanceKlass* k) { diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 86a3b22fbbb..da093936ce5 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -990,7 +990,7 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) { create_mirror(k, Handle(), Handle(), Handle(), Handle(), CHECK); } -void java_lang_Class::initialize_mirror_fields(Klass* k, +void java_lang_Class::initialize_mirror_fields(InstanceKlass* ik, Handle mirror, Handle protection_domain, Handle classData, @@ -1005,7 +1005,7 @@ void java_lang_Class::initialize_mirror_fields(Klass* k, set_protection_domain(mirror(), protection_domain()); // Initialize static fields - InstanceKlass::cast(k)->do_local_static_fields(&initialize_static_field, mirror, CHECK); + ik->do_local_static_fields(&initialize_static_field, mirror, CHECK); // Set classData set_class_data(mirror(), classData()); @@ -1111,8 +1111,7 @@ void java_lang_Class::allocate_mirror(Klass* k, bool is_scratch, Handle protecti // and java_mirror in this klass. } else { assert(k->is_instance_klass(), "Must be"); - - initialize_mirror_fields(k, mirror, protection_domain, classData, THREAD); + initialize_mirror_fields(InstanceKlass::cast(k), mirror, protection_domain, classData, THREAD); if (HAS_PENDING_EXCEPTION) { // If any of the fields throws an exception like OOM remove the klass field // from the mirror so GC doesn't follow it after the klass has been deallocated. @@ -2590,7 +2589,7 @@ static void print_stack_element_to_stream(outputStream* st, Handle mirror, int m ResourceMark rm; stringStream ss; - InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); + InstanceKlass* holder = java_lang_Class::as_InstanceKlass(mirror()); const char* klass_name = holder->external_name(); char* method_name = name->as_C_string(); ss.print("\tat %s.%s(", klass_name, method_name); @@ -2969,7 +2968,7 @@ void java_lang_Throwable::get_stack_trace_elements(int depth, Handle backtrace, THROW(vmSymbols::java_lang_NullPointerException()); } - InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(bte._mirror())); + InstanceKlass* holder = java_lang_Class::as_InstanceKlass(bte._mirror()); methodHandle method (THREAD, holder->method_with_orig_idnum(bte._method_id, bte._version)); java_lang_StackTraceElement::fill_in(stack_trace_element, holder, @@ -3055,7 +3054,7 @@ bool java_lang_Throwable::get_top_method_and_bci(oop throwable, Method** method, // Get first backtrace element. BacktraceElement bte = iter.next(current); - InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(bte._mirror())); + InstanceKlass* holder = java_lang_Class::as_InstanceKlass(bte._mirror()); assert(holder != nullptr, "first element should be non-null"); Method* m = holder->method_with_orig_idnum(bte._method_id, bte._version); @@ -3441,11 +3440,11 @@ void java_lang_reflect_Method::serialize_offsets(SerializeClosure* f) { Handle java_lang_reflect_Method::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); - Klass* klass = vmClasses::reflect_Method_klass(); + InstanceKlass* klass = vmClasses::reflect_Method_klass(); // This class is eagerly initialized during VM initialization, since we keep a reference // to one of the methods - assert(InstanceKlass::cast(klass)->is_initialized(), "must be initialized"); - return InstanceKlass::cast(klass)->allocate_instance_handle(THREAD); + assert(klass->is_initialized(), "must be initialized"); + return klass->allocate_instance_handle(THREAD); } oop java_lang_reflect_Method::clazz(oop reflect) { @@ -3914,17 +3913,15 @@ void reflect_ConstantPool::set_cp(oop reflect, ConstantPool* value) { } ConstantPool* reflect_ConstantPool::get_cp(oop reflect) { - oop mirror = reflect->obj_field(_oop_offset); - Klass* k = java_lang_Class::as_Klass(mirror); - assert(k->is_instance_klass(), "Must be"); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror); // Get the constant pool back from the klass. Since class redefinition // merges the new constant pool into the old, this is essentially the // same constant pool as the original. If constant pool merging is // no longer done in the future, this will have to change to save // the original. - return InstanceKlass::cast(k)->constants(); + return ik->constants(); } @@ -5531,7 +5528,7 @@ void JavaClasses::check_offsets() { #endif // PRODUCT int InjectedField::compute_offset() { - InstanceKlass* ik = InstanceKlass::cast(klass()); + InstanceKlass* ik = klass(); for (AllFieldStream fs(ik); !fs.done(); fs.next()) { if (!may_be_java && !fs.field_flags().is_injected()) { // Only look at injected fields diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 70fa519f0f0..6f82ca10fd6 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -269,7 +269,7 @@ class java_lang_Class : AllStatic { static void set_protection_domain(oop java_class, oop protection_domain); static void set_class_loader(oop java_class, oop class_loader); static void set_component_mirror(oop java_class, oop comp_mirror); - static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, + static void initialize_mirror_fields(InstanceKlass* ik, Handle mirror, Handle protection_domain, Handle classData, TRAPS); static void set_mirror_module_field(JavaThread* current, Klass* K, Handle mirror, Handle module); public: @@ -293,8 +293,10 @@ class java_lang_Class : AllStatic { static void fixup_module_field(Klass* k, Handle module); - // Conversion + // Conversion -- java_class must not be null. The return value is null only if java_class is a primitive type. static Klass* as_Klass(oop java_class); + static InstanceKlass* as_InstanceKlass(oop java_class); + static void set_klass(oop java_class, Klass* klass); static BasicType as_BasicType(oop java_class, Klass** reference_klass = nullptr); static Symbol* as_signature(oop java_class, bool intern_if_not_found); @@ -1895,11 +1897,11 @@ class InjectedField { const vmClassID klass_id; const vmSymbolID name_index; const vmSymbolID signature_index; - const bool may_be_java; + const bool may_be_java; - Klass* klass() const { return vmClasses::klass_at(klass_id); } - Symbol* name() const { return lookup_symbol(name_index); } + InstanceKlass* klass() const { return vmClasses::klass_at(klass_id); } + Symbol* name() const { return lookup_symbol(name_index); } Symbol* signature() const { return lookup_symbol(signature_index); } int compute_offset(); diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 3cbbd2c12f2..21ad62f8408 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -291,6 +291,12 @@ inline Klass* java_lang_Class::as_Klass(oop java_class) { return k; } +inline InstanceKlass* java_lang_Class::as_InstanceKlass(oop java_class) { + Klass* k = as_Klass(java_class); + assert(k == nullptr || k->is_instance_klass(), "type check"); + return static_cast(k); +} + inline bool java_lang_Class::is_primitive(oop java_class) { // should assert: // assert(java_lang_Class::is_instance(java_class), "must be a Class object"); diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 22d4fd1892e..95f86a8950b 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1277,10 +1277,10 @@ InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Ha assert(result.get_type() == T_OBJECT, "just checking"); oop obj = result.get_oop(); - // Primitive classes return null since forName() can not be + // Primitive classes return null since forName() cannot be // used to obtain any of the Class objects representing primitives or void if ((obj != nullptr) && !(java_lang_Class::is_primitive(obj))) { - InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(obj)); + InstanceKlass* k = java_lang_Class::as_InstanceKlass(obj); // For user defined Java class loaders, check that the name returned is // the same as that requested. This check is done for the bootstrap // loader when parsing the class file. diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp index d431d98e383..da098634ba6 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp @@ -65,7 +65,7 @@ const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) { if (is_static_field(ref_owner, ik, offset)) { assert(ik->is_mirror_instance_klass(), "invariant"); assert(java_lang_Class::as_Klass(ref_owner)->is_instance_klass(), "invariant"); - ik = InstanceKlass::cast(java_lang_Class::as_Klass(ref_owner)); + ik = java_lang_Class::as_InstanceKlass(ref_owner); } while (ik != nullptr) { JavaFieldStream jfs(ik); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index c7c3a00a127..137782f93ef 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -187,7 +187,7 @@ JRT_ENTRY(void, JVMCIRuntime::dynamic_new_array_or_null(JavaThread* current, oop JRT_END JRT_ENTRY(void, JVMCIRuntime::dynamic_new_instance_or_null(JavaThread* current, oopDesc* type_mirror)) - InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(type_mirror)); + InstanceKlass* klass = java_lang_Class::as_InstanceKlass(type_mirror); if (klass == nullptr) { ResourceMark rm(current); diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index 0e469dd7f84..34d2d614d22 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -526,7 +526,7 @@ JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message)) jint ret = JNI_OK; DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret); - InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); + InstanceKlass* k = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(clazz)); Symbol* name = k->name(); Handle class_loader (THREAD, k->class_loader()); THROW_MSG_LOADER_(name, (char *)message, class_loader, JNI_OK); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index daacfd4ab7a..2cbe764994d 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -840,14 +840,9 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, if (log_is_enabled(Debug, class, resolve) && result != nullptr) { // this function is generally only used for class loading during verification. ResourceMark rm; - oop from_mirror = JNIHandles::resolve_non_null(from); - Klass* from_class = java_lang_Class::as_Klass(from_mirror); - const char * from_name = from_class->external_name(); - - oop mirror = JNIHandles::resolve_non_null(result); - Klass* to_class = java_lang_Class::as_Klass(mirror); - const char * to = to_class->external_name(); - log_debug(class, resolve)("%s %s (verification)", from_name, to); + const char* from_name = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(from))->external_name(); + const char* to_name = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))->external_name(); + log_debug(class, resolve)("%s %s (verification)", from_name, to_name); } #if INCLUDE_CDS @@ -918,12 +913,12 @@ static jclass jvm_lookup_define_class(jclass lookup, const char *name, jboolean init, int flags, jobject classData, TRAPS) { ResourceMark rm(THREAD); - Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup)); - // Lookup class must be a non-null instance + InstanceKlass* lookup_k = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(lookup)); + // Lookup class must not be a primitive class (whose mirror has a null Klass*) if (lookup_k == nullptr) { + // The error message is wrong. We come here only if lookup is a primitive class THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null"); } - assert(lookup_k->is_instance_klass(), "Lookup class must be an instance klass"); Handle class_loader (THREAD, lookup_k->class_loader()); @@ -934,7 +929,7 @@ static jclass jvm_lookup_define_class(jclass lookup, const char *name, InstanceKlass* host_class = nullptr; if (is_nestmate) { - host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL); + host_class = lookup_k->nest_host(CHECK_NULL); } log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s", @@ -1265,7 +1260,7 @@ JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)) return (jobjectArray)JNIHandles::make_local(THREAD, result); } - InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror)); + InstanceKlass* k = java_lang_Class::as_InstanceKlass(ofMirror); InnerClassesIterator iter(k); if (iter.length() == 0) { @@ -1404,11 +1399,10 @@ static bool jvm_get_field_common(jobject field, fieldDescriptor& fd) { oop reflected = JNIHandles::resolve_non_null(field); oop mirror = java_lang_reflect_Field::clazz(reflected); - Klass* k = java_lang_Class::as_Klass(mirror); int slot = java_lang_reflect_Field::slot(reflected); int modifiers = java_lang_reflect_Field::modifiers(reflected); - InstanceKlass* ik = InstanceKlass::cast(k); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror); int offset = ik->field_offset(slot); if (modifiers & JVM_ACC_STATIC) { @@ -1444,9 +1438,9 @@ static Method* jvm_get_method_common(jobject method) { mirror = java_lang_reflect_Method::clazz(reflected); slot = java_lang_reflect_Method::slot(reflected); } - Klass* k = java_lang_Class::as_Klass(mirror); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror); - Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); + Method* m = ik->method_with_idnum(slot); assert(m != nullptr, "cannot find method"); return m; // caller has to deal with null in product mode } @@ -1570,7 +1564,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, return (jobjectArray) JNIHandles::make_local(THREAD, res); } - InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror)); + InstanceKlass* k = java_lang_Class::as_InstanceKlass(ofMirror); constantPoolHandle cp(THREAD, k->constants()); // Ensure class is linked @@ -1627,9 +1621,7 @@ JVM_END // even if the class is not a record. JVM_ENTRY(jobjectArray, JVM_GetRecordComponents(JNIEnv* env, jclass ofClass)) { - Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)); - assert(c->is_instance_klass(), "must be"); - InstanceKlass* ik = InstanceKlass::cast(c); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(ofClass)); Array* components = ik->record_components(); if (components != nullptr) { @@ -1671,7 +1663,7 @@ static jobjectArray get_class_declared_methods_helper( return (jobjectArray) JNIHandles::make_local(THREAD, res); } - InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror)); + InstanceKlass* k = java_lang_Class::as_InstanceKlass(ofMirror); // Ensure class is linked k->link_class(CHECK_NULL); @@ -1750,23 +1742,17 @@ JVM_END JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member)) { - Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); - assert(c->is_instance_klass(), "must be"); - InstanceKlass* ck = InstanceKlass::cast(c); - Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member)); - assert(m->is_instance_klass(), "must be"); - InstanceKlass* mk = InstanceKlass::cast(m); - return ck->has_nestmate_access_to(mk, THREAD); + InstanceKlass* c = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(current)); + InstanceKlass* m = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(member)); + return c->has_nestmate_access_to(m, THREAD); } JVM_END JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current)) { // current is not a primitive or array class - Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); - assert(c->is_instance_klass(), "must be"); - InstanceKlass* ck = InstanceKlass::cast(c); - InstanceKlass* host = ck->nest_host(THREAD); + InstanceKlass* c = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(current)); + InstanceKlass* host = c->nest_host(THREAD); return (jclass) (host == nullptr ? nullptr : JNIHandles::make_local(THREAD, host->java_mirror())); } @@ -1776,13 +1762,11 @@ JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current)) { // current is not a primitive or array class ResourceMark rm(THREAD); - Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); - assert(c->is_instance_klass(), "must be"); - InstanceKlass* ck = InstanceKlass::cast(c); - InstanceKlass* host = ck->nest_host(THREAD); + InstanceKlass* c = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(current)); + InstanceKlass* host = c->nest_host(THREAD); log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s", - ck->external_name(), host->external_name()); + c->external_name(), host->external_name()); { JvmtiVMObjectAllocEventCollector oam; Array* members = host->nest_members(); @@ -1845,7 +1829,7 @@ JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current)) } } else { - assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate"); + assert(host == c || c->is_hidden(), "must be singleton nest or dynamic nestmate"); } return (jobjectArray)JNIHandles::make_local(THREAD, result()); } @@ -1856,9 +1840,8 @@ JVM_ENTRY(jobjectArray, JVM_GetPermittedSubclasses(JNIEnv* env, jclass current)) { oop mirror = JNIHandles::resolve_non_null(current); assert(!java_lang_Class::is_primitive(mirror), "should not be"); - Klass* c = java_lang_Class::as_Klass(mirror); - assert(c->is_instance_klass(), "must be"); - InstanceKlass* ik = InstanceKlass::cast(c); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror); + ResourceMark rm(THREAD); log_trace(class, sealed)("Calling GetPermittedSubclasses for %s type %s", ik->is_sealed() ? "sealed" : "non-sealed", ik->external_name()); @@ -3379,16 +3362,14 @@ JVM_ENTRY(void, JVM_RegisterLambdaProxyClassForArchiving(JNIEnv* env, return; } - Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller)); - InstanceKlass* caller_ik = InstanceKlass::cast(caller_k); + InstanceKlass* caller_ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(caller)); if (caller_ik->is_hidden()) { // Hidden classes not of type lambda proxy classes are currently not being archived. // If the caller_ik is of one of the above types, the corresponding lambda proxy class won't be // registered for archiving. return; } - Klass* lambda_k = java_lang_Class::as_Klass(JNIHandles::resolve(lambdaProxyClass)); - InstanceKlass* lambda_ik = InstanceKlass::cast(lambda_k); + InstanceKlass* lambda_ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(lambdaProxyClass)); assert(lambda_ik->is_hidden(), "must be a hidden class"); assert(!lambda_ik->is_non_strong_hidden(), "expected a strong hidden class"); @@ -3428,8 +3409,7 @@ JVM_ENTRY(jclass, JVM_LookupLambdaProxyClassFromArchive(JNIEnv* env, THROW_(vmSymbols::java_lang_NullPointerException(), nullptr); } - Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller)); - InstanceKlass* caller_ik = InstanceKlass::cast(caller_k); + InstanceKlass* caller_ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(caller)); if (!caller_ik->in_aot_cache()) { // there won't be a shared lambda class if the caller_ik is not in the shared archive. return nullptr; @@ -3825,11 +3805,7 @@ JVM_ENTRY(jint, JVM_GetClassFileVersion(JNIEnv* env, jclass current)) // return latest major version and minor version of 0. return JVM_CLASSFILE_MAJOR_VERSION; } - assert(!java_lang_Class::as_Klass(mirror)->is_array_klass(), "unexpected array class"); - - Klass* c = java_lang_Class::as_Klass(mirror); - assert(c->is_instance_klass(), "must be"); - InstanceKlass* ik = InstanceKlass::cast(c); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror); return (ik->minor_version() << 16) | ik->major_version(); JVM_END diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index c46b46b1af1..b13bd392eaa 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -902,7 +902,7 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { if (clazz == nullptr) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand (as field)"); } - InstanceKlass* defc = InstanceKlass::cast(java_lang_Class::as_Klass(clazz)); + InstanceKlass* defc = java_lang_Class::as_InstanceKlass(clazz); DEBUG_ONLY(clazz = nullptr); // safety intptr_t vmindex = java_lang_invoke_MemberName::vmindex(mname()); bool is_static = ((flags & JVM_ACC_STATIC) != 0); diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp index 4b2ffd57860..c950690e8ab 100644 --- a/src/hotspot/share/prims/unsafe.cpp +++ b/src/hotspot/share/prims/unsafe.cpp @@ -489,7 +489,7 @@ static jlong find_known_instance_field_offset(jclass clazz, jstring name, TRAPS) ResourceMark rm(THREAD); char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name)); - InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); + InstanceKlass* k = java_lang_Class::as_InstanceKlass(JNIHandles::resolve_non_null(clazz)); jint offset = -1; // Not found for (JavaFieldStream fs(k); !fs.done(); fs.next()) { diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index afaa089e0b2..ce559d47b24 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -1156,7 +1156,7 @@ WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobjec WB_END WB_ENTRY(jboolean, WB_EnqueueInitializerForCompilation(JNIEnv* env, jobject o, jclass klass, jint comp_level)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); Method* clinit = ik->class_initializer(); if (clinit == nullptr || clinit->method_holder()->is_not_initialized()) { return false; @@ -1936,18 +1936,18 @@ WB_ENTRY(void, WB_ForceClassLoaderStatsSafepoint(JNIEnv* env, jobject wb)) WB_END WB_ENTRY(jlong, WB_GetConstantPool(JNIEnv* env, jobject wb, jclass klass)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); return (jlong) ik->constants(); WB_END WB_ENTRY(jobjectArray, WB_GetResolvedReferences(JNIEnv* env, jobject wb, jclass klass)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); objArrayOop resolved_refs= ik->constants()->resolved_references(); return (jobjectArray)JNIHandles::make_local(THREAD, resolved_refs); WB_END WB_ENTRY(jint, WB_getFieldEntriesLength(JNIEnv* env, jobject wb, jclass klass)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); ConstantPool* cp = ik->constants(); if (cp->cache() == nullptr) { return -1; @@ -1956,7 +1956,7 @@ WB_ENTRY(jint, WB_getFieldEntriesLength(JNIEnv* env, jobject wb, jclass klass)) WB_END WB_ENTRY(jint, WB_getFieldCPIndex(JNIEnv* env, jobject wb, jclass klass, jint index)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); ConstantPool* cp = ik->constants(); if (cp->cache() == nullptr) { return -1; @@ -1965,7 +1965,7 @@ WB_ENTRY(jint, WB_getFieldCPIndex(JNIEnv* env, jobject wb, jclass klass, jint in WB_END WB_ENTRY(jint, WB_getMethodEntriesLength(JNIEnv* env, jobject wb, jclass klass)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); ConstantPool* cp = ik->constants(); if (cp->cache() == nullptr) { return -1; @@ -1974,7 +1974,7 @@ WB_ENTRY(jint, WB_getMethodEntriesLength(JNIEnv* env, jobject wb, jclass klass)) WB_END WB_ENTRY(jint, WB_getMethodCPIndex(JNIEnv* env, jobject wb, jclass klass, jint index)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); ConstantPool* cp = ik->constants(); if (cp->cache() == nullptr) { return -1; @@ -1983,7 +1983,7 @@ WB_ENTRY(jint, WB_getMethodCPIndex(JNIEnv* env, jobject wb, jclass klass, jint i WB_END WB_ENTRY(jint, WB_getIndyInfoLength(JNIEnv* env, jobject wb, jclass klass)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); ConstantPool* cp = ik->constants(); if (cp->cache() == nullptr) { return -1; @@ -1992,7 +1992,7 @@ WB_ENTRY(jint, WB_getIndyInfoLength(JNIEnv* env, jobject wb, jclass klass)) WB_END WB_ENTRY(jint, WB_getIndyCPIndex(JNIEnv* env, jobject wb, jclass klass, jint index)) - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(klass)); ConstantPool* cp = ik->constants(); if (cp->cache() == nullptr) { return -1; @@ -2386,10 +2386,8 @@ int WhiteBox::offset_for_field(const char* field_name, oop object, Symbol* signature_symbol) { assert(field_name != nullptr && strlen(field_name) > 0, "Field name not valid"); - //Get the class of our object - Klass* arg_klass = object->klass(); - //Turn it into an instance-klass - InstanceKlass* ik = InstanceKlass::cast(arg_klass); + //Only non-array oops have fields. Don't call this function on arrays! + InstanceKlass* ik = InstanceKlass::cast(object->klass()); //Create symbols to look for in the class TempNewSymbol name_symbol = SymbolTable::new_symbol(field_name); @@ -3065,7 +3063,7 @@ JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass)) { if (WhiteBoxAPI) { // Make sure that wbclass is loaded by the null classloader - InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(wbclass))); + InstanceKlass* ik = java_lang_Class::as_InstanceKlass(JNIHandles::resolve(wbclass)); Handle loader(THREAD, ik->class_loader()); if (loader.is_null()) { WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0])); diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index a7b468c57a3..7728643c640 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -1136,7 +1136,7 @@ oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle rtype = T_OBJECT; } - InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); + InstanceKlass* klass = java_lang_Class::as_InstanceKlass(mirror); Method* m = klass->method_with_idnum(slot); if (m == nullptr) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "invoke"); @@ -1153,7 +1153,7 @@ oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0; objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror))); - InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); + InstanceKlass* klass = java_lang_Class::as_InstanceKlass(mirror); Method* m = klass->method_with_idnum(slot); if (m == nullptr) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "invoke"); diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index b7ad8081c52..2f7161ff744 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -881,8 +881,8 @@ void SharedRuntime::throw_StackOverflowError_common(JavaThread* current, bool de // We avoid using the normal exception construction in this case because // it performs an upcall to Java, and we're already out of stack space. JavaThread* THREAD = current; // For exception macros. - Klass* k = vmClasses::StackOverflowError_klass(); - oop exception_oop = InstanceKlass::cast(k)->allocate_instance(CHECK); + InstanceKlass* k = vmClasses::StackOverflowError_klass(); + oop exception_oop = k->allocate_instance(CHECK); if (delayed) { java_lang_Throwable::set_message(exception_oop, Universe::delayed_stack_overflow_error_message()); From 90e81c2bee86f404250fb9b833d43b18190b5272 Mon Sep 17 00:00:00 2001 From: Dingli Zhang Date: Tue, 16 Sep 2025 01:11:04 +0000 Subject: [PATCH 091/120] 8367616: RISC-V: Auto-enable Zicboz extension for debug builds Reviewed-by: fyang, fjiang --- src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp index 3d771123f12..3e5fb4610de 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp @@ -191,6 +191,9 @@ void RiscvHwprobe::add_features_from_query_result() { VM_Version::ext_Zbs.enable_feature(); } #ifndef PRODUCT + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZICBOZ)) { + VM_Version::ext_Zicboz.enable_feature(); + } if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBKB)) { VM_Version::ext_Zbkb.enable_feature(); } From 0fbae8050b6f853053c7dee6a43d3ffbcfa69954 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 16 Sep 2025 04:42:50 +0000 Subject: [PATCH 092/120] 8252582: HotSpot Style Guide should permit variable templates Reviewed-by: dholmes, stefank, kvn --- doc/hotspot-style.html | 45 +++++++++++++++++++++++------------------- doc/hotspot-style.md | 33 +++++++++++++++++-------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index fb4cffc9d43..7be6867b3ca 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -86,8 +86,9 @@ values
    • thread_local
    • nullptr
    • <atomic>
    • -
    • Inline -Variables
    • +
    • Variable Templates and +Inline Variables
    • Initializing variables with static storage duration
    • @@ -937,12 +938,18 @@ differ from what the Java compilers implement.

      "conservative" memory ordering, which may differ from (may be stronger than) sequentially consistent. There are algorithms in HotSpot that are believed to rely on that ordering.

      -

      Inline Variables

      -

      Variables with static storage duration may be declared -inline (p0386r2). -This has similar effects as for declaring a function inline: it can be -defined, identically, in multiple translation units, must be defined in -every translation unit in which it is Variable Templates and +Inline Variables +

      The use of variable templates (including static data member +templates) (N3651) is permitted. +They provide parameterized variables and constants in a simple and +direct form, instead of requiring the use of various workarounds.

      +

      Variables with static storage duration and variable templates may be +declared inline (p0386r2), and this usage is +permitted. This has similar effects as for declaring a function inline: +it can be defined, identically, in multiple translation units, must be +defined in every translation unit in which it is ODR used, and the behavior of the program is as if there is exactly one variable.

      @@ -955,16 +962,17 @@ initializations can make initialization order problems worse. The few ordering constraints that exist for non-inline variables don't apply, as there isn't a single program-designated translation unit containing the definition.

      -

      A constexpr static data member is implicitly -inline. As a consequence, an A constexpr static data member or static data member +template is implicitly inline. As a consequence, an ODR use of such a variable doesn't -require a definition in some .cpp file. (This is a change from -pre-C++17. Beginning with C++17, such a definition is considered a -duplicate definition, and is deprecated.)

      -

      Declaring a thread_local variable inline is -forbidden for HotSpot code. The use of -thread_local is already heavily restricted.

      +title="One Definition Rule">ODR use of such a member doesn't require +a definition in some .cpp file. (This is a change from pre-C++17. +Beginning with C++17, such a definition is considered a duplicate +definition, and is deprecated.)

      +

      Declaring a thread_local variable template or +inline variable is forbidden in HotSpot code. The use of thread_local is already +heavily restricted.

      Initializing variables with static storage duration

      @@ -1853,9 +1861,6 @@ Features
      • Trailing return type syntax for functions (n2541)

      • -
      • Variable templates (n3651, p0127r2)

      • Member initializers and aggregates (n3653)

      • Rvalue references and move semantics

      • diff --git a/doc/hotspot-style.md b/doc/hotspot-style.md index 3fd5468d531..facdf68462f 100644 --- a/doc/hotspot-style.md +++ b/doc/hotspot-style.md @@ -856,14 +856,19 @@ ordering, which may differ from (may be stronger than) sequentially consistent. There are algorithms in HotSpot that are believed to rely on that ordering. -### Inline Variables +### Variable Templates and Inline Variables -Variables with static storage duration may be declared `inline` -([p0386r2](https://wg21.link/p0386r2)). This has similar effects as for -declaring a function inline: it can be defined, identically, in multiple -translation units, must be defined in every translation unit in which it is -[ODR used][ODR], and the behavior of the program is as if there is exactly one -variable. +The use of variable templates (including static data member templates) +([N3651](https://wg21.link/N3651)) is permitted. They provide parameterized +variables and constants in a simple and direct form, instead of requiring the +use of various workarounds. + +Variables with static storage duration and variable templates may be declared +`inline` ([p0386r2](https://wg21.link/p0386r2)), and this usage is +permitted. This has similar effects as for declaring a function inline: it can +be defined, identically, in multiple translation units, must be defined in +every translation unit in which it is [ODR used][ODR], and the behavior of the +program is as if there is exactly one variable. Declaring a variable inline allows the complete definition to be in a header file, rather than having a declaration in a header and the definition in a @@ -874,13 +879,15 @@ make initialization order problems worse. The few ordering constraints that exist for non-inline variables don't apply, as there isn't a single program-designated translation unit containing the definition. -A `constexpr` static data member is implicitly `inline`. As a consequence, an -[ODR use][ODR] of such a variable doesn't require a definition in some .cpp +A `constexpr` static data member or static data member template +is implicitly `inline`. As a consequence, an +[ODR use][ODR] of such a member doesn't require a definition in some .cpp file. (This is a change from pre-C++17. Beginning with C++17, such a definition is considered a duplicate definition, and is deprecated.) -Declaring a `thread_local` variable `inline` is forbidden for HotSpot code. -[The use of `thread_local`](#thread_local) is already heavily restricted. +Declaring a `thread_local` variable template or `inline` variable is forbidden +in HotSpot code. [The use of `thread_local`](#thread_local) is already +heavily restricted. ### Initializing variables with static storage duration @@ -1849,10 +1856,6 @@ See Object Lifetime: C++17 6.8/8, C++20 6.7.3/8 * Trailing return type syntax for functions ([n2541](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm)) -* Variable templates -([n3651](https://isocpp.org/files/papers/N3651.pdf), -[p0127r2](http://wg21.link/p0127r2)) - * Member initializers and aggregates ([n3653](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html)) From 76e464bcd56dab6ef0dfd917f87fdedeb9f838b4 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Tue, 16 Sep 2025 05:06:17 +0000 Subject: [PATCH 093/120] 8367150: Add a header line to improve VMErrorCallback printing Reviewed-by: stefank, ayang --- src/hotspot/share/utilities/vmError.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 357bf111804..0fbd8ed4259 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -1143,9 +1143,11 @@ void VMError::report(outputStream* st, bool _verbose) { } STEP_IF("printing registered callbacks", _verbose && _thread != nullptr); + size_t count = 0; for (VMErrorCallback* callback = _thread->_vm_error_callbacks; callback != nullptr; callback = callback->_next) { + st->print_cr("VMErrorCallback %zu:", ++count); callback->call(st); st->cr(); } From 60e9222fe147413f20c140f2c00541b6472dfaa4 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Tue, 16 Sep 2025 06:30:53 +0000 Subject: [PATCH 094/120] 8015444: java/awt/Focus/KeyStrokeTest.java sometimes fails Reviewed-by: tr --- test/jdk/java/awt/Focus/KeyStrokeTest.java | 79 +++++++++++----------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/test/jdk/java/awt/Focus/KeyStrokeTest.java b/test/jdk/java/awt/Focus/KeyStrokeTest.java index 7c462ce8f22..668bc1216c8 100644 --- a/test/jdk/java/awt/Focus/KeyStrokeTest.java +++ b/test/jdk/java/awt/Focus/KeyStrokeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, 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 @@ -29,9 +29,9 @@ * @run main KeyStrokeTest */ -import java.awt.BorderLayout; import java.awt.Button; import java.awt.Dialog; +import java.awt.EventQueue; import java.awt.Frame; import java.awt.Robot; import java.awt.TextField; @@ -39,25 +39,53 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class KeyStrokeTest { static boolean keyTyped; static Frame frame; + static Robot robot; + static final CountDownLatch latch = new CountDownLatch(1); public static void main(String[] args) throws Exception { + robot = new Robot(); try { - KeyStrokeTest test = new KeyStrokeTest(); - test.doTest(); - } finally { - if (frame != null) { - frame.dispose(); + EventQueue.invokeAndWait(() -> { + KeyStrokeTest test = new KeyStrokeTest(); + test.initTest(); + }); + robot.waitForIdle(); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + + robot.delay(1000); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + + robot.delay(1000); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + try { + latch.await(3, TimeUnit.SECONDS); + } catch (InterruptedException e) {} + if (!keyTyped) { + throw new + RuntimeException("First keystroke after JDialog is closed is lost"); } + System.out.println("Test passed"); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); } } - private static void doTest() throws Exception { - final Object monitor = new Object(); - frame = new Frame(); + private static void initTest() { + frame = new Frame("KeyStrokeTest"); TextField textField = new TextField() { public void transferFocus() { System.err.println("transferFocus()"); @@ -71,6 +99,7 @@ public class KeyStrokeTest { }); dialog.add(btn); dialog.setSize(200, 200); + dialog.setLocationRelativeTo(null); dialog.setVisible(true); } }; @@ -81,38 +110,12 @@ public class KeyStrokeTest { if (e.getKeyChar() == 'a') { keyTyped = true; } - - synchronized (monitor) { - monitor.notifyAll(); - } + latch.countDown(); } }); frame.add(textField); frame.setSize(400, 400); + frame.setLocationRelativeTo(null); frame.setVisible(true); - - Robot robot = new Robot(); - robot.waitForIdle(); - robot.delay(1000); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); - - robot.delay(1000); - robot.keyPress(KeyEvent.VK_SPACE); - robot.keyRelease(KeyEvent.VK_SPACE); - - robot.delay(1000); - synchronized (monitor) { - robot.keyPress(KeyEvent.VK_A); - robot.keyRelease(KeyEvent.VK_A); - monitor.wait(3000); - } - - if (!keyTyped) { - throw new RuntimeException("TEST FAILED"); - } - - System.out.println("Test passed"); } - } From 73df06c80c33be584b054a528ecdab4ecbf51d56 Mon Sep 17 00:00:00 2001 From: Andreas Steiner Date: Tue, 16 Sep 2025 07:17:53 +0000 Subject: [PATCH 095/120] 8359104: gc/TestAlwaysPreTouchBehavior.java# fails on Linux Reviewed-by: mbaesken, ayang --- src/hotspot/os/linux/os_linux.cpp | 46 +++++++++++++++++-- src/hotspot/os/linux/os_linux.hpp | 17 +++++++ .../jtreg/gc/TestAlwaysPreTouchBehavior.java | 2 +- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index d7bc524e75b..3d44d839735 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -370,11 +370,20 @@ size_t os::physical_memory() { return phys_mem; } +// 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. +// Users requiring accurate RSS values should be aware of this limitation. size_t os::rss() { size_t size = 0; - os::Linux::meminfo_t info; - if (os::Linux::query_process_memory_info(&info)) { - size = info.vmrss * K; + os::Linux::accurate_meminfo_t accurate_info; + if (os::Linux::query_accurate_process_memory_info(&accurate_info) && accurate_info.rss != -1) { + size = accurate_info.rss * K; + } else { + os::Linux::meminfo_t info; + if (os::Linux::query_process_memory_info(&info)) { + size = info.vmrss * K; + } } return size; } @@ -2362,6 +2371,37 @@ bool os::Linux::query_process_memory_info(os::Linux::meminfo_t* info) { return false; } +// Accurate memory information need Linux 4.14 or newer +bool os::Linux::query_accurate_process_memory_info(os::Linux::accurate_meminfo_t* info) { + FILE* f = os::fopen("/proc/self/smaps_rollup", "r"); + if (f == nullptr) { + return false; + } + + const size_t num_values = sizeof(os::Linux::accurate_meminfo_t) / sizeof(size_t); + size_t num_found = 0; + char buf[256]; + info->rss = info->pss = info->pssdirty = info->pssanon = + info->pssfile = info->pssshmem = info->swap = info->swappss = -1; + + while (::fgets(buf, sizeof(buf), f) != nullptr && num_found < num_values) { + if ( (info->rss == -1 && sscanf(buf, "Rss: %zd kB", &info->rss) == 1) || + (info->pss == -1 && sscanf(buf, "Pss: %zd kB", &info->pss) == 1) || + (info->pssdirty == -1 && sscanf(buf, "Pss_Dirty: %zd kB", &info->pssdirty) == 1) || + (info->pssanon == -1 && sscanf(buf, "Pss_Anon: %zd kB", &info->pssanon) == 1) || + (info->pssfile == -1 && sscanf(buf, "Pss_File: %zd kB", &info->pssfile) == 1) || + (info->pssshmem == -1 && sscanf(buf, "Pss_Shmem: %zd kB", &info->pssshmem) == 1) || + (info->swap == -1 && sscanf(buf, "Swap: %zd kB", &info->swap) == 1) || + (info->swappss == -1 && sscanf(buf, "SwapPss: %zd kB", &info->swappss) == 1) + ) + { + num_found ++; + } + } + fclose(f); + return true; +} + #ifdef __GLIBC__ // For Glibc, print a one-liner with the malloc tunables. // Most important and popular is MALLOC_ARENA_MAX, but we are diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index d3e0d6c5668..497d383200d 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -181,6 +181,23 @@ class os::Linux { // fields will contain -1. static bool query_process_memory_info(meminfo_t* info); + // Output structure for query_accurate_process_memory_info() (all values in KB) + struct accurate_meminfo_t { + ssize_t rss; // current resident set size + ssize_t pss; // current proportional set size + ssize_t pssdirty; // proportional set size (dirty) + ssize_t pssanon; // proportional set size (anonymous mappings) + ssize_t pssfile; // proportional set size (file mappings) + ssize_t pssshmem; // proportional set size (shared mappings) + ssize_t swap; // swapped out + ssize_t swappss; // proportional set size (swapped out) + }; + + // Attempts to query accurate memory information from /proc/self/smaps_rollup and return it in the output structure. + // May fail (returns false) or succeed (returns true) but not all output fields are available; unavailable + // fields will contain -1. + static bool query_accurate_process_memory_info(accurate_meminfo_t* info); + // Tells if the user asked for transparent huge pages. static bool _thp_requested; diff --git a/test/hotspot/jtreg/gc/TestAlwaysPreTouchBehavior.java b/test/hotspot/jtreg/gc/TestAlwaysPreTouchBehavior.java index b8197f70384..141ef7ba197 100644 --- a/test/hotspot/jtreg/gc/TestAlwaysPreTouchBehavior.java +++ b/test/hotspot/jtreg/gc/TestAlwaysPreTouchBehavior.java @@ -155,7 +155,7 @@ public class TestAlwaysPreTouchBehavior { } if (available > requiredAvailable) { Asserts.assertGreaterThan(rss, minRequiredRss, "RSS of this process(" + rss + "b) should be bigger " + - "than or equal to heap size(" + heapSize + "b) (available memory: " + available + ")"); + "than or equal to heap size(" + heapSize + "b) (available memory: " + available + "). On Linux Kernel < 4.14 RSS can be inaccurate"); } } } From 3ba2e748d61a9ed8098093c6d4732973051808b2 Mon Sep 17 00:00:00 2001 From: Guanqiang Han Date: Tue, 16 Sep 2025 08:00:09 +0000 Subject: [PATCH 096/120] 8366925: Improper std::nothrow new expression in NativeHeapTrimmerThread ctor Reviewed-by: ayang, kbarrett, dholmes --- src/hotspot/share/runtime/trimNativeHeap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/trimNativeHeap.cpp b/src/hotspot/share/runtime/trimNativeHeap.cpp index 875bcb8e0c8..6049f4531c0 100644 --- a/src/hotspot/share/runtime/trimNativeHeap.cpp +++ b/src/hotspot/share/runtime/trimNativeHeap.cpp @@ -163,7 +163,7 @@ class NativeHeapTrimmerThread : public NamedThread { public: NativeHeapTrimmerThread() : - _lock(new (std::nothrow) PaddedMonitor(Mutex::nosafepoint, "NativeHeapTrimmer_lock")), + _lock(new PaddedMonitor(Mutex::nosafepoint, "NativeHeapTrimmer_lock")), _stop(false), _suspend_count(0), _num_trims_performed(0) From eb26865c36f1961ee802c8db812c786d4bdd4944 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 16 Sep 2025 08:00:32 +0000 Subject: [PATCH 097/120] 8367552: JCmdTestFileSafety.java fails when run by root user Reviewed-by: dcubed, ayang, phubner --- .../jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java index 68d77c5455c..74f98d5b777 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java @@ -141,6 +141,9 @@ public class JCmdTestFileSafety extends JCmdTestDumpBase { // to create archive successfully which is not expected. throw new jtreg.SkippedException("Test skipped on Windows"); } + if (Platform.isRoot()) { + throw new jtreg.SkippedException("Test skipped when executed by root user."); + } runTest(JCmdTestFileSafety::test); } } From ca89cd06d39ed3a6bbe16f60fea4d7382849edbd Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 16 Sep 2025 08:46:18 +0000 Subject: [PATCH 098/120] 8367410: ZGC: Remove unused ZNmethodTable::wait_until_iteration_done() Reviewed-by: stefank, fandreuzzi --- src/hotspot/share/gc/z/zNMethodTable.cpp | 8 -------- src/hotspot/share/gc/z/zNMethodTable.hpp | 4 +--- src/hotspot/share/gc/z/zNMethodTableIteration.hpp | 4 ++-- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/hotspot/share/gc/z/zNMethodTable.cpp b/src/hotspot/share/gc/z/zNMethodTable.cpp index bbc8f56b654..f73014085f7 100644 --- a/src/hotspot/share/gc/z/zNMethodTable.cpp +++ b/src/hotspot/share/gc/z/zNMethodTable.cpp @@ -194,14 +194,6 @@ void ZNMethodTable::register_nmethod(nmethod* nm) { } } -void ZNMethodTable::wait_until_iteration_done() { - assert(CodeCache_lock->owned_by_self(), "Lock must be held"); - - while (_iteration.in_progress() || _iteration_secondary.in_progress()) { - CodeCache_lock->wait_without_safepoint_check(); - } -} - void ZNMethodTable::unregister_nmethod(nmethod* nm) { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); diff --git a/src/hotspot/share/gc/z/zNMethodTable.hpp b/src/hotspot/share/gc/z/zNMethodTable.hpp index e160ac1b39a..a8b9029caeb 100644 --- a/src/hotspot/share/gc/z/zNMethodTable.hpp +++ b/src/hotspot/share/gc/z/zNMethodTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, 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 @@ -64,8 +64,6 @@ public: static void register_nmethod(nmethod* nm); static void unregister_nmethod(nmethod* nm); - static void wait_until_iteration_done(); - static void nmethods_do_begin(bool secondary); static void nmethods_do_end(bool secondary); static void nmethods_do(bool secondary, NMethodClosure* cl); diff --git a/src/hotspot/share/gc/z/zNMethodTableIteration.hpp b/src/hotspot/share/gc/z/zNMethodTableIteration.hpp index fc8acd2589c..34bd7d9b4f8 100644 --- a/src/hotspot/share/gc/z/zNMethodTableIteration.hpp +++ b/src/hotspot/share/gc/z/zNMethodTableIteration.hpp @@ -35,11 +35,11 @@ private: size_t _size; ZCACHE_ALIGNED volatile size_t _claimed; + bool in_progress() const; + public: ZNMethodTableIteration(); - bool in_progress() const; - void nmethods_do_begin(ZNMethodTableEntry* table, size_t size); void nmethods_do_end(); void nmethods_do(NMethodClosure* cl); From c7f014ed494409cdf9fc925fe98de08346606408 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Tue, 16 Sep 2025 12:33:32 +0000 Subject: [PATCH 099/120] 8356813: Improve Mod(I|L)Node::Value Reviewed-by: epeter, qamai --- src/hotspot/share/opto/divnode.cpp | 126 ++++---- .../compiler/c2/gvn/ModINodeValueTests.java | 292 ++++++++++++++++++ .../compiler/c2/gvn/ModLNodeValueTests.java | 292 ++++++++++++++++++ 3 files changed, 645 insertions(+), 65 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/gvn/ModINodeValueTests.java create mode 100644 test/hotspot/jtreg/compiler/c2/gvn/ModLNodeValueTests.java diff --git a/src/hotspot/share/opto/divnode.cpp b/src/hotspot/share/opto/divnode.cpp index 0d1337909fb..213f2e1e9a8 100644 --- a/src/hotspot/share/opto/divnode.cpp +++ b/src/hotspot/share/opto/divnode.cpp @@ -1198,44 +1198,76 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) { } //------------------------------Value------------------------------------------ -const Type* ModINode::Value(PhaseGVN* phase) const { +static const Type* mod_value(const PhaseGVN* phase, const Node* in1, const Node* in2, const BasicType bt) { + assert(bt == T_INT || bt == T_LONG, "unexpected basic type"); // Either input is TOP ==> the result is TOP - const Type *t1 = phase->type( in(1) ); - const Type *t2 = phase->type( in(2) ); - if( t1 == Type::TOP ) return Type::TOP; - if( t2 == Type::TOP ) return Type::TOP; + const Type* t1 = phase->type(in1); + const Type* t2 = phase->type(in2); + if (t1 == Type::TOP) { return Type::TOP; } + if (t2 == Type::TOP) { return Type::TOP; } // We always generate the dynamic check for 0. // 0 MOD X is 0 - if( t1 == TypeInt::ZERO ) return TypeInt::ZERO; + if (t1 == TypeInteger::zero(bt)) { return t1; } + // X MOD X is 0 - if (in(1) == in(2)) { - return TypeInt::ZERO; + if (in1 == in2) { + return TypeInteger::zero(bt); } - // Either input is BOTTOM ==> the result is the local BOTTOM - const Type *bot = bottom_type(); - if( (t1 == bot) || (t2 == bot) || - (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) - return bot; - - const TypeInt *i1 = t1->is_int(); - const TypeInt *i2 = t2->is_int(); - if( !i1->is_con() || !i2->is_con() ) { - if( i1->_lo >= 0 && i2->_lo >= 0 ) - return TypeInt::POS; - // If both numbers are not constants, we know little. - return TypeInt::INT; - } // Mod by zero? Throw exception at runtime! - if( !i2->get_con() ) return TypeInt::POS; + if (t2 == TypeInteger::zero(bt)) { + return Type::TOP; + } - // We must be modulo'ing 2 float constants. - // Check for min_jint % '-1', result is defined to be '0'. - if( i1->get_con() == min_jint && i2->get_con() == -1 ) - return TypeInt::ZERO; + const TypeInteger* i1 = t1->is_integer(bt); + const TypeInteger* i2 = t2->is_integer(bt); + if (i1->is_con() && i2->is_con()) { + // We must be modulo'ing 2 int constants. + // Special case: min_jlong % '-1' is UB, and e.g., x86 triggers a division error. + // Any value % -1 is 0, so we can return 0 and avoid that scenario. + if (i2->get_con_as_long(bt) == -1) { + return TypeInteger::zero(bt); + } + return TypeInteger::make(i1->get_con_as_long(bt) % i2->get_con_as_long(bt), bt); + } + // We checked that t2 is not the zero constant. Hence, at least i2->_lo or i2->_hi must be non-zero, + // and hence its absoute value is bigger than zero. Hence, the magnitude of the divisor (i.e. the + // largest absolute value for any value in i2) must be in the range [1, 2^31] or [1, 2^63], depending + // on the BasicType. + julong divisor_magnitude = MAX2(g_uabs(i2->lo_as_long()), g_uabs(i2->hi_as_long())); + // JVMS lrem bytecode: "the magnitude of the result is always less than the magnitude of the divisor" + // "less than" means we can subtract 1 to get an inclusive upper bound in [0, 2^31-1] or [0, 2^63-1], respectively + jlong hi = static_cast(divisor_magnitude - 1); + jlong lo = -hi; + // JVMS lrem bytecode: "the result of the remainder operation can be negative only if the dividend + // is negative and can be positive only if the dividend is positive" + // Note that with a dividend with bounds e.g. lo == -4 and hi == -1 can still result in values + // below lo; i.e., -3 % 3 == 0. + // That means we cannot restrict the bound that is closer to zero beyond knowing its sign (or zero). + if (i1->hi_as_long() <= 0) { + // all dividends are not positive, so the result is not positive + hi = 0; + // if the dividend is known to be closer to zero, use that as a lower limit + lo = MAX2(lo, i1->lo_as_long()); + } else if (i1->lo_as_long() >= 0) { + // all dividends are not negative, so the result is not negative + lo = 0; + // if the dividend is known to be closer to zero, use that as an upper limit + hi = MIN2(hi, i1->hi_as_long()); + } else { + // Mixed signs, so we don't know the sign of the result, but the result is + // either the dividend itself or a value closer to zero than the dividend, + // and it is closer to zero than the divisor. + // As we know i1->_lo < 0 and i1->_hi > 0, we can use these bounds directly. + lo = MAX2(lo, i1->lo_as_long()); + hi = MIN2(hi, i1->hi_as_long()); + } + return TypeInteger::make(lo, hi, MAX2(i1->_widen, i2->_widen), bt); +} - return TypeInt::make( i1->get_con() % i2->get_con() ); +const Type* ModINode::Value(PhaseGVN* phase) const { + return mod_value(phase, in(1), in(2), T_INT); } //============================================================================= @@ -1464,43 +1496,7 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { //------------------------------Value------------------------------------------ const Type* ModLNode::Value(PhaseGVN* phase) const { - // Either input is TOP ==> the result is TOP - const Type *t1 = phase->type( in(1) ); - const Type *t2 = phase->type( in(2) ); - if( t1 == Type::TOP ) return Type::TOP; - if( t2 == Type::TOP ) return Type::TOP; - - // We always generate the dynamic check for 0. - // 0 MOD X is 0 - if( t1 == TypeLong::ZERO ) return TypeLong::ZERO; - // X MOD X is 0 - if (in(1) == in(2)) { - return TypeLong::ZERO; - } - - // Either input is BOTTOM ==> the result is the local BOTTOM - const Type *bot = bottom_type(); - if( (t1 == bot) || (t2 == bot) || - (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) - return bot; - - const TypeLong *i1 = t1->is_long(); - const TypeLong *i2 = t2->is_long(); - if( !i1->is_con() || !i2->is_con() ) { - if( i1->_lo >= CONST64(0) && i2->_lo >= CONST64(0) ) - return TypeLong::POS; - // If both numbers are not constants, we know little. - return TypeLong::LONG; - } - // Mod by zero? Throw exception at runtime! - if( !i2->get_con() ) return TypeLong::POS; - - // We must be modulo'ing 2 float constants. - // Check for min_jint % '-1', result is defined to be '0'. - if( i1->get_con() == min_jlong && i2->get_con() == -1 ) - return TypeLong::ZERO; - - return TypeLong::make( i1->get_con() % i2->get_con() ); + return mod_value(phase, in(1), in(2), T_LONG); } Node *UModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { diff --git a/test/hotspot/jtreg/compiler/c2/gvn/ModINodeValueTests.java b/test/hotspot/jtreg/compiler/c2/gvn/ModINodeValueTests.java new file mode 100644 index 00000000000..7870ce10910 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/gvn/ModINodeValueTests.java @@ -0,0 +1,292 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package compiler.c2.gvn; + +import compiler.lib.generators.Generator; +import compiler.lib.generators.Generators; +import compiler.lib.generators.RestrictableGenerator; +import compiler.lib.ir_framework.DontCompile; +import compiler.lib.ir_framework.ForceInline; +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.IRNode; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; +import jdk.test.lib.Asserts; + +/* + * @test + * @bug 8356813 + * @summary Test that Value method of ModINode is working as expected. + * @key randomness + * @library /test/lib / + * @run driver compiler.c2.gvn.ModINodeValueTests + */ +public class ModINodeValueTests { + private static final RestrictableGenerator INT_GEN = Generators.G.ints(); + private static final int POS_INT = INT_GEN.restricted(1, Integer.MAX_VALUE).next(); + private static final int NEG_INT = INT_GEN.restricted(Integer.MIN_VALUE, -1).next(); + + public static void main(String[] args) { + TestFramework.run(); + } + + @Run(test = { + "nonNegativeDividend", "nonNegativeDividendInRange", + "negativeDividend", "negativeDividendInRange", + "modByKnownBoundsUpper", "modByKnownBoundsUpperInRange", + "modByKnownBoundsLower", "modByKnownBoundsLowerInRange", + "modByKnownBoundsLimitedByDividendUpper", "modByKnownBoundsLimitedByDividendUpperInRange", + "modByKnownBoundsLimitedByDividendLower", "modByKnownBoundsLimitedByDividendLowerInRange", + "testRandomLimits" + }) + public void runMethod() { + int a = INT_GEN.next(); + int b = INT_GEN.next(); + + int min = Integer.MIN_VALUE; + int max = Integer.MAX_VALUE; + + assertResult(0, 0); + assertResult(a, b); + assertResult(min, min); + assertResult(max, max); + } + + @DontCompile + public void assertResult(int x, int y) { + Asserts.assertEQ(x != 0 && POS_INT % x < 0, nonNegativeDividend(x)); + Asserts.assertEQ(x != 0 && POS_INT % x <= 0, nonNegativeDividendInRange(x)); + Asserts.assertEQ(x != 0 && NEG_INT % x > 0, negativeDividend(x)); + Asserts.assertEQ(x != 0 && NEG_INT % x >= 0, negativeDividendInRange(x)); + Asserts.assertEQ(x % (((byte) y) + 129) > 255, modByKnownBoundsUpper(x, y)); + Asserts.assertEQ(x % (((byte) y) + 129) >= 255, modByKnownBoundsUpperInRange(x, y)); + Asserts.assertEQ(x % (((byte) y) + 129) < -255, modByKnownBoundsLower(x, y)); + Asserts.assertEQ(x % (((byte) y) + 129) <= -255, modByKnownBoundsLowerInRange(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1) > 127, modByKnownBoundsLimitedByDividendUpper(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1) >= 127, modByKnownBoundsLimitedByDividendUpperInRange(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1) < -128, modByKnownBoundsLimitedByDividendLower(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1) <= -128, modByKnownBoundsLimitedByDividendLowerInRange(x, y)); + + int res; + try { + res = testRandomLimitsInterpreted(x, y); + } catch (ArithmeticException _) { + try { + testRandomLimits(x, y); + Asserts.fail("Expected ArithmeticException"); + return; // unreachable + } catch (ArithmeticException _) { + return; // test succeeded, no result to assert + } + } + Asserts.assertEQ(res, testRandomLimits(x, y)); + } + + @Test + @IR(failOn = {IRNode.MOD_I, IRNode.CMP_I}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., POS_INT % x < 0 => false. + public boolean nonNegativeDividend(int x) { + return x != 0 && POS_INT % x < 0; + } + + @Test + @IR(counts = {IRNode.MOD_I, "1"}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., POS_INT % x < 0 => false. + // This uses <= to verify the % is not optimized away + public boolean nonNegativeDividendInRange(int x) { + return x != 0 && POS_INT % x <= 0; + } + + @Test + @IR(failOn = {IRNode.MOD_I, IRNode.CMP_I}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., NEG_INT % x > 0 => false. + public boolean negativeDividend(int x) { + return x != 0 && NEG_INT % x > 0; + } + + @Test + @IR(counts = {IRNode.MOD_I, "1"}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., NEG_INT % x > 0 => false. + // This uses >= to verify the % is not optimized away + public boolean negativeDividendInRange(int x) { + return x != 0 && NEG_INT % x >= 0; + } + + @Test + @IR(failOn = {IRNode.MOD_I, IRNode.CMP_I}) + // The magnitude of the result is less than the divisor. + public boolean modByKnownBoundsUpper(int x, int y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + return x % (((byte) y) + 129) > 255; + } + + @Test + @IR(counts = {IRNode.MOD_I, "1"}) + // The magnitude of the result is less than the divisor. + public boolean modByKnownBoundsUpperInRange(int x, int y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + // in bounds, cannot optimize + return x % (((byte) y) + 129) >= 255; + } + + @Test + @IR(failOn = {IRNode.MOD_I, IRNode.CMP_I}) + // The magnitude of the result is less than the divisor + public boolean modByKnownBoundsLower(int x, int y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + return x % (((byte) y) + 129) < -255; + } + + @Test + @IR(counts = {IRNode.MOD_I, "1"}) + // The magnitude of the result is less than the divisor + public boolean modByKnownBoundsLowerInRange(int x, int y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + // in bounds, cannot optimize + return x % (((byte) y) + 129) <= -255; + } + + @Test + @IR(failOn = {IRNode.MOD_I, IRNode.CMP_I}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendUpper(int x, int y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + return ((byte) x) % (((char) y) + 1) > 127; + } + + @Test + @IR(counts = {IRNode.MOD_I, "1"}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendUpperInRange(int x, int y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + // in bounds, cannot optimize + return ((byte) x) % (((char) y) + 1) >= 127; + } + + @Test + @IR(failOn = {IRNode.MOD_I, IRNode.CMP_I}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendLower(int x, int y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + return ((byte) x) % (((char) y) + 1) < -128; + } + + @Test + @IR(counts = {IRNode.MOD_I, "1"}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendLowerInRange(int x, int y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + // in bounds, cannot optimize + return ((byte) x) % (((char) y) + 1) <= -128; + } + + private static final int LIMIT_1 = INT_GEN.next(); + private static final int LIMIT_2 = INT_GEN.next(); + private static final int LIMIT_3 = INT_GEN.next(); + private static final int LIMIT_4 = INT_GEN.next(); + private static final int LIMIT_5 = INT_GEN.next(); + private static final int LIMIT_6 = INT_GEN.next(); + private static final int LIMIT_7 = INT_GEN.next(); + private static final int LIMIT_8 = INT_GEN.next(); + private static final Range RANGE_1 = Range.generate(INT_GEN); + private static final Range RANGE_2 = Range.generate(INT_GEN); + + @Test + public int testRandomLimits(int x, int y) { + x = RANGE_1.clamp(x); + y = RANGE_2.clamp(y); + int z = x % y; + + int sum = 0; + if (z < LIMIT_1) sum += 1; + if (z < LIMIT_2) sum += 2; + if (z < LIMIT_3) sum += 4; + if (z < LIMIT_4) sum += 8; + if (z > LIMIT_5) sum += 16; + if (z > LIMIT_6) sum += 32; + if (z > LIMIT_7) sum += 64; + if (z > LIMIT_8) sum += 128; + + return sum; + } + + @DontCompile + public int testRandomLimitsInterpreted(int x, int y) { + x = RANGE_1.clamp(x); + y = RANGE_2.clamp(y); + int z = x % y; + + int sum = 0; + if (z < LIMIT_1) sum += 1; + if (z < LIMIT_2) sum += 2; + if (z < LIMIT_3) sum += 4; + if (z < LIMIT_4) sum += 8; + if (z > LIMIT_5) sum += 16; + if (z > LIMIT_6) sum += 32; + if (z > LIMIT_7) sum += 64; + if (z > LIMIT_8) sum += 128; + + return sum; + } + + record Range(int lo, int hi) { + Range { + if (lo > hi) { + throw new IllegalArgumentException("lo > hi"); + } + } + + @ForceInline + int clamp(int v) { + return Math.min(hi, Math.max(v, lo)); + } + + static Range generate(Generator g) { + var a = g.next(); + var b = g.next(); + if (a > b) { + var tmp = a; + a = b; + b = tmp; + } + return new Range(a, b); + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/gvn/ModLNodeValueTests.java b/test/hotspot/jtreg/compiler/c2/gvn/ModLNodeValueTests.java new file mode 100644 index 00000000000..a6eef6d3326 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/gvn/ModLNodeValueTests.java @@ -0,0 +1,292 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package compiler.c2.gvn; + +import compiler.lib.generators.Generator; +import compiler.lib.generators.Generators; +import compiler.lib.ir_framework.DontCompile; +import compiler.lib.ir_framework.ForceInline; +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.IRNode; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; +import jdk.test.lib.Asserts; + +/* + * @test + * @bug 8356813 + * @summary Test that Value method of ModLNode is working as expected. + * @key randomness + * @library /test/lib / + * @run driver compiler.c2.gvn.ModLNodeValueTests + */ +public class ModLNodeValueTests { + private static final Generator LONG_GEN = Generators.G.longs(); + private static final long POS_LONG = Generators.G.longs().restricted(1L, Long.MAX_VALUE).next(); + private static final long NEG_LONG = Generators.G.longs().restricted(Long.MIN_VALUE, -1L).next(); + + public static void main(String[] args) { + TestFramework.run(); + } + + @Run(test = { + "nonNegativeDividend", "nonNegativeDividendInRange", + "negativeDividend", "negativeDividendInRange", + "modByKnownBoundsUpper", "modByKnownBoundsUpperInRange", + "modByKnownBoundsLower", "modByKnownBoundsLowerInRange", + "modByKnownBoundsLimitedByDividendUpper", "modByKnownBoundsLimitedByDividendUpperInRange", + "modByKnownBoundsLimitedByDividendLower", "modByKnownBoundsLimitedByDividendLowerInRange", + "testRandomLimits" + }) + public void runMethod() { + long a = LONG_GEN.next(); + long b = LONG_GEN.next(); + + long min = Long.MIN_VALUE; + long max = Long.MAX_VALUE; + + assertResult(0, 0); + assertResult(a, b); + assertResult(min, min); + assertResult(max, max); + } + + @DontCompile + public void assertResult(long x, long y) { + Asserts.assertEQ(x != 0 && POS_LONG % x < 0, nonNegativeDividend(x)); + Asserts.assertEQ(x != 0 && POS_LONG % x <= 0, nonNegativeDividendInRange(x)); + Asserts.assertEQ(x != 0 && NEG_LONG % x > 0, negativeDividend(x)); + Asserts.assertEQ(x != 0 && NEG_LONG % x >= 0, negativeDividendInRange(x)); + Asserts.assertEQ(x % (((byte) y) + 129L) > 255, modByKnownBoundsUpper(x, y)); + Asserts.assertEQ(x % (((byte) y) + 129L) >= 255, modByKnownBoundsUpperInRange(x, y)); + Asserts.assertEQ(x % (((byte) y) + 129L) < -255, modByKnownBoundsLower(x, y)); + Asserts.assertEQ(x % (((byte) y) + 129L) <= -255, modByKnownBoundsLowerInRange(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1L) > 127, modByKnownBoundsLimitedByDividendUpper(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1L) >= 127, modByKnownBoundsLimitedByDividendUpperInRange(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1L) < -128, modByKnownBoundsLimitedByDividendLower(x, y)); + Asserts.assertEQ(((byte) x) % (((char) y) + 1L) <= -128, modByKnownBoundsLimitedByDividendLowerInRange(x, y)); + + int res; + try { + res = testRandomLimitsInterpreted(x, y); + } catch (ArithmeticException _) { + try { + testRandomLimits(x, y); + Asserts.fail("Expected ArithmeticException"); + return; // unreachable + } catch (ArithmeticException _) { + return; // test succeeded, no result to assert + } + } + Asserts.assertEQ(res, testRandomLimits(x, y)); + } + + @Test + @IR(failOn = {IRNode.MOD_L, IRNode.CMP_L}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., posVal % x < 0 => false. + public boolean nonNegativeDividend(long x) { + return x != 0 && POS_LONG % x < 0; + } + + @Test + @IR(counts = {IRNode.MOD_L, "1"}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., posVal % x < 0 => false. + // This uses <= to verify the % is not optimized away + public boolean nonNegativeDividendInRange(long x) { + return x != 0 && POS_LONG % x <= 0; + } + + @Test + @IR(failOn = {IRNode.MOD_L, IRNode.CMP_L}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., negValue % x > 0 => false. + public boolean negativeDividend(long x) { + return x != 0 && NEG_LONG % x > 0; + } + + @Test + @IR(counts = {IRNode.MOD_L, "1"}) + // The sign of the result of % is the same as the sign of the dividend, + // i.e., negValue % x > 0 => false. + // This uses >= to verify the % is not optimized away + public boolean negativeDividendInRange(long x) { + return x != 0 && NEG_LONG % x >= 0; + } + + @Test + @IR(failOn = {IRNode.MOD_L, IRNode.CMP_L}) + // The magnitude of the result is less than the divisor. + public boolean modByKnownBoundsUpper(long x, long y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + return x % (((byte) y) + 129L) > 255; + } + + @Test + @IR(counts = {IRNode.MOD_L, "1"}) + // The magnitude of the result is less than the divisor. + public boolean modByKnownBoundsUpperInRange(long x, long y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + // in bounds, cannot optimize + return x % (((byte) y) + 129L) >= 255; + } + + @Test + @IR(failOn = {IRNode.MOD_L, IRNode.CMP_L}) + // The magnitude of the result is less than the divisor + public boolean modByKnownBoundsLower(long x, long y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + return x % (((byte) y) + 129L) < -255; + } + + @Test + @IR(counts = {IRNode.MOD_L, "1"}) + // The magnitude of the result is less than the divisor + public boolean modByKnownBoundsLowerInRange(long x, long y) { + // d = ((byte) y) + 129 => [1, 256] divisor + // x % d => [-255, 255] + // in bounds, cannot optimize + return x % (((byte) y) + 129L) <= -255; + } + + @Test + @IR(failOn = {IRNode.MOD_L, IRNode.CMP_L}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendUpper(long x, long y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + return ((byte) x) % (((char) y) + 1L) > 127; + } + + @Test + @IR(counts = {IRNode.MOD_L, "1"}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendUpperInRange(long x, long y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + // in bounds, cannot optimize + return ((byte) x) % (((char) y) + 1L) >= 127; + } + + @Test + @IR(failOn = {IRNode.MOD_L, IRNode.CMP_L}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendLower(long x, long y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + return ((byte) x) % (((char) y) + 1L) < -128; + } + + @Test + @IR(counts = {IRNode.MOD_L, "1"}) + // The result is closer to zero than or equal to the dividend. + public boolean modByKnownBoundsLimitedByDividendLowerInRange(long x, long y) { + // d = ((char) y) + 1 => [1, 65536] divisor + // e = ((byte) x) => [-128, 127] + // e % d => [-128, 127] + // in bounds, cannot optimize + return ((byte) x) % (((char) y) + 1L) <= -128; + } + + + private static final long LIMIT_1 = LONG_GEN.next(); + private static final long LIMIT_2 = LONG_GEN.next(); + private static final long LIMIT_3 = LONG_GEN.next(); + private static final long LIMIT_4 = LONG_GEN.next(); + private static final long LIMIT_5 = LONG_GEN.next(); + private static final long LIMIT_6 = LONG_GEN.next(); + private static final long LIMIT_7 = LONG_GEN.next(); + private static final long LIMIT_8 = LONG_GEN.next(); + private static final Range RANGE_1 = Range.generate(LONG_GEN); + private static final Range RANGE_2 = Range.generate(LONG_GEN); + + @Test + public int testRandomLimits(long x, long y) { + x = RANGE_1.clamp(x); + y = RANGE_2.clamp(y); + long z = x % y; + + int sum = 0; + if (z < LIMIT_1) sum += 1; + if (z < LIMIT_2) sum += 2; + if (z < LIMIT_3) sum += 4; + if (z < LIMIT_4) sum += 8; + if (z > LIMIT_5) sum += 16; + if (z > LIMIT_6) sum += 32; + if (z > LIMIT_7) sum += 64; + if (z > LIMIT_8) sum += 128; + + return sum; + } + + @DontCompile + public int testRandomLimitsInterpreted(long x, long y) { + x = RANGE_1.clamp(x); + y = RANGE_2.clamp(y); + long z = x % y; + + int sum = 0; + if (z < LIMIT_1) sum += 1; + if (z < LIMIT_2) sum += 2; + if (z < LIMIT_3) sum += 4; + if (z < LIMIT_4) sum += 8; + if (z > LIMIT_5) sum += 16; + if (z > LIMIT_6) sum += 32; + if (z > LIMIT_7) sum += 64; + if (z > LIMIT_8) sum += 128; + + return sum; + } + + record Range(long lo, long hi) { + Range { + if (lo > hi) { + throw new IllegalArgumentException("lo > hi"); + } + } + + @ForceInline + long clamp(long v) { + return Math.min(hi, Math.max(v, lo)); + } + + static Range generate(Generator g) { + var a = g.next(); + var b = g.next(); + if (a > b) { + var tmp = a; + a = b; + b = tmp; + } + return new Range(a, b); + } + } +} From 0bc3705948b1bb8f327dc48c4dbd85d22d66f036 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Tue, 16 Sep 2025 13:16:48 +0000 Subject: [PATCH 100/120] 8367597: Runtime.exit logging failed: Cannot invoke "java.lang.Module.getClassLoader()" because "m" is null Reviewed-by: alanb, rriggs --- src/java.base/share/classes/java/lang/Shutdown.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Shutdown.java b/src/java.base/share/classes/java/lang/Shutdown.java index 36cf471a575..87c4732a5ce 100644 --- a/src/java.base/share/classes/java/lang/Shutdown.java +++ b/src/java.base/share/classes/java/lang/Shutdown.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, 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 @@ -157,8 +157,10 @@ class Shutdown { * which should pass a nonzero status code. */ static void exit(int status) { - logRuntimeExit(status); // Log without holding the lock; - + // log only if VM is fully initialized + if (VM.isBooted()) { + logRuntimeExit(status); // Log without holding the lock; + } synchronized (Shutdown.class) { /* Synchronize on the class object, causing any other thread * that attempts to initiate shutdown to stall indefinitely From c82070e6357a1b49f2887ab22267393ba87d9352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20H=C3=A4ssig?= Date: Tue, 16 Sep 2025 13:19:12 +0000 Subject: [PATCH 101/120] 8366775: TestCompileTaskTimeout should use timeoutFactor Reviewed-by: chagedorn, rcastanedalo, mbaesken --- .../jtreg/compiler/arguments/TestCompileTaskTimeout.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/arguments/TestCompileTaskTimeout.java b/test/hotspot/jtreg/compiler/arguments/TestCompileTaskTimeout.java index cb52e5a24a0..f19223e6dce 100644 --- a/test/hotspot/jtreg/compiler/arguments/TestCompileTaskTimeout.java +++ b/test/hotspot/jtreg/compiler/arguments/TestCompileTaskTimeout.java @@ -37,6 +37,11 @@ import jdk.test.lib.process.ProcessTools; public class TestCompileTaskTimeout { public static void main(String[] args) throws Throwable { + double timeoutFactor = 1.0; + try { + timeoutFactor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0")); + } catch (NumberFormatException ignored) {} + ProcessTools.executeTestJava("-Xcomp", "-XX:CompileTaskTimeout=1", "--version") .shouldHaveExitValue(134) .shouldContain("timed out after"); @@ -49,7 +54,8 @@ public class TestCompileTaskTimeout { .shouldHaveExitValue(134) .shouldContain("timed out after"); - ProcessTools.executeTestJava("-Xcomp", "-XX:CompileTaskTimeout=2000", "--version") + int timeout = (int)(500.0 * timeoutFactor); + ProcessTools.executeTestJava("-Xcomp", "-XX:CompileTaskTimeout=" + timeout, "--version") .shouldHaveExitValue(0); } } From 58007c0bcc03f4609ce202cfb9f89b8438055dac Mon Sep 17 00:00:00 2001 From: Guanqiang Han Date: Tue, 16 Sep 2025 14:57:42 +0000 Subject: [PATCH 102/120] 8367619: String.format in outOfRangeException uses wrong format specifier for String argument Reviewed-by: fandreuzzi, rriggs, liach --- .../share/classes/jdk/internal/classfile/impl/Util.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java index 7e6384dd1a4..6411c939549 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java @@ -230,7 +230,7 @@ public final class Util { public static IllegalArgumentException outOfRangeException(int value, String fieldName, String typeName) { return new IllegalArgumentException( - String.format("%s out of range of %d: %d", fieldName, typeName, value)); + String.format("%s out of range of %s: %d", fieldName, typeName, value)); } /// Ensures the given mask won't be truncated when written as an access flag From 15d42c6d772d2c4cca1f21a947407fc0931aee64 Mon Sep 17 00:00:00 2001 From: Koushik Thirupattur Date: Tue, 16 Sep 2025 16:24:19 +0000 Subject: [PATCH 103/120] 8366978: dead code in SunCertPathBuilder Reviewed-by: mullan, hchao --- .../provider/certpath/SunCertPathBuilder.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java index c4e31cf7947..8b47c437dac 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, 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 @@ -637,18 +637,4 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { return (nextAltNameExt == null); } } - - /** - * Returns true if trust anchor certificate matches specified - * certificate constraints. - */ - private static boolean anchorIsTarget(TrustAnchor anchor, - CertSelector sel) - { - X509Certificate anchorCert = anchor.getTrustedCert(); - if (anchorCert != null) { - return sel.match(anchorCert); - } - return false; - } } From 075ebb4ee592c10879799a68ba79f782ee49b60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20H=C3=BCbner?= Date: Tue, 16 Sep 2025 16:53:21 +0000 Subject: [PATCH 104/120] 8366229: runtime/Thread/TooSmallStackSize.java runs with all collectors Reviewed-by: dholmes, shade --- test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java b/test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java index 09db906b151..6fd1da6f2ae 100644 --- a/test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java +++ b/test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java @@ -28,6 +28,7 @@ * VMThreadStackSize values should result in an error message that shows * the minimum stack size value for each thread type. * @library /test/lib + * @requires vm.flagless * @modules java.base/jdk.internal.misc * java.management * @run driver TooSmallStackSize From c41add8d3e24be5f469f18cfbf0f476f2baf63a6 Mon Sep 17 00:00:00 2001 From: Srinivas Vamsi Parasa Date: Tue, 16 Sep 2025 18:13:34 +0000 Subject: [PATCH 105/120] 8354348: Enable Extended EVEX to REX2/REX demotion for commutative operations with same dst and src2 Reviewed-by: jbhateja, epeter, sviswanathan --- src/hotspot/cpu/x86/assembler_x86.cpp | 176 +- src/hotspot/cpu/x86/assembler_x86.hpp | 9 +- test/hotspot/gtest/x86/asmtest.out.h | 5268 +++++++++++++------------ test/hotspot/gtest/x86/x86-asmtest.py | 30 +- 4 files changed, 2916 insertions(+), 2567 deletions(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index d1b6897f287..49d40447f9f 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -1398,11 +1398,7 @@ void Assembler::addl(Address dst, Register src) { void Assembler::eaddl(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x01); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x01, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::addl(Register dst, int32_t imm32) { @@ -1432,11 +1428,7 @@ void Assembler::addl(Register dst, Register src) { } void Assembler::eaddl(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void)emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_arith(0x03, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x03, 0xC0, no_flags, true /* is_commutative */); } void Assembler::addr_nop_4() { @@ -1657,17 +1649,18 @@ void Assembler::eandl(Register dst, Register src1, Address src2, bool no_flags) emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x23, no_flags); } +void Assembler::eandl(Register dst, Address src1, Register src2, bool no_flags) { + InstructionMark im(this); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x21, no_flags, false /* is_map1 */, true /* is_commutative */); +} + void Assembler::andl(Register dst, Register src) { (void) prefix_and_encode(dst->encoding(), src->encoding()); emit_arith(0x23, 0xC0, dst, src); } void Assembler::eandl(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_arith(0x23, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x23, 0xC0, no_flags, true /* is_commutative */); } void Assembler::andnl(Register dst, Register src1, Register src2) { @@ -2519,7 +2512,7 @@ void Assembler::imull(Register dst, Register src) { } void Assembler::eimull(Register dst, Register src1, Register src2, bool no_flags) { - emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0xAF, no_flags, true /* is_map1 */, true /* swap */); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0xAF, no_flags, true /* is_map1 */, true /* swap */, true /* is_commutative */); } void Assembler::imull(Register dst, Address src, int32_t value) { @@ -4419,11 +4412,7 @@ void Assembler::enotl(Register dst, Register src) { } void Assembler::eorw(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_arith(0x0B, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_66, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_16bit, 0x0B, 0xC0, no_flags, true /* is_commutative */); } void Assembler::orl(Address dst, int32_t imm32) { @@ -4467,11 +4456,7 @@ void Assembler::orl(Register dst, Register src) { } void Assembler::eorl(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_arith(0x0B, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x0B, 0xC0, no_flags, true /* is_commutative */); } void Assembler::orl(Address dst, Register src) { @@ -4483,11 +4468,7 @@ void Assembler::orl(Address dst, Register src) { void Assembler::eorl(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x09); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x09, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::orb(Address dst, int imm8) { @@ -4517,11 +4498,7 @@ void Assembler::orb(Address dst, Register src) { void Assembler::eorb(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_8bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x08); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_8bit, 0x08, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::packsswb(XMMRegister dst, XMMRegister src) { @@ -7323,11 +7300,7 @@ void Assembler::xorl(Register dst, Register src) { } void Assembler::exorl(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_arith(0x33, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x33, 0xC0, no_flags, true /* is_commutative */); } void Assembler::xorl(Address dst, Register src) { @@ -7339,11 +7312,7 @@ void Assembler::xorl(Address dst, Register src) { void Assembler::exorl(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x31); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x31, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::xorb(Register dst, Address src) { @@ -7367,11 +7336,7 @@ void Assembler::xorb(Address dst, Register src) { void Assembler::exorb(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_8bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x30); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_8bit, 0x30, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::xorw(Register dst, Address src) { @@ -12955,6 +12920,31 @@ void Assembler::eevex_prefix_ndd(Address adr, int ndd_enc, int xreg_enc, VexSimd vex_prefix(adr, ndd_enc, xreg_enc, pre, opc, attributes, /* nds_is_ndd */ true, no_flags); } +void Assembler::emit_eevex_or_demote(Register dst, Address src1, Register src2, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags, bool is_map1, bool is_commutative) { + if (is_commutative && is_demotable(no_flags, dst->encoding(), src2->encoding())) { + // Opcode byte adjustment due to mismatch between NDD and equivalent demotable variant + opcode_byte += 2; + if (size == EVEX_64bit) { + emit_prefix_and_int8(get_prefixq(src1, dst, is_map1), opcode_byte); + } else { + // For 32-bit, 16-bit and 8-bit + if (size == EVEX_16bit) { + emit_int8(0x66); + } + prefix(src1, dst, false, is_map1); + emit_int8(opcode_byte); + } + } else { + bool vex_w = (size == EVEX_64bit) ? true : false; + InstructionAttr attributes(AVX_128bit, vex_w, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, size); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), pre, opc, &attributes, no_flags); + emit_int8(opcode_byte); + } + emit_operand(src2, src1, 0); +} + void Assembler::emit_eevex_or_demote(Register dst, Register src1, Address src2, VexSimdPrefix pre, VexOpcode opc, int size, int opcode_byte, bool no_flags, bool is_map1) { if (is_demotable(no_flags, dst->encoding(), src1->encoding())) { @@ -13055,18 +13045,20 @@ void Assembler::emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, int8 } void Assembler::emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, - int size, int opcode_byte, bool no_flags, bool is_map1, bool swap) { + int size, int opcode_byte, bool no_flags, bool is_map1, bool swap, bool is_commutative) { int encode; bool is_prefixq = (size == EVEX_64bit) ? true : false; - if (is_demotable(no_flags, dst_enc, nds_enc)) { + bool first_operand_demotable = is_demotable(no_flags, dst_enc, nds_enc); + bool second_operand_demotable = is_commutative && is_demotable(no_flags, dst_enc, src_enc); + if (first_operand_demotable || second_operand_demotable) { if (size == EVEX_16bit) { emit_int8(0x66); } - + int src = first_operand_demotable ? src_enc : nds_enc; if (swap) { - encode = is_prefixq ? prefixq_and_encode(dst_enc, src_enc, is_map1) : prefix_and_encode(dst_enc, src_enc, is_map1); + encode = is_prefixq ? prefixq_and_encode(dst_enc, src, is_map1) : prefix_and_encode(dst_enc, src, is_map1); } else { - encode = is_prefixq ? prefixq_and_encode(src_enc, dst_enc, is_map1) : prefix_and_encode(src_enc, dst_enc, is_map1); + encode = is_prefixq ? prefixq_and_encode(src, dst_enc, is_map1) : prefix_and_encode(src, dst_enc, is_map1); } emit_opcode_prefix_and_encoding((unsigned char)opcode_byte, 0xC0, encode); } else { @@ -13114,6 +13106,26 @@ int Assembler::eevex_prefix_and_encode_nf(int dst_enc, int nds_enc, int src_enc, return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, attributes, /* src_is_gpr */ true, /* nds_is_ndd */ false, no_flags); } +void Assembler::emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register src1, Register src2, VexSimdPrefix pre, VexOpcode opc, + int size, int op1, int op2, bool no_flags, bool is_commutative) { + bool demotable = is_demotable(no_flags, dst->encoding(), src1->encoding()); + if (!demotable && is_commutative) { + if (is_demotable(no_flags, dst->encoding(), src2->encoding())) { + // swap src1 and src2 + Register tmp = src1; + src1 = src2; + src2 = tmp; + } + } + bool vex_w = (size == EVEX_64bit) ? true : false; + bool use_prefixq = vex_w; + InstructionAttr attributes(AVX_128bit, vex_w, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + // NDD shares its encoding bits with NDS bits for regular EVEX instruction. + // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. + (void)emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), pre, opc, &attributes, no_flags, use_prefixq); + emit_arith(op1, op2, src1, src2); +} + void Assembler::emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register nds, int32_t imm32, VexSimdPrefix pre, VexOpcode opc, int size, int op1, int op2, bool no_flags) { int dst_enc = dst->encoding(); @@ -13124,7 +13136,6 @@ void Assembler::emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register nds } else { bool vex_w = (size == EVEX_64bit) ? true : false; InstructionAttr attributes(AVX_128bit, vex_w, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - //attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, size); attributes.set_is_evex_instruction(); vex_prefix_and_encode(0, dst_enc, nds_enc, pre, opc, &attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); @@ -14623,11 +14634,7 @@ void Assembler::addq(Address dst, Register src) { void Assembler::eaddq(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x01); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x01, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::addq(Register dst, int32_t imm32) { @@ -14656,11 +14663,7 @@ void Assembler::addq(Register dst, Register src) { } void Assembler::eaddq(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); - emit_arith(0x03, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x03, 0xC0, no_flags, true /* is_commutative */); } void Assembler::adcxq(Register dst, Register src) { @@ -14753,11 +14756,7 @@ void Assembler::andq(Register dst, Register src) { } void Assembler::eandq(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); - emit_arith(0x23, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x23, 0xC0, no_flags, true /* is_commutative */); } void Assembler::andq(Address dst, Register src) { @@ -14768,11 +14767,7 @@ void Assembler::andq(Address dst, Register src) { void Assembler::eandq(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x21); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x21, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::andnq(Register dst, Register src1, Register src2) { @@ -15118,7 +15113,7 @@ void Assembler::eimulq(Register dst, Register src, bool no_flags) { } void Assembler::eimulq(Register dst, Register src1, Register src2, bool no_flags) { - emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0xAF, no_flags, true /* is_map1 */, true /* swap */); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0xAF, no_flags, true /* is_map1 */, true /* swap */, true /* is_commutative */); } void Assembler::imulq(Register src) { @@ -15580,11 +15575,7 @@ void Assembler::orq(Address dst, Register src) { void Assembler::eorq(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x09); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x09, no_flags, false /* is_map1 */, true /* is_commutative */); } void Assembler::orq(Register dst, int32_t imm32) { @@ -15624,13 +15615,8 @@ void Assembler::orq(Register dst, Register src) { } void Assembler::eorq(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); - emit_arith(0x0B, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x0B, 0xC0, no_flags, true /* is_commutative */); } - void Assembler::popcntq(Register dst, Address src) { assert(VM_Version::supports_popcnt(), "must support"); InstructionMark im(this); @@ -16372,11 +16358,7 @@ void Assembler::xorq(Register dst, Register src) { } void Assembler::exorq(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); - emit_arith(0x33, 0xC0, src1, src2); + emit_eevex_prefix_or_demote_arith_ndd(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x33, 0xC0, no_flags, true /* is_commutative */); } void Assembler::xorq(Register dst, Address src) { @@ -16430,11 +16412,7 @@ void Assembler::esetzucc(Condition cc, Register dst) { void Assembler::exorq(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); - emit_int8(0x31); - emit_operand(src2, src1, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x31, no_flags, false /* is_map1 */, true /* is_commutative */); } void InstructionAttr::set_address_attributes(int tuple_type, int input_size_in_bits) { diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 45c24f8c832..99dade412b2 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -807,14 +807,20 @@ private: int emit_eevex_prefix_or_demote_ndd(int dst_enc, int nds_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags = false, bool use_prefixq = false); + void emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register src1, Register src2, VexSimdPrefix pre, VexOpcode opc, + int size, int op1, int op2, bool no_flags = false, bool is_commutative = false); + void emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register nds, int32_t imm32, VexSimdPrefix pre, VexOpcode opc, int size, int op1, int op2, bool no_flags); void emit_eevex_or_demote(Register dst, Register src1, Address src2, VexSimdPrefix pre, VexOpcode opc, int size, int opcode_byte, bool no_flags = false, bool is_map1 = false); + void emit_eevex_or_demote(Register dst, Address src1, Register src2, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags = false, bool is_map1 = false, bool is_commutative = false); + void emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, - int size, int opcode_byte, bool no_flags, bool is_map1 = false, bool swap = false); + int size, int opcode_byte, bool no_flags, bool is_map1 = false, bool swap = false, bool is_commutative = false); void emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, int8_t imm8, VexSimdPrefix pre, VexOpcode opc, int size, int opcode_byte, bool no_flags, bool is_map1 = false); @@ -1149,6 +1155,7 @@ private: void eandl(Register dst, Register src, int32_t imm32, bool no_flags); void andl(Register dst, Address src); void eandl(Register dst, Register src1, Address src2, bool no_flags); + void eandl(Register dst, Address src1, Register src2, bool no_flags); void andl(Register dst, Register src); void eandl(Register dst, Register src1, Register src2, bool no_flags); void andl(Address dst, Register src); diff --git a/test/hotspot/gtest/x86/asmtest.out.h b/test/hotspot/gtest/x86/asmtest.out.h index a2071bafc20..1f5aae4f636 100644 --- a/test/hotspot/gtest/x86/asmtest.out.h +++ b/test/hotspot/gtest/x86/asmtest.out.h @@ -289,667 +289,751 @@ __ exorl(rdx, Address(r10, r16, (Address::ScaleFactor)2, -0x161e1d47), 16777216, false); // {EVEX}xor edx, dword ptr [r10+r16*4-0x161e1d47], 16777216 IID265 __ exorl(rdx, Address(r29, r23, (Address::ScaleFactor)1, +0x1b34e2f8), 16777216, true); // {NF}xor edx, dword ptr [r29+r23*2+0x1b34e2f8], 16777216 IID266 __ eaddl(r19, Address(r27, r31, (Address::ScaleFactor)0, +0x1f3ce7d8), r29, false); // {EVEX}add r19d, dword ptr [r27+r31*1+0x1f3ce7d8], r29d IID267 - __ eaddl(r28, Address(r24, rcx, (Address::ScaleFactor)3, -0x6053edc2), r28, false); // {EVEX}add r28d, dword ptr [r24+rcx*8-0x6053edc2], r28d IID268 + __ eaddl(r28, Address(r24, rcx, (Address::ScaleFactor)3, -0x6053edc2), r28, false); // add r28d, dword ptr [r24+rcx*8-0x6053edc2] IID268 __ eaddl(r17, Address(r18, r24, (Address::ScaleFactor)3, -0x1bf71f78), r29, true); // {NF}add r17d, dword ptr [r18+r24*8-0x1bf71f78], r29d IID269 __ eaddl(rcx, Address(r15, r28, (Address::ScaleFactor)1, +0x15b8216), rcx, true); // {NF}add ecx, dword ptr [r15+r28*2+0x15b8216], ecx IID270 - __ eorl(r30, Address(rbx, rdx, (Address::ScaleFactor)3, -0x463540b4), r28, false); // {EVEX}or r30d, dword ptr [rbx+rdx*8-0x463540b4], r28d IID271 - __ eorl(r18, Address(r28, r10, (Address::ScaleFactor)3, +0x3523a73b), r18, false); // {EVEX}or r18d, dword ptr [r28+r10*8+0x3523a73b], r18d IID272 - __ eorl(r9, Address(r15, r15, (Address::ScaleFactor)1, -0x2a0bdd56), r21, true); // {NF}or r9d, dword ptr [r15+r15*2-0x2a0bdd56], r21d IID273 - __ eorl(r16, Address(r23, -0x165064ff), r16, true); // {NF}or r16d, dword ptr [r23-0x165064ff], r16d IID274 - __ eorb(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false); // {EVEX}or r28b, byte ptr [r30+r11*1+0x17281e3a], r20b IID275 - __ eorb(rdx, Address(rbx, r31, (Address::ScaleFactor)2, +0x2477b5bb), rdx, false); // {EVEX}or dl, byte ptr [rbx+r31*4+0x2477b5bb], dl IID276 - __ eorb(r16, Address(r11, rcx, (Address::ScaleFactor)1, -0x3175d1af), r24, true); // {NF}or r16b, byte ptr [r11+rcx*2-0x3175d1af], r24b IID277 - __ eorb(rbx, Address(r11, r20, (Address::ScaleFactor)3, -0x22d67bd3), rbx, true); // {NF}or bl, byte ptr [r11+r20*8-0x22d67bd3], bl IID278 - __ esubl(r26, Address(r27, r30, (Address::ScaleFactor)1, -0x3d9bce2e), rdx, false); // {EVEX}sub r26d, dword ptr [r27+r30*2-0x3d9bce2e], edx IID279 - __ esubl(r31, Address(r22, r29, (Address::ScaleFactor)1, +0x14218519), r31, false); // {EVEX}sub r31d, dword ptr [r22+r29*2+0x14218519], r31d IID280 - __ esubl(r21, Address(r9, -0x1050127a), r13, true); // {NF}sub r21d, dword ptr [r9-0x1050127a], r13d IID281 - __ esubl(r31, Address(r9, r8, (Address::ScaleFactor)0, -0xae18961), r31, true); // {NF}sub r31d, dword ptr [r9+r8*1-0xae18961], r31d IID282 - __ exorl(r15, Address(r18, +0x5c2bbce5), r12, false); // {EVEX}xor r15d, dword ptr [r18+0x5c2bbce5], r12d IID283 - __ exorl(r27, Address(r25, r23, (Address::ScaleFactor)0, +0x5c6078b3), r27, false); // {EVEX}xor r27d, dword ptr [r25+r23*1+0x5c6078b3], r27d IID284 - __ exorl(r18, Address(r8, rdx, (Address::ScaleFactor)3, -0x9ed3881), r14, true); // {NF}xor r18d, dword ptr [r8+rdx*8-0x9ed3881], r14d IID285 - __ exorl(r9, Address(r15, +0x775acdad), r9, true); // {NF}xor r9d, dword ptr [r15+0x775acdad], r9d IID286 - __ exorb(r21, Address(r18, r26, (Address::ScaleFactor)1, +0x2fe31fd5), r23, false); // {EVEX}xor r21b, byte ptr [r18+r26*2+0x2fe31fd5], r23b IID287 - __ exorb(r10, Address(r27, +0xa3150de), r10, false); // {EVEX}xor r10b, byte ptr [r27+0xa3150de], r10b IID288 - __ exorb(r18, Address(r22, r30, (Address::ScaleFactor)3, +0x1ad4e897), r24, true); // {NF}xor r18b, byte ptr [r22+r30*8+0x1ad4e897], r24b IID289 - __ exorb(r8, Address(r16, r20, (Address::ScaleFactor)0, +0x626eae82), r8, true); // {NF}xor r8b, byte ptr [r16+r20*1+0x626eae82], r8b IID290 - __ eaddl(r21, r15, 1048576, false); // {EVEX}add r21d, r15d, 1048576 IID291 - __ eaddl(rax, r18, 1048576, false); // {EVEX}add eax, r18d, 1048576 IID292 - __ eaddl(r18, r18, 256, false); // add r18d, 256 IID293 - __ eaddl(r13, r19, 16, true); // {NF}add r13d, r19d, 16 IID294 - __ eaddl(rax, r23, 16, true); // {NF}add eax, r23d, 16 IID295 - __ eaddl(r25, r25, 16777216, true); // {NF}add r25d, r25d, 16777216 IID296 - __ eandl(r29, r18, 1048576, false); // {EVEX}and r29d, r18d, 1048576 IID297 - __ eandl(rax, r14, 1048576, false); // {EVEX}and eax, r14d, 1048576 IID298 - __ eandl(r19, r19, 65536, false); // and r19d, 65536 IID299 - __ eandl(r27, r25, 1048576, true); // {NF}and r27d, r25d, 1048576 IID300 - __ eandl(rax, r20, 1048576, true); // {NF}and eax, r20d, 1048576 IID301 - __ eandl(r28, r28, 16, true); // {NF}and r28d, r28d, 16 IID302 - __ eimull(r31, r22, 4096, false); // {EVEX}imul r31d, r22d, 4096 IID303 + __ eandl(r30, Address(rbx, rdx, (Address::ScaleFactor)3, -0x463540b4), r28, false); // {EVEX}and r30d, dword ptr [rbx+rdx*8-0x463540b4], r28d IID271 + __ eandl(r18, Address(r28, r10, (Address::ScaleFactor)3, +0x3523a73b), r18, false); // and r18d, dword ptr [r28+r10*8+0x3523a73b] IID272 + __ eandl(r9, Address(r15, r15, (Address::ScaleFactor)1, -0x2a0bdd56), r21, true); // {NF}and r9d, dword ptr [r15+r15*2-0x2a0bdd56], r21d IID273 + __ eandl(r16, Address(r23, -0x165064ff), r16, true); // {NF}and r16d, dword ptr [r23-0x165064ff], r16d IID274 + __ eorl(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false); // {EVEX}or r28d, dword ptr [r30+r11*1+0x17281e3a], r20d IID275 + __ eorl(rdx, Address(rbx, r31, (Address::ScaleFactor)2, +0x2477b5bb), rdx, false); // or edx, dword ptr [rbx+r31*4+0x2477b5bb] IID276 + __ eorl(r16, Address(r11, rcx, (Address::ScaleFactor)1, -0x3175d1af), r24, true); // {NF}or r16d, dword ptr [r11+rcx*2-0x3175d1af], r24d IID277 + __ eorl(rbx, Address(r11, r20, (Address::ScaleFactor)3, -0x22d67bd3), rbx, true); // {NF}or ebx, dword ptr [r11+r20*8-0x22d67bd3], ebx IID278 + __ eorb(r26, Address(r27, r30, (Address::ScaleFactor)1, -0x3d9bce2e), rdx, false); // {EVEX}or r26b, byte ptr [r27+r30*2-0x3d9bce2e], dl IID279 + __ eorb(r31, Address(r22, r29, (Address::ScaleFactor)1, +0x14218519), r31, false); // or r31b, byte ptr [r22+r29*2+0x14218519] IID280 + __ eorb(r21, Address(r9, -0x1050127a), r13, true); // {NF}or r21b, byte ptr [r9-0x1050127a], r13b IID281 + __ eorb(r31, Address(r9, r8, (Address::ScaleFactor)0, -0xae18961), r31, true); // {NF}or r31b, byte ptr [r9+r8*1-0xae18961], r31b IID282 + __ esubl(r15, Address(r18, +0x5c2bbce5), r12, false); // {EVEX}sub r15d, dword ptr [r18+0x5c2bbce5], r12d IID283 + __ esubl(r27, Address(r25, r23, (Address::ScaleFactor)0, +0x5c6078b3), r27, false); // {EVEX}sub r27d, dword ptr [r25+r23*1+0x5c6078b3], r27d IID284 + __ esubl(r18, Address(r8, rdx, (Address::ScaleFactor)3, -0x9ed3881), r14, true); // {NF}sub r18d, dword ptr [r8+rdx*8-0x9ed3881], r14d IID285 + __ esubl(r9, Address(r15, +0x775acdad), r9, true); // {NF}sub r9d, dword ptr [r15+0x775acdad], r9d IID286 + __ exorl(r21, Address(r18, r26, (Address::ScaleFactor)1, +0x2fe31fd5), r23, false); // {EVEX}xor r21d, dword ptr [r18+r26*2+0x2fe31fd5], r23d IID287 + __ exorl(r10, Address(r27, +0xa3150de), r10, false); // xor r10d, dword ptr [r27+0xa3150de] IID288 + __ exorl(r18, Address(r22, r30, (Address::ScaleFactor)3, +0x1ad4e897), r24, true); // {NF}xor r18d, dword ptr [r22+r30*8+0x1ad4e897], r24d IID289 + __ exorl(r8, Address(r16, r20, (Address::ScaleFactor)0, +0x626eae82), r8, true); // {NF}xor r8d, dword ptr [r16+r20*1+0x626eae82], r8d IID290 + __ exorb(r16, Address(r21, r15, (Address::ScaleFactor)0, -0x1403b60d), r18, false); // {EVEX}xor r16b, byte ptr [r21+r15*1-0x1403b60d], r18b IID291 + __ exorb(r13, Address(r19, r23, (Address::ScaleFactor)2, +0x237ef1e1), r13, false); // xor r13b, byte ptr [r19+r23*4+0x237ef1e1] IID292 + __ exorb(r29, Address(r18, r14, (Address::ScaleFactor)2, +0x5cc0095b), r14, true); // {NF}xor r29b, byte ptr [r18+r14*4+0x5cc0095b], r14b IID293 + __ exorb(r27, Address(r25, r20, (Address::ScaleFactor)3, +0x1cf7b958), r27, true); // {NF}xor r27b, byte ptr [r25+r20*8+0x1cf7b958], r27b IID294 + __ eaddl(r16, r24, 16, false); // {EVEX}add r16d, r24d, 16 IID295 + __ eaddl(rax, r24, 16, false); // {EVEX}add eax, r24d, 16 IID296 + __ eaddl(r21, r21, 65536, false); // add r21d, 65536 IID297 + __ eaddl(r24, r8, 1048576, true); // {NF}add r24d, r8d, 1048576 IID298 + __ eaddl(rax, r13, 1048576, true); // {NF}add eax, r13d, 1048576 IID299 + __ eaddl(r29, r29, 16777216, true); // {NF}add r29d, r29d, 16777216 IID300 + __ eandl(r12, r12, 16, false); // and r12d, 16 IID301 + __ eandl(rax, r30, 16, false); // {EVEX}and eax, r30d, 16 IID302 + __ eandl(r24, r24, 16, false); // and r24d, 16 IID303 + __ eandl(r8, r12, 1, true); // {NF}and r8d, r12d, 1 IID304 + __ eandl(rax, r13, 1, true); // {NF}and eax, r13d, 1 IID305 + __ eandl(r25, r25, 16, true); // {NF}and r25d, r25d, 16 IID306 + __ eimull(r18, r23, 65536, false); // {EVEX}imul r18d, r23d, 65536 IID307 + __ eimull(rax, r9, 65536, false); // {EVEX}imul eax, r9d, 65536 IID308 + __ eimull(r26, r26, 268435456, false); // {EVEX}imul r26d, r26d, 268435456 IID309 + __ eimull(r25, r21, 1, true); // {NF}imul r25d, r21d, 1 IID310 + __ eimull(rax, r24, 1, true); // {NF}imul eax, r24d, 1 IID311 + __ eimull(r24, r24, 16777216, true); // {NF}imul r24d, r24d, 16777216 IID312 + __ eorl(r30, r26, 1, false); // {EVEX}or r30d, r26d, 1 IID313 + __ eorl(rax, r22, 1, false); // {EVEX}or eax, r22d, 1 IID314 + __ eorl(r17, r17, 1048576, false); // or r17d, 1048576 IID315 + __ eorl(r24, r8, 1, true); // {NF}or r24d, r8d, 1 IID316 + __ eorl(rax, r27, 1, true); // {NF}or eax, r27d, 1 IID317 #endif // _LP64 - __ eimull(rax, rbx, 4096, false); // {EVEX}imul eax, ebx, 4096 IID304 + __ eorl(rdx, rdx, 268435456, true); // {NF}or edx, edx, 268435456 IID318 #ifdef _LP64 - __ eimull(r24, r24, 1048576, false); // {EVEX}imul r24d, r24d, 1048576 IID305 - __ eimull(r21, r16, 65536, true); // {NF}imul r21d, r16d, 65536 IID306 - __ eimull(rax, r24, 65536, true); // {NF}imul eax, r24d, 65536 IID307 - __ eimull(r13, r13, 16, true); // {NF}imul r13d, r13d, 16 IID308 - __ eorl(r29, r8, 16777216, false); // {EVEX}or r29d, r8d, 16777216 IID309 - __ eorl(rax, r12, 16777216, false); // {EVEX}or eax, r12d, 16777216 IID310 - __ eorl(r30, r30, 4096, false); // or r30d, 4096 IID311 - __ eorl(r24, rdx, 16, true); // {NF}or r24d, edx, 16 IID312 - __ eorl(rax, r8, 16, true); // {NF}or eax, r8d, 16 IID313 - __ eorl(r13, r13, 4096, true); // {NF}or r13d, r13d, 4096 IID314 - __ ercll(r25, r13, 1); // {EVEX}rcl r25d, r13d, 1 IID315 - __ ercll(rax, r18, 1); // {EVEX}rcl eax, r18d, 1 IID316 - __ ercll(r9, r9, 16); // rcl r9d, 16 IID317 - __ eroll(r26, r25, 8, false); // {EVEX}rol r26d, r25d, 8 IID318 + __ ercll(r22, r22, 8); // rcl r22d, 8 IID319 + __ ercll(rax, r23, 8); // {EVEX}rcl eax, r23d, 8 IID320 + __ ercll(r19, r19, 4); // rcl r19d, 4 IID321 + __ eroll(r30, r24, 2, false); // {EVEX}rol r30d, r24d, 2 IID322 + __ eroll(rax, r29, 2, false); // {EVEX}rol eax, r29d, 2 IID323 + __ eroll(r8, r8, 2, false); // rol r8d, 2 IID324 + __ eroll(r18, r24, 16, true); // {NF}rol r18d, r24d, 16 IID325 + __ eroll(rax, r13, 16, true); // {NF}rol eax, r13d, 16 IID326 + __ eroll(r24, r24, 1, true); // {NF}rol r24d, r24d, 1 IID327 + __ erorl(r28, r17, 16, false); // {EVEX}ror r28d, r17d, 16 IID328 + __ erorl(rax, r24, 16, false); // {EVEX}ror eax, r24d, 16 IID329 + __ erorl(r17, r17, 4, false); // ror r17d, 4 IID330 + __ erorl(r24, rcx, 4, true); // {NF}ror r24d, ecx, 4 IID331 + __ erorl(rax, r16, 4, true); // {NF}ror eax, r16d, 4 IID332 + __ erorl(r15, r15, 2, true); // {NF}ror r15d, r15d, 2 IID333 + __ esall(r14, r27, 4, false); // {EVEX}sal r14d, r27d, 4 IID334 + __ esall(rax, r23, 4, false); // {EVEX}sal eax, r23d, 4 IID335 + __ esall(r30, r30, 4, false); // sal r30d, 4 IID336 + __ esall(r27, rdx, 2, true); // {NF}sal r27d, edx, 2 IID337 + __ esall(rax, r19, 2, true); // {NF}sal eax, r19d, 2 IID338 + __ esall(r20, r20, 2, true); // {NF}sal r20d, r20d, 2 IID339 + __ esarl(r21, r23, 1, false); // {EVEX}sar r21d, r23d, 1 IID340 + __ esarl(rax, r30, 1, false); // {EVEX}sar eax, r30d, 1 IID341 + __ esarl(r25, r25, 2, false); // sar r25d, 2 IID342 + __ esarl(r24, r19, 4, true); // {NF}sar r24d, r19d, 4 IID343 + __ esarl(rax, r14, 4, true); // {NF}sar eax, r14d, 4 IID344 + __ esarl(r26, r26, 16, true); // {NF}sar r26d, r26d, 16 IID345 + __ eshll(r22, r13, 8, false); // {EVEX}shl r22d, r13d, 8 IID346 + __ eshll(rax, r24, 8, false); // {EVEX}shl eax, r24d, 8 IID347 + __ eshll(r14, r14, 16, false); // shl r14d, 16 IID348 + __ eshll(r28, r25, 8, true); // {NF}shl r28d, r25d, 8 IID349 + __ eshll(rax, r10, 8, true); // {NF}shl eax, r10d, 8 IID350 + __ eshll(r20, r20, 1, true); // {NF}shl r20d, r20d, 1 IID351 + __ eshrl(r12, rbx, 4, false); // {EVEX}shr r12d, ebx, 4 IID352 + __ eshrl(rax, r23, 4, false); // {EVEX}shr eax, r23d, 4 IID353 + __ eshrl(r28, r28, 16, false); // shr r28d, 16 IID354 + __ eshrl(r24, r30, 4, true); // {NF}shr r24d, r30d, 4 IID355 + __ eshrl(rax, r31, 4, true); // {NF}shr eax, r31d, 4 IID356 + __ eshrl(r31, r31, 2, true); // {NF}shr r31d, r31d, 2 IID357 + __ esubl(r20, r10, 256, false); // {EVEX}sub r20d, r10d, 256 IID358 + __ esubl(rax, r13, 256, false); // {EVEX}sub eax, r13d, 256 IID359 + __ esubl(r25, r25, 256, false); // sub r25d, 256 IID360 + __ esubl(r23, r12, 268435456, true); // {NF}sub r23d, r12d, 268435456 IID361 + __ esubl(rax, r16, 268435456, true); // {NF}sub eax, r16d, 268435456 IID362 + __ esubl(r31, r31, 1, true); // {NF}sub r31d, r31d, 1 IID363 + __ exorl(r9, r15, 16777216, false); // {EVEX}xor r9d, r15d, 16777216 IID364 + __ exorl(rax, r13, 16777216, false); // {EVEX}xor eax, r13d, 16777216 IID365 + __ exorl(r28, r28, 16, false); // xor r28d, 16 IID366 + __ exorl(r29, r22, 16, true); // {NF}xor r29d, r22d, 16 IID367 #endif // _LP64 - __ eroll(rax, rdx, 8, false); // {EVEX}rol eax, edx, 8 IID319 + __ exorl(rax, rbx, 16, true); // {NF}xor eax, ebx, 16 IID368 #ifdef _LP64 - __ eroll(r24, r24, 16, false); // rol r24d, 16 IID320 - __ eroll(r24, rcx, 8, true); // {NF}rol r24d, ecx, 8 IID321 - __ eroll(rax, r30, 8, true); // {NF}rol eax, r30d, 8 IID322 - __ eroll(r28, r28, 16, true); // {NF}rol r28d, r28d, 16 IID323 - __ erorl(r17, r28, 4, false); // {EVEX}ror r17d, r28d, 4 IID324 + __ exorl(r8, r8, 16, true); // {NF}xor r8d, r8d, 16 IID369 + __ esubl_imm32(r16, r13, 4194304, false); // {EVEX}sub r16d, r13d, 4194304 IID370 + __ esubl_imm32(rax, r12, 4194304, false); // {EVEX}sub eax, r12d, 4194304 IID371 + __ esubl_imm32(r17, r17, 67108864, false); // sub r17d, 67108864 IID372 + __ esubl_imm32(r22, r26, 1073741824, true); // {NF}sub r22d, r26d, 1073741824 IID373 + __ esubl_imm32(rax, r10, 1073741824, true); // {NF}sub eax, r10d, 1073741824 IID374 + __ esubl_imm32(r11, r11, 1073741824, true); // {NF}sub r11d, r11d, 1073741824 IID375 + __ eaddl(r19, r12, Address(r30, r8, (Address::ScaleFactor)0, +0x6a1a0a73), false); // {EVEX}add r19d, r12d, dword ptr [r30+r8*1+0x6a1a0a73] IID376 + __ eaddl(r30, r30, Address(r18, r19, (Address::ScaleFactor)2, +0x25f990cf), false); // add r30d, dword ptr [r18+r19*4+0x25f990cf] IID377 + __ eaddl(rcx, r25, Address(r19, r16, (Address::ScaleFactor)0, +0x482d5dbc), true); // {NF}add ecx, r25d, dword ptr [r19+r16*1+0x482d5dbc] IID378 + __ eaddl(r9, r9, Address(r11, +0x43d5ee01), true); // {NF}add r9d, r9d, dword ptr [r11+0x43d5ee01] IID379 + __ eandl(rcx, r23, Address(r21, r15, (Address::ScaleFactor)2, +0x2825c2bc), false); // {EVEX}and ecx, r23d, dword ptr [r21+r15*4+0x2825c2bc] IID380 + __ eandl(r27, r27, Address(r13, r15, (Address::ScaleFactor)3, -0x1268b895), false); // and r27d, dword ptr [r13+r15*8-0x1268b895] IID381 + __ eandl(r9, r23, Address(r22, r30, (Address::ScaleFactor)0, -0x715acbb), true); // {NF}and r9d, r23d, dword ptr [r22+r30*1-0x715acbb] IID382 + __ eandl(rbx, rbx, Address(r28, r16, (Address::ScaleFactor)2, +0xb0223ee), true); // {NF}and ebx, ebx, dword ptr [r28+r16*4+0xb0223ee] IID383 + __ eimull(r15, r29, Address(r15, r28, (Address::ScaleFactor)1, -0x1f297a69), false); // {EVEX}imul r15d, r29d, dword ptr [r15+r28*2-0x1f297a69] IID384 + __ eimull(r17, r17, Address(r23, rbx, (Address::ScaleFactor)1, +0xadc7545), false); // imul r17d, dword ptr [r23+rbx*2+0xadc7545] IID385 + __ eimull(r27, r9, Address(rdx, r22, (Address::ScaleFactor)2, -0x43d90f61), true); // {NF}imul r27d, r9d, dword ptr [rdx+r22*4-0x43d90f61] IID386 + __ eimull(rbx, rbx, Address(r28, r22, (Address::ScaleFactor)3, -0x519d9a27), true); // {NF}imul ebx, ebx, dword ptr [r28+r22*8-0x519d9a27] IID387 + __ eorl(r17, rcx, Address(r14, +0x10642223), false); // {EVEX}or r17d, ecx, dword ptr [r14+0x10642223] IID388 + __ eorl(r26, r26, Address(r31, -0x7a9a83ba), false); // or r26d, dword ptr [r31-0x7a9a83ba] IID389 + __ eorl(r15, r22, Address(r12, r12, (Address::ScaleFactor)2, +0x743b6997), true); // {NF}or r15d, r22d, dword ptr [r12+r12*4+0x743b6997] IID390 + __ eorl(r8, r8, Address(rdx, r22, (Address::ScaleFactor)3, -0x588414dc), true); // {NF}or r8d, r8d, dword ptr [rdx+r22*8-0x588414dc] IID391 + __ esubl(rcx, r28, Address(r30, r13, (Address::ScaleFactor)2, +0xe9310e5), false); // {EVEX}sub ecx, r28d, dword ptr [r30+r13*4+0xe9310e5] IID392 + __ esubl(rcx, rcx, Address(r30, r10, (Address::ScaleFactor)1, -0x1b076ed1), false); // sub ecx, dword ptr [r30+r10*2-0x1b076ed1] IID393 + __ esubl(r9, r21, Address(r30, +0x2f79ffd3), true); // {NF}sub r9d, r21d, dword ptr [r30+0x2f79ffd3] IID394 + __ esubl(r16, r16, Address(rdx, r14, (Address::ScaleFactor)2, +0x675d71c1), true); // {NF}sub r16d, r16d, dword ptr [rdx+r14*4+0x675d71c1] IID395 + __ exorl(r27, r28, Address(rbx, r26, (Address::ScaleFactor)2, -0x78c20b81), false); // {EVEX}xor r27d, r28d, dword ptr [rbx+r26*4-0x78c20b81] IID396 + __ exorl(r14, r14, Address(r31, r19, (Address::ScaleFactor)1, -0x4ff251cc), false); // xor r14d, dword ptr [r31+r19*2-0x4ff251cc] IID397 + __ exorl(r20, r18, Address(r13, r16, (Address::ScaleFactor)2, -0x19efc6e2), true); // {NF}xor r20d, r18d, dword ptr [r13+r16*4-0x19efc6e2] IID398 + __ exorl(r19, r19, Address(r13, r23, (Address::ScaleFactor)1, -0x2d1bd8aa), true); // {NF}xor r19d, r19d, dword ptr [r13+r23*2-0x2d1bd8aa] IID399 + __ exorb(r29, r17, Address(rdx, r29, (Address::ScaleFactor)2, +0x66573e84), false); // {EVEX}xor r29b, r17b, byte ptr [rdx+r29*4+0x66573e84] IID400 + __ exorb(r22, r22, Address(r24, r25, (Address::ScaleFactor)3, +0x3a94a93f), false); // xor r22b, byte ptr [r24+r25*8+0x3a94a93f] IID401 + __ exorb(r13, r29, Address(r15, r23, (Address::ScaleFactor)1, +0x76d43532), true); // {NF}xor r13b, r29b, byte ptr [r15+r23*2+0x76d43532] IID402 + __ exorb(r15, r15, Address(r13, r9, (Address::ScaleFactor)0, -0x474e6d1a), true); // {NF}xor r15b, r15b, byte ptr [r13+r9*1-0x474e6d1a] IID403 + __ exorw(r17, r16, Address(r23, rdx, (Address::ScaleFactor)0, +0x562a291), false); // {EVEX}xor r17w, r16w, word ptr [r23+rdx*1+0x562a291] IID404 + __ exorw(r29, r29, Address(r18, r28, (Address::ScaleFactor)3, -0x541967f2), false); // xor r29w, word ptr [r18+r28*8-0x541967f2] IID405 + __ exorw(r27, r11, Address(r10, +0xa911c5a), true); // {NF}xor r27w, r11w, word ptr [r10+0xa911c5a] IID406 + __ exorw(r31, r31, Address(r30, r19, (Address::ScaleFactor)2, -0xf6a3da), true); // {NF}xor r31w, r31w, word ptr [r30+r19*4-0xf6a3da] IID407 + __ eaddl(r12, r13, r23, false); // {load}{EVEX}add r12d, r13d, r23d IID408 + __ eaddl(r28, r28, r20, false); // {load}add r28d, r20d IID409 + __ eaddl(r20, r24, r20, false); // {load}add r20d, r24d IID410 + __ eaddl(r11, r10, r15, true); // {load}{NF}add r11d, r10d, r15d IID411 + __ eaddl(r19, r19, r20, true); // {load}{NF}add r19d, r19d, r20d IID412 + __ eaddl(r23, r15, r23, true); // {load}{NF}add r23d, r15d, r23d IID413 + __ eandl(r26, r19, r24, false); // {load}{EVEX}and r26d, r19d, r24d IID414 + __ eandl(r23, r23, r28, false); // {load}and r23d, r28d IID415 + __ eandl(r11, r13, r11, false); // {load}and r11d, r13d IID416 + __ eandl(r13, rdx, r31, true); // {load}{NF}and r13d, edx, r31d IID417 + __ eandl(r23, r23, r23, true); // {load}{NF}and r23d, r23d, r23d IID418 + __ eandl(r9, r27, r9, true); // {load}{NF}and r9d, r27d, r9d IID419 + __ eimull(r21, r20, r24, false); // {load}{EVEX}imul r21d, r20d, r24d IID420 + __ eimull(r21, r21, r29, false); // {load}imul r21d, r29d IID421 + __ eimull(rbx, r11, rbx, false); // {load}imul ebx, r11d IID422 + __ eimull(r21, rbx, rcx, true); // {load}{NF}imul r21d, ebx, ecx IID423 + __ eimull(r31, r31, r21, true); // {load}{NF}imul r31d, r31d, r21d IID424 + __ eimull(r15, r25, r15, true); // {load}{NF}imul r15d, r25d, r15d IID425 + __ eorw(r30, r23, r25, false); // {load}{EVEX}or r30w, r23w, r25w IID426 + __ eorw(r18, r18, rcx, false); // {load}or r18w, cx IID427 + __ eorw(r10, rcx, r10, false); // {load}or r10w, cx IID428 + __ eorw(r31, r21, r26, true); // {load}{NF}or r31w, r21w, r26w IID429 + __ eorw(r21, r21, r19, true); // {load}{NF}or r21w, r21w, r19w IID430 #endif // _LP64 - __ erorl(rax, rdx, 4, false); // {EVEX}ror eax, edx, 4 IID325 + __ eorw(rdx, rbx, rdx, true); // {load}{NF}or dx, bx, dx IID431 #ifdef _LP64 - __ erorl(r8, r8, 16, false); // ror r8d, 16 IID326 - __ erorl(r19, rdx, 16, true); // {NF}ror r19d, edx, 16 IID327 - __ erorl(rax, r31, 16, true); // {NF}ror eax, r31d, 16 IID328 - __ erorl(r22, r22, 8, true); // {NF}ror r22d, r22d, 8 IID329 - __ esall(r23, r25, 16, false); // {EVEX}sal r23d, r25d, 16 IID330 - __ esall(rax, r14, 16, false); // {EVEX}sal eax, r14d, 16 IID331 - __ esall(r31, r31, 8, false); // sal r31d, 8 IID332 - __ esall(r30, r24, 2, true); // {NF}sal r30d, r24d, 2 IID333 - __ esall(rax, r29, 2, true); // {NF}sal eax, r29d, 2 IID334 - __ esall(r8, r8, 2, true); // {NF}sal r8d, r8d, 2 IID335 - __ esarl(r18, r24, 16, false); // {EVEX}sar r18d, r24d, 16 IID336 - __ esarl(rax, r13, 16, false); // {EVEX}sar eax, r13d, 16 IID337 - __ esarl(r24, r24, 1, false); // sar r24d, 1 IID338 - __ esarl(r28, r17, 16, true); // {NF}sar r28d, r17d, 16 IID339 - __ esarl(rax, r24, 16, true); // {NF}sar eax, r24d, 16 IID340 - __ esarl(r17, r17, 4, true); // {NF}sar r17d, r17d, 4 IID341 - __ eshll(r24, rcx, 4, false); // {EVEX}shl r24d, ecx, 4 IID342 - __ eshll(rax, r16, 4, false); // {EVEX}shl eax, r16d, 4 IID343 - __ eshll(r15, r15, 2, false); // shl r15d, 2 IID344 - __ eshll(r14, r27, 4, true); // {NF}shl r14d, r27d, 4 IID345 - __ eshll(rax, r23, 4, true); // {NF}shl eax, r23d, 4 IID346 - __ eshll(r30, r30, 4, true); // {NF}shl r30d, r30d, 4 IID347 - __ eshrl(r27, rdx, 2, false); // {EVEX}shr r27d, edx, 2 IID348 - __ eshrl(rax, r19, 2, false); // {EVEX}shr eax, r19d, 2 IID349 - __ eshrl(r20, r20, 2, false); // shr r20d, 2 IID350 - __ eshrl(r21, r23, 1, true); // {NF}shr r21d, r23d, 1 IID351 - __ eshrl(rax, r30, 1, true); // {NF}shr eax, r30d, 1 IID352 - __ eshrl(r25, r25, 2, true); // {NF}shr r25d, r25d, 2 IID353 - __ esubl(r24, r19, 1048576, false); // {EVEX}sub r24d, r19d, 1048576 IID354 - __ esubl(rax, r14, 1048576, false); // {EVEX}sub eax, r14d, 1048576 IID355 - __ esubl(r22, r22, 268435456, false); // sub r22d, 268435456 IID356 - __ esubl(r24, r24, 65536, true); // {NF}sub r24d, r24d, 65536 IID357 - __ esubl(rax, r14, 65536, true); // {NF}sub eax, r14d, 65536 IID358 - __ esubl(r28, r28, 268435456, true); // {NF}sub r28d, r28d, 268435456 IID359 - __ exorl(rbx, r20, 256, false); // {EVEX}xor ebx, r20d, 256 IID360 - __ exorl(rax, r15, 256, false); // {EVEX}xor eax, r15d, 256 IID361 -#endif // _LP64 - __ exorl(rbx, rbx, 4096, false); // xor ebx, 4096 IID362 -#ifdef _LP64 - __ exorl(r24, r30, 65536, true); // {NF}xor r24d, r30d, 65536 IID363 - __ exorl(rax, r31, 65536, true); // {NF}xor eax, r31d, 65536 IID364 - __ exorl(r31, r31, 4096, true); // {NF}xor r31d, r31d, 4096 IID365 - __ esubl_imm32(r20, r10, 1048576, false); // {EVEX}sub r20d, r10d, 1048576 IID366 - __ esubl_imm32(rax, r13, 1048576, false); // {EVEX}sub eax, r13d, 1048576 IID367 - __ esubl_imm32(r25, r25, 1048576, false); // sub r25d, 1048576 IID368 - __ esubl_imm32(r23, r12, 1073741824, true); // {NF}sub r23d, r12d, 1073741824 IID369 - __ esubl_imm32(rax, r16, 1073741824, true); // {NF}sub eax, r16d, 1073741824 IID370 - __ esubl_imm32(r31, r31, 65536, true); // {NF}sub r31d, r31d, 65536 IID371 - __ eaddl(r17, r13, Address(r9, +0x7fef2f98), false); // {EVEX}add r17d, r13d, dword ptr [r9+0x7fef2f98] IID372 - __ eaddl(r29, r8, Address(r22, -0x4df70aac), true); // {NF}add r29d, r8d, dword ptr [r22-0x4df70aac] IID373 - __ eandl(r13, r17, Address(r12, r15, (Address::ScaleFactor)3, +0x50a8a902), false); // {EVEX}and r13d, r17d, dword ptr [r12+r15*8+0x50a8a902] IID374 - __ eandl(r22, r25, Address(r26, r10, (Address::ScaleFactor)2, +0x70ea2754), true); // {NF}and r22d, r25d, dword ptr [r26+r10*4+0x70ea2754] IID375 - __ eimull(r19, r12, Address(r30, r8, (Address::ScaleFactor)0, +0x6a1a0a73), false); // {EVEX}imul r19d, r12d, dword ptr [r30+r8*1+0x6a1a0a73] IID376 - __ eimull(r30, r18, Address(r18, r19, (Address::ScaleFactor)2, -0x7fcd28c7), true); // {NF}imul r30d, r18d, dword ptr [r18+r19*4-0x7fcd28c7] IID377 - __ eorl(r16, r31, Address(r25, r11, (Address::ScaleFactor)3, +0x482d5dbc), false); // {EVEX}or r16d, r31d, dword ptr [r25+r11*8+0x482d5dbc] IID378 - __ eorl(r9, r27, Address(r11, +0x43d5ee01), true); // {NF}or r9d, r27d, dword ptr [r11+0x43d5ee01] IID379 - __ esubl(rcx, r23, Address(r21, r15, (Address::ScaleFactor)2, +0x2825c2bc), false); // {EVEX}sub ecx, r23d, dword ptr [r21+r15*4+0x2825c2bc] IID380 - __ esubl(r27, r22, Address(r13, r15, (Address::ScaleFactor)1, +0x771f0da7), true); // {NF}sub r27d, r22d, dword ptr [r13+r15*2+0x771f0da7] IID381 - __ exorl(r9, r30, Address(r9, r22, (Address::ScaleFactor)3, -0x4ad6c88e), false); // {EVEX}xor r9d, r30d, dword ptr [r9+r22*8-0x4ad6c88e] IID382 - __ exorl(r11, r16, Address(rbx, r28, (Address::ScaleFactor)2, +0xb0223ee), true); // {NF}xor r11d, r16d, dword ptr [rbx+r28*4+0xb0223ee] IID383 - __ exorb(r15, r29, Address(r15, r28, (Address::ScaleFactor)1, -0x1f297a69), false); // {EVEX}xor r15b, r29b, byte ptr [r15+r28*2-0x1f297a69] IID384 - __ exorb(r17, r30, Address(r23, rbx, (Address::ScaleFactor)1, +0xadc7545), true); // {NF}xor r17b, r30b, byte ptr [r23+rbx*2+0xadc7545] IID385 - __ exorw(r27, r9, Address(rdx, r22, (Address::ScaleFactor)2, -0x43d90f61), false); // {EVEX}xor r27w, r9w, word ptr [rdx+r22*4-0x43d90f61] IID386 - __ exorw(rbx, r22, Address(r28, r22, (Address::ScaleFactor)0, -0x7d30a0b1), true); // {NF}xor bx, r22w, word ptr [r28+r22*1-0x7d30a0b1] IID387 - __ eaddl(r14, r24, rcx, false); // {load}{EVEX}add r14d, r24d, ecx IID388 - __ eaddl(r8, r8, r17, false); // {load}add r8d, r17d IID389 - __ eaddl(r26, r24, r12, true); // {load}{NF}add r26d, r24d, r12d IID390 - __ eaddl(r24, r24, r23, true); // {load}{NF}add r24d, r24d, r23d IID391 - __ eandl(r13, r26, r31, false); // {load}{EVEX}and r13d, r26d, r31d IID392 - __ eandl(r11, r11, r8, false); // {load}and r11d, r8d IID393 - __ eandl(rcx, r19, r15, true); // {load}{NF}and ecx, r19d, r15d IID394 - __ eandl(r12, r12, r12, true); // {load}{NF}and r12d, r12d, r12d IID395 - __ eimull(r22, r20, r19, false); // {load}{EVEX}imul r22d, r20d, r19d IID396 - __ eimull(r8, r8, rdx, false); // {load}imul r8d, edx IID397 - __ eimull(r22, r27, r23, true); // {load}{NF}imul r22d, r27d, r23d IID398 - __ eimull(r9, r9, r18, true); // {load}{NF}imul r9d, r9d, r18d IID399 - __ eorw(rcx, r30, r13, false); // {load}{EVEX}or cx, r30w, r13w IID400 - __ eorw(r28, r28, r19, false); // {load}or r28w, r19w IID401 - __ eorw(r12, r30, r27, true); // {load}{NF}or r12w, r30w, r27w IID402 - __ eorw(r8, r8, r22, true); // {load}{NF}or r8w, r8w, r22w IID403 - __ eorl(r16, rcx, r30, false); // {load}{EVEX}or r16d, ecx, r30d IID404 - __ eorl(r10, r10, r25, false); // {load}or r10d, r25d IID405 - __ eorl(r15, r17, r17, true); // {load}{NF}or r15d, r17d, r17d IID406 - __ eorl(r9, r9, r30, true); // {load}{NF}or r9d, r9d, r30d IID407 - __ eshldl(r20, r21, r8, false); // {load}{EVEX}shld r20d, r21d, r8d, cl IID408 - __ eshldl(r26, r26, r14, false); // {load}shld r26d, r14d IID409 - __ eshldl(r16, rdx, r14, true); // {load}{NF}shld r16d, edx, r14d, cl IID410 - __ eshldl(r19, r19, r8, true); // {load}{NF}shld r19d, r19d, r8d, cl IID411 - __ eshrdl(r27, rbx, r26, false); // {load}{EVEX}shrd r27d, ebx, r26d, cl IID412 - __ eshrdl(r28, r28, r19, false); // {load}shrd r28d, r19d IID413 - __ eshrdl(rcx, r11, r14, true); // {load}{NF}shrd ecx, r11d, r14d, cl IID414 - __ eshrdl(r31, r31, r19, true); // {load}{NF}shrd r31d, r31d, r19d, cl IID415 - __ esubl(r26, r13, r25, false); // {load}{EVEX}sub r26d, r13d, r25d IID416 - __ esubl(r24, r24, r11, false); // {load}sub r24d, r11d IID417 - __ esubl(r18, r20, r13, true); // {load}{NF}sub r18d, r20d, r13d IID418 - __ esubl(r16, r16, r18, true); // {load}{NF}sub r16d, r16d, r18d IID419 - __ exorl(r19, r17, r8, false); // {load}{EVEX}xor r19d, r17d, r8d IID420 - __ exorl(r19, r19, r13, false); // {load}xor r19d, r13d IID421 - __ exorl(r23, r13, r15, true); // {load}{NF}xor r23d, r13d, r15d IID422 - __ exorl(r11, r11, r29, true); // {load}{NF}xor r11d, r11d, r29d IID423 - __ eshldl(r29, r17, r17, 1, false); // {EVEX}shld r29d, r17d, r17d, 1 IID424 - __ eshldl(r22, r22, r24, 4, false); // shld r22d, r24d, 4 IID425 - __ eshldl(r8, r28, r11, 16, true); // {NF}shld r8d, r28d, r11d, 16 IID426 - __ eshldl(r15, r15, r23, 4, true); // {NF}shld r15d, r15d, r23d, 4 IID427 - __ eshrdl(r29, r22, r16, 4, false); // {EVEX}shrd r29d, r22d, r16d, 4 IID428 - __ eshrdl(r13, r13, r9, 4, false); // shrd r13d, r9d, 4 IID429 - __ eshrdl(r15, r21, r12, 2, true); // {NF}shrd r15d, r21d, r12d, 2 IID430 - __ eshrdl(r17, r17, r23, 2, true); // {NF}shrd r17d, r17d, r23d, 2 IID431 - __ ecmovl (Assembler::Condition::overflow, rdx, r16, r29); // cmovo edx, r16d, r29d IID432 - __ ecmovl (Assembler::Condition::overflow, r10, r10, r21); // cmovo r10d, r21d IID433 - __ ecmovl (Assembler::Condition::noOverflow, r17, r29, r18); // cmovno r17d, r29d, r18d IID434 - __ ecmovl (Assembler::Condition::noOverflow, r28, r28, r24); // cmovno r28d, r24d IID435 - __ ecmovl (Assembler::Condition::below, r10, r20, r27); // cmovb r10d, r20d, r27d IID436 - __ ecmovl (Assembler::Condition::below, r10, r10, r14); // cmovb r10d, r14d IID437 - __ ecmovl (Assembler::Condition::aboveEqual, r11, r27, rcx); // cmovae r11d, r27d, ecx IID438 - __ ecmovl (Assembler::Condition::aboveEqual, r22, r22, r15); // cmovae r22d, r15d IID439 - __ ecmovl (Assembler::Condition::zero, r31, r30, r19); // cmovz r31d, r30d, r19d IID440 - __ ecmovl (Assembler::Condition::zero, r19, r19, r26); // cmovz r19d, r26d IID441 - __ ecmovl (Assembler::Condition::notZero, r21, r14, r26); // cmovnz r21d, r14d, r26d IID442 - __ ecmovl (Assembler::Condition::notZero, r20, r20, r15); // cmovnz r20d, r15d IID443 - __ ecmovl (Assembler::Condition::belowEqual, r12, r13, r23); // cmovbe r12d, r13d, r23d IID444 - __ ecmovl (Assembler::Condition::belowEqual, r28, r28, r20); // cmovbe r28d, r20d IID445 - __ ecmovl (Assembler::Condition::above, r20, r24, r11); // cmova r20d, r24d, r11d IID446 - __ ecmovl (Assembler::Condition::above, r10, r10, r15); // cmova r10d, r15d IID447 - __ ecmovl (Assembler::Condition::negative, r19, r20, r23); // cmovs r19d, r20d, r23d IID448 - __ ecmovl (Assembler::Condition::negative, r15, r15, r26); // cmovs r15d, r26d IID449 - __ ecmovl (Assembler::Condition::positive, r19, r24, r23); // cmovns r19d, r24d, r23d IID450 - __ ecmovl (Assembler::Condition::positive, r28, r28, r11); // cmovns r28d, r11d IID451 - __ ecmovl (Assembler::Condition::parity, r13, r13, rdx); // cmovp r13d, edx IID452 - __ ecmovl (Assembler::Condition::parity, r31, r31, r23); // cmovp r31d, r23d IID453 - __ ecmovl (Assembler::Condition::noParity, r23, r9, r27); // cmovnp r23d, r9d, r27d IID454 - __ ecmovl (Assembler::Condition::noParity, r21, r21, r20); // cmovnp r21d, r20d IID455 - __ ecmovl (Assembler::Condition::less, r24, r21, r29); // cmovl r24d, r21d, r29d IID456 - __ ecmovl (Assembler::Condition::less, rbx, rbx, r11); // cmovl ebx, r11d IID457 - __ ecmovl (Assembler::Condition::greaterEqual, r21, rbx, rcx); // cmovge r21d, ebx, ecx IID458 - __ ecmovl (Assembler::Condition::greaterEqual, r31, r31, r21); // cmovge r31d, r21d IID459 - __ ecmovl (Assembler::Condition::lessEqual, r15, r25, r30); // cmovle r15d, r25d, r30d IID460 - __ ecmovl (Assembler::Condition::lessEqual, r23, r23, r25); // cmovle r23d, r25d IID461 - __ ecmovl (Assembler::Condition::greater, r18, rcx, r10); // cmovg r18d, ecx, r10d IID462 - __ ecmovl (Assembler::Condition::greater, rcx, rcx, r31); // cmovg ecx, r31d IID463 - __ ecmovl (Assembler::Condition::overflow, r21, r19, Address(r26, -0x6e290873)); // cmovo r21d, r19d, dword ptr [r26-0x6e290873] IID464 - __ ecmovl (Assembler::Condition::noOverflow, r24, r19, Address(r22, rcx, (Address::ScaleFactor)0, +0x11f85f9a)); // cmovno r24d, r19d, dword ptr [r22+rcx*1+0x11f85f9a] IID465 - __ ecmovl (Assembler::Condition::below, r17, r24, Address(r20, +0x534d775e)); // cmovb r17d, r24d, dword ptr [r20+0x534d775e] IID466 - __ ecmovl (Assembler::Condition::aboveEqual, r20, r18, Address(r20, -0x47c94ecd)); // cmovae r20d, r18d, dword ptr [r20-0x47c94ecd] IID467 - __ ecmovl (Assembler::Condition::zero, r9, r13, Address(r23, -0x4b83c563)); // cmovz r9d, r13d, dword ptr [r23-0x4b83c563] IID468 - __ ecmovl (Assembler::Condition::notZero, r11, r25, Address(r24, r14, (Address::ScaleFactor)1, -0x446507af)); // cmovnz r11d, r25d, dword ptr [r24+r14*2-0x446507af] IID469 - __ ecmovl (Assembler::Condition::belowEqual, r14, r24, Address(r30, r13, (Address::ScaleFactor)2, +0xd0661d)); // cmovbe r14d, r24d, dword ptr [r30+r13*4+0xd0661d] IID470 - __ ecmovl (Assembler::Condition::above, r13, r25, Address(r14, r27, (Address::ScaleFactor)3, +0x47e1403)); // cmova r13d, r25d, dword ptr [r14+r27*8+0x47e1403] IID471 - __ ecmovl (Assembler::Condition::negative, r24, r19, Address(rcx, rdx, (Address::ScaleFactor)3, -0x644a5318)); // cmovs r24d, r19d, dword ptr [rcx+rdx*8-0x644a5318] IID472 - __ ecmovl (Assembler::Condition::positive, r26, r24, Address(r22, r22, (Address::ScaleFactor)0, +0x70352446)); // cmovns r26d, r24d, dword ptr [r22+r22*1+0x70352446] IID473 - __ ecmovl (Assembler::Condition::parity, r19, r26, Address(r8, r30, (Address::ScaleFactor)2, +0x78a12f5c)); // cmovp r19d, r26d, dword ptr [r8+r30*4+0x78a12f5c] IID474 - __ ecmovl (Assembler::Condition::noParity, r29, r11, Address(r25, r20, (Address::ScaleFactor)0, +0x27a8303a)); // cmovnp r29d, r11d, dword ptr [r25+r20*1+0x27a8303a] IID475 - __ ecmovl (Assembler::Condition::less, r22, r24, Address(r27, r16, (Address::ScaleFactor)1, +0x2541a10)); // cmovl r22d, r24d, dword ptr [r27+r16*2+0x2541a10] IID476 - __ ecmovl (Assembler::Condition::greaterEqual, r31, r15, Address(r8, r16, (Address::ScaleFactor)3, +0x558e3251)); // cmovge r31d, r15d, dword ptr [r8+r16*8+0x558e3251] IID477 - __ ecmovl (Assembler::Condition::lessEqual, r27, r18, Address(r8, r10, (Address::ScaleFactor)0, -0x471987b7)); // cmovle r27d, r18d, dword ptr [r8+r10*1-0x471987b7] IID478 - __ ecmovl (Assembler::Condition::greater, r18, r16, Address(r18, r19, (Address::ScaleFactor)2, -0x120ae81e)); // cmovg r18d, r16d, dword ptr [r18+r19*4-0x120ae81e] IID479 + __ eorl(rcx, r24, r22, false); // {load}{EVEX}or ecx, r24d, r22d IID432 + __ eorl(rcx, rcx, r19, false); // {load}or ecx, r19d IID433 + __ eorl(r27, r27, r27, false); // {load}or r27d, r27d IID434 + __ eorl(r31, r9, r13, true); // {load}{NF}or r31d, r9d, r13d IID435 + __ eorl(r31, r31, r23, true); // {load}{NF}or r31d, r31d, r23d IID436 + __ eorl(r19, r17, r19, true); // {load}{NF}or r19d, r17d, r19d IID437 + __ eshldl(r20, r16, r24, false); // {load}{EVEX}shld r20d, r16d, r24d, cl IID438 + __ eshldl(rdx, rdx, r12, false); // {load}shld edx, r12d IID439 + __ eshldl(r29, r9, r31, true); // {load}{NF}shld r29d, r9d, r31d, cl IID440 + __ eshldl(r17, r17, r20, true); // {load}{NF}shld r17d, r17d, r20d, cl IID441 + __ eshrdl(r20, r15, r18, false); // {load}{EVEX}shrd r20d, r15d, r18d, cl IID442 + __ eshrdl(rcx, rcx, r12, false); // {load}shrd ecx, r12d IID443 + __ eshrdl(r14, r9, r23, true); // {load}{NF}shrd r14d, r9d, r23d, cl IID444 + __ eshrdl(r19, r19, r13, true); // {load}{NF}shrd r19d, r19d, r13d, cl IID445 + __ esubl(r30, r27, r27, false); // {load}{EVEX}sub r30d, r27d, r27d IID446 + __ esubl(rdx, rdx, r11, false); // {load}sub edx, r11d IID447 + __ esubl(r15, r11, r24, true); // {load}{NF}sub r15d, r11d, r24d IID448 + __ esubl(r14, r14, r25, true); // {load}{NF}sub r14d, r14d, r25d IID449 + __ exorl(r31, r16, r12, false); // {load}{EVEX}xor r31d, r16d, r12d IID450 + __ exorl(r20, r20, r14, false); // {load}xor r20d, r14d IID451 + __ exorl(r30, r13, r30, false); // {load}xor r30d, r13d IID452 + __ exorl(r24, r17, r17, true); // {load}{NF}xor r24d, r17d, r17d IID453 + __ exorl(r26, r26, r21, true); // {load}{NF}xor r26d, r26d, r21d IID454 + __ exorl(r11, r13, r11, true); // {load}{NF}xor r11d, r13d, r11d IID455 + __ eshldl(r27, r25, r21, 4, false); // {EVEX}shld r27d, r25d, r21d, 4 IID456 + __ eshldl(r22, r22, r10, 4, false); // shld r22d, r10d, 4 IID457 + __ eshldl(r21, r15, r24, 16, true); // {NF}shld r21d, r15d, r24d, 16 IID458 + __ eshldl(rdx, rdx, r19, 1, true); // {NF}shld edx, edx, r19d, 1 IID459 + __ eshrdl(r23, r13, r8, 16, false); // {EVEX}shrd r23d, r13d, r8d, 16 IID460 + __ eshrdl(r26, r26, r22, 1, false); // shrd r26d, r22d, 1 IID461 + __ eshrdl(r24, r9, r30, 16, true); // {NF}shrd r24d, r9d, r30d, 16 IID462 + __ eshrdl(r19, r19, r8, 4, true); // {NF}shrd r19d, r19d, r8d, 4 IID463 + __ ecmovl (Assembler::Condition::overflow, r30, r26, r17); // cmovo r30d, r26d, r17d IID464 + __ ecmovl (Assembler::Condition::overflow, r14, r14, r26); // cmovo r14d, r26d IID465 + __ ecmovl (Assembler::Condition::noOverflow, r24, r19, r29); // cmovno r24d, r19d, r29d IID466 + __ ecmovl (Assembler::Condition::noOverflow, r25, r25, r20); // cmovno r25d, r20d IID467 + __ ecmovl (Assembler::Condition::below, r11, r10, r14); // cmovb r11d, r10d, r14d IID468 + __ ecmovl (Assembler::Condition::below, r30, r30, r25); // cmovb r30d, r25d IID469 + __ ecmovl (Assembler::Condition::aboveEqual, r13, r22, r27); // cmovae r13d, r22d, r27d IID470 + __ ecmovl (Assembler::Condition::aboveEqual, r16, r16, r24); // cmovae r16d, r24d IID471 + __ ecmovl (Assembler::Condition::zero, r28, r13, r30); // cmovz r28d, r13d, r30d IID472 + __ ecmovl (Assembler::Condition::zero, r30, r30, r24); // cmovz r30d, r24d IID473 + __ ecmovl (Assembler::Condition::notZero, r21, r20, r31); // cmovnz r21d, r20d, r31d IID474 + __ ecmovl (Assembler::Condition::notZero, r8, r8, r16); // cmovnz r8d, r16d IID475 + __ ecmovl (Assembler::Condition::belowEqual, r15, r26, r22); // cmovbe r15d, r26d, r22d IID476 + __ ecmovl (Assembler::Condition::belowEqual, r31, r31, rdx); // cmovbe r31d, edx IID477 + __ ecmovl (Assembler::Condition::above, r27, r8, r10); // cmova r27d, r8d, r10d IID478 + __ ecmovl (Assembler::Condition::above, r18, r18, r11); // cmova r18d, r11d IID479 + __ ecmovl (Assembler::Condition::negative, r27, rbx, r21); // cmovs r27d, ebx, r21d IID480 + __ ecmovl (Assembler::Condition::negative, r12, r12, r31); // cmovs r12d, r31d IID481 + __ ecmovl (Assembler::Condition::positive, r12, rdx, r18); // cmovns r12d, edx, r18d IID482 + __ ecmovl (Assembler::Condition::positive, r18, r18, r19); // cmovns r18d, r19d IID483 + __ ecmovl (Assembler::Condition::parity, r16, r20, r23); // cmovp r16d, r20d, r23d IID484 + __ ecmovl (Assembler::Condition::parity, r18, r18, r16); // cmovp r18d, r16d IID485 + __ ecmovl (Assembler::Condition::noParity, rbx, r31, r30); // cmovnp ebx, r31d, r30d IID486 + __ ecmovl (Assembler::Condition::noParity, r31, r31, r29); // cmovnp r31d, r29d IID487 + __ ecmovl (Assembler::Condition::less, r28, r25, r10); // cmovl r28d, r25d, r10d IID488 + __ ecmovl (Assembler::Condition::less, r24, r24, r20); // cmovl r24d, r20d IID489 + __ ecmovl (Assembler::Condition::greaterEqual, r16, rdx, r26); // cmovge r16d, edx, r26d IID490 + __ ecmovl (Assembler::Condition::greaterEqual, r28, r28, r28); // cmovge r28d, r28d IID491 + __ ecmovl (Assembler::Condition::lessEqual, r9, r20, r24); // cmovle r9d, r20d, r24d IID492 + __ ecmovl (Assembler::Condition::lessEqual, r24, r24, r29); // cmovle r24d, r29d IID493 + __ ecmovl (Assembler::Condition::greater, r23, r27, r15); // cmovg r23d, r27d, r15d IID494 + __ ecmovl (Assembler::Condition::greater, r12, r12, r18); // cmovg r12d, r18d IID495 + __ ecmovl (Assembler::Condition::overflow, r19, r9, Address(r31, rcx, (Address::ScaleFactor)1, -0x2be98bd)); // cmovo r19d, r9d, dword ptr [r31+rcx*2-0x2be98bd] IID496 + __ ecmovl (Assembler::Condition::overflow, r8, r8, Address(r21, r24, (Address::ScaleFactor)1, +0x41e6a0cb)); // cmovo r8d, dword ptr [r21+r24*2+0x41e6a0cb] IID497 + __ ecmovl (Assembler::Condition::noOverflow, r23, r15, Address(r19, r30, (Address::ScaleFactor)3, -0x55adfe2d)); // cmovno r23d, r15d, dword ptr [r19+r30*8-0x55adfe2d] IID498 + __ ecmovl (Assembler::Condition::noOverflow, rdx, rdx, Address(r27, rdx, (Address::ScaleFactor)0, -0x1aa12735)); // cmovno edx, dword ptr [r27+rdx*1-0x1aa12735] IID499 + __ ecmovl (Assembler::Condition::below, rbx, r29, Address(r31, r12, (Address::ScaleFactor)0, +0xbd42246)); // cmovb ebx, r29d, dword ptr [r31+r12*1+0xbd42246] IID500 + __ ecmovl (Assembler::Condition::below, r21, r21, Address(r19, r21, (Address::ScaleFactor)1, -0x41518818)); // cmovb r21d, dword ptr [r19+r21*2-0x41518818] IID501 + __ ecmovl (Assembler::Condition::aboveEqual, r23, r29, Address(r22, r9, (Address::ScaleFactor)2, -0x35addbd8)); // cmovae r23d, r29d, dword ptr [r22+r9*4-0x35addbd8] IID502 + __ ecmovl (Assembler::Condition::aboveEqual, r18, r18, Address(r25, +0x632184c3)); // cmovae r18d, dword ptr [r25+0x632184c3] IID503 + __ ecmovl (Assembler::Condition::zero, r29, r13, Address(r18, r13, (Address::ScaleFactor)0, -0x3972eac6)); // cmovz r29d, r13d, dword ptr [r18+r13*1-0x3972eac6] IID504 + __ ecmovl (Assembler::Condition::zero, r29, r29, Address(r12, r9, (Address::ScaleFactor)3, -0x668cdfd2)); // cmovz r29d, dword ptr [r12+r9*8-0x668cdfd2] IID505 + __ ecmovl (Assembler::Condition::notZero, r25, r18, Address(r9, r22, (Address::ScaleFactor)2, +0x7f6ac91f)); // cmovnz r25d, r18d, dword ptr [r9+r22*4+0x7f6ac91f] IID506 + __ ecmovl (Assembler::Condition::notZero, r28, r28, Address(r30, +0x562e6594)); // cmovnz r28d, dword ptr [r30+0x562e6594] IID507 + __ ecmovl (Assembler::Condition::belowEqual, r27, r24, Address(r15, r20, (Address::ScaleFactor)2, -0x466538b7)); // cmovbe r27d, r24d, dword ptr [r15+r20*4-0x466538b7] IID508 + __ ecmovl (Assembler::Condition::belowEqual, r25, r25, Address(r26, r11, (Address::ScaleFactor)3, -0x593812a9)); // cmovbe r25d, dword ptr [r26+r11*8-0x593812a9] IID509 + __ ecmovl (Assembler::Condition::above, rcx, r20, Address(r16, -0x1389a3eb)); // cmova ecx, r20d, dword ptr [r16-0x1389a3eb] IID510 + __ ecmovl (Assembler::Condition::above, rbx, rbx, Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615)); // cmova ebx, dword ptr [r29+r8*1+0x1d022615] IID511 + __ ecmovl (Assembler::Condition::negative, rdx, r14, Address(r12, r28, (Address::ScaleFactor)1, -0x51725a91)); // cmovs edx, r14d, dword ptr [r12+r28*2-0x51725a91] IID512 + __ ecmovl (Assembler::Condition::negative, r24, r24, Address(r17, r18, (Address::ScaleFactor)1, -0x1725c4e4)); // cmovs r24d, dword ptr [r17+r18*2-0x1725c4e4] IID513 + __ ecmovl (Assembler::Condition::positive, rcx, rcx, Address(r15, r23, (Address::ScaleFactor)2, -0x6bd22ccf)); // cmovns ecx, dword ptr [r15+r23*4-0x6bd22ccf] IID514 + __ ecmovl (Assembler::Condition::positive, r24, r24, Address(r15, r10, (Address::ScaleFactor)1, -0x7ffb3d09)); // cmovns r24d, dword ptr [r15+r10*2-0x7ffb3d09] IID515 + __ ecmovl (Assembler::Condition::parity, r23, rcx, Address(r11, r23, (Address::ScaleFactor)0, +0x3738c585)); // cmovp r23d, ecx, dword ptr [r11+r23*1+0x3738c585] IID516 + __ ecmovl (Assembler::Condition::parity, r24, r24, Address(r30, r10, (Address::ScaleFactor)0, +0xfcc15a8)); // cmovp r24d, dword ptr [r30+r10*1+0xfcc15a8] IID517 + __ ecmovl (Assembler::Condition::noParity, r14, r26, Address(r14, r21, (Address::ScaleFactor)1, -0x4430ce9f)); // cmovnp r14d, r26d, dword ptr [r14+r21*2-0x4430ce9f] IID518 + __ ecmovl (Assembler::Condition::noParity, r10, r10, Address(r28, +0x3d7c59f)); // cmovnp r10d, dword ptr [r28+0x3d7c59f] IID519 + __ ecmovl (Assembler::Condition::less, r10, r21, Address(r8, r8, (Address::ScaleFactor)3, +0x4a6584b4)); // cmovl r10d, r21d, dword ptr [r8+r8*8+0x4a6584b4] IID520 + __ ecmovl (Assembler::Condition::less, r26, r26, Address(r19, r20, (Address::ScaleFactor)3, +0x47c660ef)); // cmovl r26d, dword ptr [r19+r20*8+0x47c660ef] IID521 + __ ecmovl (Assembler::Condition::greaterEqual, r26, r10, Address(rcx, +0x61977a97)); // cmovge r26d, r10d, dword ptr [rcx+0x61977a97] IID522 + __ ecmovl (Assembler::Condition::greaterEqual, r30, r30, Address(r15, r19, (Address::ScaleFactor)3, +0x53c601cb)); // cmovge r30d, dword ptr [r15+r19*8+0x53c601cb] IID523 + __ ecmovl (Assembler::Condition::lessEqual, r14, r9, Address(r17, -0x566ceee2)); // cmovle r14d, r9d, dword ptr [r17-0x566ceee2] IID524 + __ ecmovl (Assembler::Condition::lessEqual, r15, r15, Address(r27, r20, (Address::ScaleFactor)0, +0x76164792)); // cmovle r15d, dword ptr [r27+r20*1+0x76164792] IID525 + __ ecmovl (Assembler::Condition::greater, r27, r14, Address(r9, r13, (Address::ScaleFactor)2, +0xf5752d7)); // cmovg r27d, r14d, dword ptr [r9+r13*4+0xf5752d7] IID526 + __ ecmovl (Assembler::Condition::greater, r12, r12, Address(rbx, rcx, (Address::ScaleFactor)3, -0x5501b4c6)); // cmovg r12d, dword ptr [rbx+rcx*8-0x5501b4c6] IID527 #endif // _LP64 #ifdef _LP64 - __ adcq(rbx, r31); // {load}adc rbx, r31 IID480 - __ cmpq(r30, r31); // {load}cmp r30, r31 IID481 - __ imulq(r29, r28); // {load}imul r29, r28 IID482 - __ popcntq(r25, r10); // {load}popcnt r25, r10 IID483 - __ sbbq(r24, r20); // {load}sbb r24, r20 IID484 - __ subq(r16, rdx); // {load}sub r16, rdx IID485 - __ tzcntq(r26, r28); // {load}tzcnt r26, r28 IID486 - __ lzcntq(r28, r9); // {load}lzcnt r28, r9 IID487 - __ addq(r20, r24); // {load}add r20, r24 IID488 - __ andq(r24, r29); // {load}and r24, r29 IID489 - __ orq(r23, r27); // {load}or r23, r27 IID490 - __ xorq(r15, r12); // {load}xor r15, r12 IID491 - __ movq(r18, r19); // {load}mov r18, r19 IID492 - __ bsfq(r31, rcx); // {load}bsf r31, rcx IID493 - __ bsrq(r9, r13); // {load}bsr r9, r13 IID494 - __ btq(r20, rcx); // {load}bt r20, rcx IID495 - __ xchgq(r8, r21); // {load}xchg r8, r21 IID496 - __ testq(r24, r14); // {load}test r24, r14 IID497 - __ addq(Address(rcx, r23, (Address::ScaleFactor)2, +0x4ff06c4d), r29); // add qword ptr [rcx+r23*4+0x4ff06c4d], r29 IID498 - __ andq(Address(r24, r10, (Address::ScaleFactor)1, -0x75d9a189), r26); // and qword ptr [r24+r10*2-0x75d9a189], r26 IID499 - __ cmpq(Address(rbx, rbx, (Address::ScaleFactor)0, +0x4033d59c), r17); // cmp qword ptr [rbx+rbx*1+0x4033d59c], r17 IID500 - __ orq(Address(r22, r12, (Address::ScaleFactor)3, -0x3893347d), r18); // or qword ptr [r22+r12*8-0x3893347d], r18 IID501 - __ xorq(Address(r20, r23, (Address::ScaleFactor)3, +0x4b311560), r12); // xor qword ptr [r20+r23*8+0x4b311560], r12 IID502 - __ subq(Address(r10, r28, (Address::ScaleFactor)2, +0x5c3a2657), r29); // sub qword ptr [r10+r28*4+0x5c3a2657], r29 IID503 - __ movq(Address(r13, r25, (Address::ScaleFactor)3, +0x1a3d6f3f), r22); // mov qword ptr [r13+r25*8+0x1a3d6f3f], r22 IID504 - __ xaddq(Address(r17, r24, (Address::ScaleFactor)3, -0x35addbd8), r25); // xadd qword ptr [r17+r24*8-0x35addbd8], r25 IID505 - __ andq(Address(r25, +0x632184c3), 16777216); // and qword ptr [r25+0x632184c3], 16777216 IID506 - __ addq(Address(r13, r13, (Address::ScaleFactor)0, -0x3972eac6), 16777216); // add qword ptr [r13+r13*1-0x3972eac6], 16777216 IID507 - __ cmpq(Address(r9, -0x13b4c806), 4096); // cmp qword ptr [r9-0x13b4c806], 4096 IID508 - __ sarq(Address(r31, +0x4fa7f551), 1); // sar qword ptr [r31+0x4fa7f551], 1 IID509 - __ salq(Address(r21, r31, (Address::ScaleFactor)2, +0x31aa8232), 1); // sal qword ptr [r21+r31*4+0x31aa8232], 1 IID510 - __ sbbq(Address(r24, r31, (Address::ScaleFactor)2, -0x466538b7), 268435456); // sbb qword ptr [r24+r31*4-0x466538b7], 268435456 IID511 - __ shrq(Address(r28, r22, (Address::ScaleFactor)0, -0x3efe85b1), 2); // shr qword ptr [r28+r22*1-0x3efe85b1], 2 IID512 - __ subq(Address(r16, -0x1389a3eb), 1048576); // sub qword ptr [r16-0x1389a3eb], 1048576 IID513 - __ xorq(Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615), 16); // xor qword ptr [r29+r8*1+0x1d022615], 16 IID514 - __ orq(Address(r12, r28, (Address::ScaleFactor)1, -0x34c898e2), 1); // or qword ptr [r12+r28*2-0x34c898e2], 1 IID515 - __ movq(Address(rcx, r24, (Address::ScaleFactor)2, -0x1644eb08), 256); // mov qword ptr [rcx+r24*4-0x1644eb08], 256 IID516 - __ testq(Address(r29, -0x7d23890b), -65536); // test qword ptr [r29-0x7d23890b], -65536 IID517 - __ addq(r23, Address(rcx, r19, (Address::ScaleFactor)2, +0x70eac654)); // add r23, qword ptr [rcx+r19*4+0x70eac654] IID518 - __ andq(rdx, Address(r24, r15, (Address::ScaleFactor)0, -0x204ddaa9)); // and rdx, qword ptr [r24+r15*1-0x204ddaa9] IID519 - __ cmpq(rdx, Address(r23, r11, (Address::ScaleFactor)3, +0x32c930bd)); // cmp rdx, qword ptr [r23+r11*8+0x32c930bd] IID520 - __ lzcntq(r28, Address(rdx, -0x5433c28f)); // lzcnt r28, qword ptr [rdx-0x5433c28f] IID521 - __ orq(r22, Address(r19, r14, (Address::ScaleFactor)1, -0x2cc67d38)); // or r22, qword ptr [r19+r14*2-0x2cc67d38] IID522 - __ adcq(r10, Address(r10, +0x3d7c59f)); // adc r10, qword ptr [r10+0x3d7c59f] IID523 - __ imulq(r10, Address(r8, r8, (Address::ScaleFactor)3, -0xe61862d)); // imul r10, qword ptr [r8+r8*8-0xe61862d] IID524 - __ popcntq(r23, Address(r29, -0x777ed96d)); // popcnt r23, qword ptr [r29-0x777ed96d] IID525 - __ sbbq(rcx, Address(rbx, r19, (Address::ScaleFactor)1, +0x53c601cb)); // sbb rcx, qword ptr [rbx+r19*2+0x53c601cb] IID526 - __ subq(r14, Address(r17, rbx, (Address::ScaleFactor)0, -0x768bf073)); // sub r14, qword ptr [r17+rbx*1-0x768bf073] IID527 - __ tzcntq(r29, Address(r10, r19, (Address::ScaleFactor)1, +0x30c98d3c)); // tzcnt r29, qword ptr [r10+r19*2+0x30c98d3c] IID528 - __ xorq(r10, Address(r16, r27, (Address::ScaleFactor)0, -0x3d08d602)); // xor r10, qword ptr [r16+r27*1-0x3d08d602] IID529 - __ movq(r18, Address(r28, r28, (Address::ScaleFactor)3, -0x62fbac91)); // mov r18, qword ptr [r28+r28*8-0x62fbac91] IID530 - __ leaq(rbx, Address(rcx, +0x450602a5)); // lea rbx, qword ptr [rcx+0x450602a5] IID531 - __ cvttsd2siq(r12, Address(r30, r31, (Address::ScaleFactor)0, -0x6798a630)); // cvttsd2si r12, qword ptr [r30+r31*1-0x6798a630] IID532 - __ xchgq(r31, Address(r24, r10, (Address::ScaleFactor)1, -0x706712ed)); // xchg r31, qword ptr [r24+r10*2-0x706712ed] IID533 - __ testq(r14, Address(r13, r20, (Address::ScaleFactor)3, +0x171081f2)); // test r14, qword ptr [r13+r20*8+0x171081f2] IID534 - __ addq(r31, 16); // add r31, 16 IID535 - __ andq(r25, 16); // and r25, 16 IID536 - __ adcq(r23, 256); // adc r23, 256 IID537 - __ cmpq(r19, 268435456); // cmp r19, 268435456 IID538 - __ rclq(r31, 1); // rcl r31, 1 IID539 - __ rcrq(r17, 1); // rcr r17, 1 IID540 - __ rolq(r25, 2); // rol r25, 2 IID541 - __ rorq(r17, 4); // ror r17, 4 IID542 - __ sarq(r28, 1); // sar r28, 1 IID543 - __ salq(r15, 4); // sal r15, 4 IID544 - __ sbbq(rbx, 65536); // sbb rbx, 65536 IID545 - __ shlq(r21, 1); // shl r21, 1 IID546 - __ shrq(r10, 1); // shr r10, 1 IID547 - __ subq(r14, 16); // sub r14, 16 IID548 - __ xorq(r18, 268435456); // xor r18, 268435456 IID549 - __ movq(r23, 16); // mov r23, 16 IID550 - __ mov64(r12, 1099511627776); // mov r12, 1099511627776 IID551 - __ btq(r14, 4); // bt r14, 4 IID552 - __ testq(r24, -4096); // test r24, -4096 IID553 - __ orq_imm32(r19, 1048576); // or r19, 1048576 IID554 - __ subq_imm32(rcx, 268435456); // sub rcx, 268435456 IID555 - __ cmovq(Assembler::Condition::overflow, rdx, Address(r19, rbx, (Address::ScaleFactor)3, +0x211c8c4)); // cmovo rdx, qword ptr [r19+rbx*8+0x211c8c4] IID556 - __ cmovq(Assembler::Condition::noOverflow, rbx, Address(r21, +0x49267743)); // cmovno rbx, qword ptr [r21+0x49267743] IID557 - __ cmovq(Assembler::Condition::below, r21, Address(r8, r28, (Address::ScaleFactor)1, -0x4c8c2946)); // cmovb r21, qword ptr [r8+r28*2-0x4c8c2946] IID558 - __ cmovq(Assembler::Condition::aboveEqual, r12, Address(r26, r20, (Address::ScaleFactor)0, -0x264df89c)); // cmovae r12, qword ptr [r26+r20*1-0x264df89c] IID559 - __ cmovq(Assembler::Condition::zero, r17, Address(r28, r9, (Address::ScaleFactor)2, +0x3497196b)); // cmovz r17, qword ptr [r28+r9*4+0x3497196b] IID560 - __ cmovq(Assembler::Condition::notZero, r13, Address(r15, r23, (Address::ScaleFactor)1, -0x27a30999)); // cmovnz r13, qword ptr [r15+r23*2-0x27a30999] IID561 - __ cmovq(Assembler::Condition::belowEqual, r22, Address(r22, +0xf39ab05)); // cmovbe r22, qword ptr [r22+0xf39ab05] IID562 - __ cmovq(Assembler::Condition::above, rcx, Address(r22, r26, (Address::ScaleFactor)3, -0x48c954c)); // cmova rcx, qword ptr [r22+r26*8-0x48c954c] IID563 - __ cmovq(Assembler::Condition::negative, r25, Address(r19, r21, (Address::ScaleFactor)0, +0xe405b0b)); // cmovs r25, qword ptr [r19+r21*1+0xe405b0b] IID564 - __ cmovq(Assembler::Condition::positive, r12, Address(r19, r29, (Address::ScaleFactor)3, -0x7762044b)); // cmovns r12, qword ptr [r19+r29*8-0x7762044b] IID565 - __ cmovq(Assembler::Condition::parity, rbx, Address(r30, r10, (Address::ScaleFactor)1, -0x19798323)); // cmovp rbx, qword ptr [r30+r10*2-0x19798323] IID566 - __ cmovq(Assembler::Condition::noParity, r21, Address(r24, r31, (Address::ScaleFactor)0, -0x5731652b)); // cmovnp r21, qword ptr [r24+r31*1-0x5731652b] IID567 - __ cmovq(Assembler::Condition::less, r18, Address(r8, r10, (Address::ScaleFactor)1, -0x5613be89)); // cmovl r18, qword ptr [r8+r10*2-0x5613be89] IID568 - __ cmovq(Assembler::Condition::greaterEqual, r28, Address(r21, r21, (Address::ScaleFactor)3, +0x65a0fdc4)); // cmovge r28, qword ptr [r21+r21*8+0x65a0fdc4] IID569 - __ cmovq(Assembler::Condition::lessEqual, r23, Address(r11, r18, (Address::ScaleFactor)0, -0x1d1af10c)); // cmovle r23, qword ptr [r11+r18*1-0x1d1af10c] IID570 - __ cmovq(Assembler::Condition::greater, r22, Address(r18, r12, (Address::ScaleFactor)1, +0x1a5f1c38)); // cmovg r22, qword ptr [r18+r12*2+0x1a5f1c38] IID571 - __ call(r23); // call r23 IID572 - __ divq(r30); // div r30 IID573 - __ idivq(r19); // idiv r19 IID574 - __ imulq(r9); // imul r9 IID575 - __ mulq(r13); // mul r13 IID576 - __ negq(r16); // neg r16 IID577 - __ notq(r29); // not r29 IID578 - __ rolq(rcx); // rol rcx, cl IID579 - __ rorq(r25); // ror r25, cl IID580 - __ sarq(r8); // sar r8, cl IID581 - __ salq(r27); // sal r27, cl IID582 - __ shlq(r30); // shl r30, cl IID583 - __ shrq(r23); // shr r23, cl IID584 - __ incrementq(rbx); // inc rbx IID585 - __ decrementq(r14); // dec r14 IID586 - __ pushp(r21); // pushp r21 IID587 - __ popp(r21); // popp r21 IID588 - __ call(Address(r20, r21, (Address::ScaleFactor)1, +0x56c6af2f)); // call qword ptr [r20+r21*2+0x56c6af2f] IID589 - __ mulq(Address(r31, r19, (Address::ScaleFactor)3, -0x1b4eb23)); // mul qword ptr [r31+r19*8-0x1b4eb23] IID590 - __ negq(Address(r27, r27, (Address::ScaleFactor)0, -0x58dbfc1f)); // neg qword ptr [r27+r27*1-0x58dbfc1f] IID591 - __ sarq(Address(rbx, r22, (Address::ScaleFactor)2, -0x606349d1)); // sar qword ptr [rbx+r22*4-0x606349d1], cl IID592 - __ salq(Address(r26, r23, (Address::ScaleFactor)3, +0xb95a079)); // sal qword ptr [r26+r23*8+0xb95a079], cl IID593 - __ shrq(Address(r14, r26, (Address::ScaleFactor)0, +0x3544e09)); // shr qword ptr [r14+r26*1+0x3544e09], cl IID594 - __ incrementq(Address(r27, rdx, (Address::ScaleFactor)0, +0x120b3250)); // inc qword ptr [r27+rdx*1+0x120b3250] IID595 - __ decrementq(Address(r9, r25, (Address::ScaleFactor)2, -0x34aaeccb)); // dec qword ptr [r9+r25*4-0x34aaeccb] IID596 - __ imulq(r20, Address(r16, r28, (Address::ScaleFactor)1, -0x59de05a5), 1048576); // imul r20, qword ptr [r16+r28*2-0x59de05a5], 1048576 IID597 - __ imulq(r17, r23, 256); // imul r17, r23, 256 IID598 - __ shldq(r19, r11, 8); // shld r19, r11, 8 IID599 - __ shrdq(r28, r10, 8); // shrd r28, r10, 8 IID600 - __ pop2(r29, r26); // {load}pop2 r26, r29 IID601 - __ pop2p(r22, r10); // {load}pop2p r10, r22 IID602 - __ push2(r25, r30); // {load}push2 r30, r25 IID603 - __ push2p(r28, r15); // {load}push2p r15, r28 IID604 - __ movzbq(r11, Address(r29, r19, (Address::ScaleFactor)2, -0x12368d34)); // movzx r11, byte ptr [r29+r19*4-0x12368d34] IID605 - __ movzwq(r14, Address(r8, r30, (Address::ScaleFactor)2, -0x4a9392de)); // movzx r14, word ptr [r8+r30*4-0x4a9392de] IID606 - __ movsbq(r28, Address(r23, r15, (Address::ScaleFactor)0, +0x6189cb54)); // movsx r28, byte ptr [r23+r15*1+0x6189cb54] IID607 - __ movswq(r28, Address(rbx, r23, (Address::ScaleFactor)3, -0x2de86561)); // movsx r28, word ptr [rbx+r23*8-0x2de86561] IID608 - __ movzbq(r11, rcx); // movzx r11, cl IID609 - __ movzwq(r30, r15); // movzx r30, r15w IID610 - __ movsbq(r14, rcx); // movsx r14, cl IID611 - __ movswq(r23, r9); // movsx r23, r9w IID612 - __ cmpxchgq(r12, Address(r13, r10, (Address::ScaleFactor)1, -0x7c62c3a)); // cmpxchg qword ptr [r13+r10*2-0x7c62c3a], r12 IID613 - __ eidivq(rcx, false); // {EVEX}idiv rcx IID614 - __ eidivq(r15, true); // {NF}idiv r15 IID615 - __ edivq(r23, false); // {EVEX}div r23 IID616 - __ edivq(r24, true); // {NF}div r24 IID617 - __ eimulq(r27, false); // {EVEX}imul r27 IID618 - __ eimulq(r30, true); // {NF}imul r30 IID619 - __ emulq(r12, false); // {EVEX}mul r12 IID620 - __ emulq(rcx, true); // {NF}mul rcx IID621 - __ emulq(Address(r13, r9, (Address::ScaleFactor)3, -0x226aab94), false); // {EVEX}mul qword ptr [r13+r9*8-0x226aab94] IID622 - __ emulq(Address(r13, r24, (Address::ScaleFactor)3, -0x286c7605), true); // {NF}mul qword ptr [r13+r24*8-0x286c7605] IID623 - __ eimulq(r21, r30, false); // {EVEX}imul r21, r30 IID624 - __ eimulq(r17, r17, false); // imul r17 IID625 - __ eimulq(r29, r12, true); // {NF}imul r29, r12 IID626 - __ eimulq(r30, r30, true); // {NF}imul r30, r30 IID627 - __ elzcntq(r24, r15, false); // {EVEX}lzcnt r24, r15 IID628 - __ elzcntq(r25, r25, false); // {EVEX}lzcnt r25, r25 IID629 - __ elzcntq(r25, r21, true); // {NF}lzcnt r25, r21 IID630 - __ elzcntq(r22, r22, true); // {NF}lzcnt r22, r22 IID631 - __ enegq(r17, r30, false); // {EVEX}neg r17, r30 IID632 - __ enegq(r17, r17, false); // neg r17 IID633 - __ enegq(r31, r17, true); // {NF}neg r31, r17 IID634 - __ enegq(r29, r29, true); // {NF}neg r29, r29 IID635 - __ enotq(r10, r9); // {EVEX}not r10, r9 IID636 - __ enotq(r24, r24); // not r24 IID637 - __ epopcntq(r28, r15, false); // {EVEX}popcnt r28, r15 IID638 - __ epopcntq(r10, r10, false); // {EVEX}popcnt r10, r10 IID639 - __ epopcntq(r27, r30, true); // {NF}popcnt r27, r30 IID640 - __ epopcntq(r28, r28, true); // {NF}popcnt r28, r28 IID641 - __ erolq(r28, r14, false); // {EVEX}rol r28, r14, cl IID642 - __ erolq(r23, r23, false); // rol r23, cl IID643 - __ erolq(r23, r24, true); // {NF}rol r23, r24, cl IID644 - __ erolq(r21, r21, true); // {NF}rol r21, r21, cl IID645 - __ erorq(r31, r22, false); // {EVEX}ror r31, r22, cl IID646 - __ erorq(r28, r28, false); // ror r28, cl IID647 - __ erorq(r17, r10, true); // {NF}ror r17, r10, cl IID648 - __ erorq(r9, r9, true); // {NF}ror r9, r9, cl IID649 - __ esalq(r29, r30, false); // {EVEX}sal r29, r30, cl IID650 - __ esalq(r11, r11, false); // sal r11, cl IID651 - __ esalq(r26, r11, true); // {NF}sal r26, r11, cl IID652 - __ esalq(r16, r16, true); // {NF}sal r16, r16, cl IID653 - __ esarq(rbx, r15, false); // {EVEX}sar rbx, r15, cl IID654 - __ esarq(r14, r14, false); // sar r14, cl IID655 - __ esarq(r25, r16, true); // {NF}sar r25, r16, cl IID656 - __ esarq(r8, r8, true); // {NF}sar r8, r8, cl IID657 - __ edecq(r11, r13, false); // {EVEX}dec r11, r13 IID658 - __ edecq(rcx, rcx, false); // dec rcx IID659 - __ edecq(r21, r18, true); // {NF}dec r21, r18 IID660 - __ edecq(r28, r28, true); // {NF}dec r28, r28 IID661 - __ eincq(r16, r16, false); // inc r16 IID662 - __ eincq(r29, r29, false); // inc r29 IID663 - __ eincq(r18, r9, true); // {NF}inc r18, r9 IID664 - __ eincq(r19, r19, true); // {NF}inc r19, r19 IID665 - __ eshlq(r19, r18, false); // {EVEX}shl r19, r18, cl IID666 - __ eshlq(r8, r8, false); // shl r8, cl IID667 - __ eshlq(r12, r15, true); // {NF}shl r12, r15, cl IID668 - __ eshlq(r29, r29, true); // {NF}shl r29, r29, cl IID669 - __ eshrq(r28, r24, false); // {EVEX}shr r28, r24, cl IID670 - __ eshrq(r19, r19, false); // shr r19, cl IID671 - __ eshrq(r8, r28, true); // {NF}shr r8, r28, cl IID672 - __ eshrq(r17, r17, true); // {NF}shr r17, r17, cl IID673 - __ etzcntq(r28, r16, false); // {EVEX}tzcnt r28, r16 IID674 - __ etzcntq(r14, r14, false); // {EVEX}tzcnt r14, r14 IID675 - __ etzcntq(r12, r31, true); // {NF}tzcnt r12, r31 IID676 - __ etzcntq(r14, r14, true); // {NF}tzcnt r14, r14 IID677 - __ eimulq(r31, Address(r13, -0x69c4b352), false); // {EVEX}imul r31, qword ptr [r13-0x69c4b352] IID678 - __ eimulq(r17, Address(r18, -0x60ab1105), true); // {NF}imul r17, qword ptr [r18-0x60ab1105] IID679 - __ elzcntq(r27, Address(r14, r25, (Address::ScaleFactor)2, +0x2798bf83), false); // {EVEX}lzcnt r27, qword ptr [r14+r25*4+0x2798bf83] IID680 - __ elzcntq(r23, Address(r10, r11, (Address::ScaleFactor)0, -0x378e635d), true); // {NF}lzcnt r23, qword ptr [r10+r11*1-0x378e635d] IID681 - __ enegq(rcx, Address(r19, r9, (Address::ScaleFactor)3, -0x6847d440), false); // {EVEX}neg rcx, qword ptr [r19+r9*8-0x6847d440] IID682 - __ enegq(rcx, Address(rbx, rcx, (Address::ScaleFactor)0, +0x6f92d38d), true); // {NF}neg rcx, qword ptr [rbx+rcx*1+0x6f92d38d] IID683 - __ epopcntq(r20, Address(r12, -0x2a8b27d6), false); // {EVEX}popcnt r20, qword ptr [r12-0x2a8b27d6] IID684 - __ epopcntq(r31, Address(r30, +0x4603f6d0), true); // {NF}popcnt r31, qword ptr [r30+0x4603f6d0] IID685 - __ esalq(rbx, Address(r24, +0x567d06f9), false); // {EVEX}sal rbx, qword ptr [r24+0x567d06f9], cl IID686 - __ esalq(r12, Address(r24, r28, (Address::ScaleFactor)0, -0x1c4c584e), true); // {NF}sal r12, qword ptr [r24+r28*1-0x1c4c584e], cl IID687 - __ esarq(r12, Address(r23, r24, (Address::ScaleFactor)2, -0x3157bcba), false); // {EVEX}sar r12, qword ptr [r23+r24*4-0x3157bcba], cl IID688 - __ esarq(r8, Address(r14, r24, (Address::ScaleFactor)2, -0x714290a5), true); // {NF}sar r8, qword ptr [r14+r24*4-0x714290a5], cl IID689 - __ edecq(r23, Address(r8, r15, (Address::ScaleFactor)1, -0x5ae272dd), false); // {EVEX}dec r23, qword ptr [r8+r15*2-0x5ae272dd] IID690 - __ edecq(r13, Address(r29, r9, (Address::ScaleFactor)3, -0x5b5174a9), true); // {NF}dec r13, qword ptr [r29+r9*8-0x5b5174a9] IID691 - __ eincq(r11, Address(r21, r31, (Address::ScaleFactor)3, -0x2176b4dc), false); // {EVEX}inc r11, qword ptr [r21+r31*8-0x2176b4dc] IID692 - __ eincq(r13, Address(rcx, r16, (Address::ScaleFactor)0, -0x36b448c9), true); // {NF}inc r13, qword ptr [rcx+r16*1-0x36b448c9] IID693 - __ eshrq(r26, Address(r25, rcx, (Address::ScaleFactor)2, -0x5f894993), false); // {EVEX}shr r26, qword ptr [r25+rcx*4-0x5f894993], cl IID694 - __ eshrq(r25, Address(r9, +0x51798d21), true); // {NF}shr r25, qword ptr [r9+0x51798d21], cl IID695 - __ etzcntq(r28, Address(r13, r26, (Address::ScaleFactor)2, +0x207196f6), false); // {EVEX}tzcnt r28, qword ptr [r13+r26*4+0x207196f6] IID696 - __ etzcntq(rbx, Address(r19, r13, (Address::ScaleFactor)0, -0x24d937d5), true); // {NF}tzcnt rbx, qword ptr [r19+r13*1-0x24d937d5] IID697 - __ eaddq(r17, Address(r30, +0x3935ccff), r31, false); // {EVEX}add r17, qword ptr [r30+0x3935ccff], r31 IID698 - __ eaddq(r14, Address(r27, r10, (Address::ScaleFactor)2, -0x34ad9bab), r14, false); // {EVEX}add r14, qword ptr [r27+r10*4-0x34ad9bab], r14 IID699 - __ eaddq(r18, Address(r20, r23, (Address::ScaleFactor)0, +0x5ad3ed4b), r30, true); // {NF}add r18, qword ptr [r20+r23*1+0x5ad3ed4b], r30 IID700 - __ eaddq(r20, Address(rdx, -0x322a99e5), r20, true); // {NF}add r20, qword ptr [rdx-0x322a99e5], r20 IID701 - __ eandq(r31, Address(rbx, r27, (Address::ScaleFactor)3, +0x4ce247d2), r17, false); // {EVEX}and r31, qword ptr [rbx+r27*8+0x4ce247d2], r17 IID702 - __ eandq(r30, Address(r18, r19, (Address::ScaleFactor)1, -0x4ee3d14), r30, false); // {EVEX}and r30, qword ptr [r18+r19*2-0x4ee3d14], r30 IID703 - __ eandq(r28, Address(r11, rbx, (Address::ScaleFactor)3, -0x28994bbf), r24, true); // {NF}and r28, qword ptr [r11+rbx*8-0x28994bbf], r24 IID704 - __ eandq(r30, Address(r22, +0x7d21c24), r30, true); // {NF}and r30, qword ptr [r22+0x7d21c24], r30 IID705 - __ eorq(r26, Address(r15, r19, (Address::ScaleFactor)3, +0x58c21792), r20, false); // {EVEX}or r26, qword ptr [r15+r19*8+0x58c21792], r20 IID706 - __ eorq(r13, Address(r10, r27, (Address::ScaleFactor)2, -0x2c70d333), r13, false); // {EVEX}or r13, qword ptr [r10+r27*4-0x2c70d333], r13 IID707 - __ eorq(rbx, Address(r12, rbx, (Address::ScaleFactor)0, -0x1fb0f1bc), r26, true); // {NF}or rbx, qword ptr [r12+rbx*1-0x1fb0f1bc], r26 IID708 - __ eorq(r31, Address(r27, r31, (Address::ScaleFactor)1, +0x28d1756), r31, true); // {NF}or r31, qword ptr [r27+r31*2+0x28d1756], r31 IID709 - __ esubq(r24, Address(r28, r23, (Address::ScaleFactor)1, +0x6980f610), r27, false); // {EVEX}sub r24, qword ptr [r28+r23*2+0x6980f610], r27 IID710 - __ esubq(r15, Address(r11, r30, (Address::ScaleFactor)3, -0x49777e7), r15, false); // {EVEX}sub r15, qword ptr [r11+r30*8-0x49777e7], r15 IID711 - __ esubq(r17, Address(r25, r13, (Address::ScaleFactor)2, +0x31619e46), r31, true); // {NF}sub r17, qword ptr [r25+r13*4+0x31619e46], r31 IID712 - __ esubq(r18, Address(r11, r10, (Address::ScaleFactor)2, +0x1922861a), r18, true); // {NF}sub r18, qword ptr [r11+r10*4+0x1922861a], r18 IID713 - __ exorq(rbx, Address(r11, -0x4716d420), r21, false); // {EVEX}xor rbx, qword ptr [r11-0x4716d420], r21 IID714 - __ exorq(r8, Address(rdx, r9, (Address::ScaleFactor)2, -0x4cfe39c), r8, false); // {EVEX}xor r8, qword ptr [rdx+r9*4-0x4cfe39c], r8 IID715 - __ exorq(r16, Address(r14, r27, (Address::ScaleFactor)0, +0x7c6654d9), r25, true); // {NF}xor r16, qword ptr [r14+r27*1+0x7c6654d9], r25 IID716 - __ exorq(r29, Address(r15, -0x5efab479), r29, true); // {NF}xor r29, qword ptr [r15-0x5efab479], r29 IID717 - __ eaddq(r19, Address(r13, r22, (Address::ScaleFactor)2, +0x68b64559), 16777216, false); // {EVEX}add r19, qword ptr [r13+r22*4+0x68b64559], 16777216 IID718 - __ eaddq(r16, Address(r13, r31, (Address::ScaleFactor)3, -0x65143af5), 1, true); // {NF}add r16, qword ptr [r13+r31*8-0x65143af5], 1 IID719 - __ eandq(r31, Address(r24, r13, (Address::ScaleFactor)1, -0x25b16a0e), 1, false); // {EVEX}and r31, qword ptr [r24+r13*2-0x25b16a0e], 1 IID720 - __ eandq(r11, Address(r28, -0xf6d4b26), 65536, true); // {NF}and r11, qword ptr [r28-0xf6d4b26], 65536 IID721 - __ eimulq(rcx, Address(r18, r10, (Address::ScaleFactor)0, +0x46ec6da1), 16777216, false); // {EVEX}imul rcx, qword ptr [r18+r10*1+0x46ec6da1], 16777216 IID722 - __ eimulq(r15, Address(r9, r10, (Address::ScaleFactor)3, -0x7fc36af3), 16, true); // {NF}imul r15, qword ptr [r9+r10*8-0x7fc36af3], 16 IID723 - __ eorq(r17, Address(r27, r30, (Address::ScaleFactor)0, +0x1b4cda2c), 1, false); // {EVEX}or r17, qword ptr [r27+r30*1+0x1b4cda2c], 1 IID724 - __ eorq(rdx, Address(r25, r14, (Address::ScaleFactor)2, -0x59aa6b85), 4096, true); // {NF}or rdx, qword ptr [r25+r14*4-0x59aa6b85], 4096 IID725 - __ esalq(r17, Address(r26, r21, (Address::ScaleFactor)1, -0x6ab1f15f), 8, false); // {EVEX}sal r17, qword ptr [r26+r21*2-0x6ab1f15f], 8 IID726 - __ esalq(r12, Address(r22, r17, (Address::ScaleFactor)0, -0x43ac14ab), 2, true); // {NF}sal r12, qword ptr [r22+r17*1-0x43ac14ab], 2 IID727 - __ esarq(r29, Address(r18, r16, (Address::ScaleFactor)0, -0x59dc0c61), 4, false); // {EVEX}sar r29, qword ptr [r18+r16*1-0x59dc0c61], 4 IID728 - __ esarq(r16, Address(r11, -0x7bdd314), 4, true); // {NF}sar r16, qword ptr [r11-0x7bdd314], 4 IID729 - __ eshrq(r26, Address(r23, r27, (Address::ScaleFactor)3, -0x55b92314), 16, false); // {EVEX}shr r26, qword ptr [r23+r27*8-0x55b92314], 16 IID730 - __ eshrq(r23, Address(r16, r29, (Address::ScaleFactor)1, +0x71311a1d), 2, true); // {NF}shr r23, qword ptr [r16+r29*2+0x71311a1d], 2 IID731 - __ esubq(r25, Address(r9, -0x9532bac), 1048576, false); // {EVEX}sub r25, qword ptr [r9-0x9532bac], 1048576 IID732 - __ esubq(r17, Address(r8, r23, (Address::ScaleFactor)0, +0x55d06ca2), 1048576, true); // {NF}sub r17, qword ptr [r8+r23*1+0x55d06ca2], 1048576 IID733 - __ exorq(r29, Address(r9, r24, (Address::ScaleFactor)0, -0x2c141c1), 1048576, false); // {EVEX}xor r29, qword ptr [r9+r24*1-0x2c141c1], 1048576 IID734 - __ exorq(r28, Address(r22, r19, (Address::ScaleFactor)1, -0x2d9d9abd), 16, true); // {NF}xor r28, qword ptr [r22+r19*2-0x2d9d9abd], 16 IID735 - __ eaddq(r22, r14, 16, false); // {EVEX}add r22, r14, 16 IID736 - __ eaddq(rax, r12, 16, false); // {EVEX}add rax, r12, 16 IID737 - __ eaddq(r24, r24, 65536, false); // add r24, 65536 IID738 - __ eaddq(r21, rbx, 65536, true); // {NF}add r21, rbx, 65536 IID739 - __ eaddq(rax, rbx, 65536, true); // {NF}add rax, rbx, 65536 IID740 - __ eaddq(r24, r24, 65536, true); // {NF}add r24, r24, 65536 IID741 - __ eandq(r21, r27, 16777216, false); // {EVEX}and r21, r27, 16777216 IID742 - __ eandq(rax, r27, 16777216, false); // {EVEX}and rax, r27, 16777216 IID743 - __ eandq(r24, r24, 65536, false); // and r24, 65536 IID744 - __ eandq(r13, r31, 1048576, true); // {NF}and r13, r31, 1048576 IID745 - __ eandq(rax, r21, 1048576, true); // {NF}and rax, r21, 1048576 IID746 - __ eandq(r30, r30, 1048576, true); // {NF}and r30, r30, 1048576 IID747 - __ eimulq(r8, r13, 268435456, false); // {EVEX}imul r8, r13, 268435456 IID748 - __ eimulq(rax, r31, 268435456, false); // {EVEX}imul rax, r31, 268435456 IID749 - __ eimulq(r13, r13, 65536, false); // {EVEX}imul r13, r13, 65536 IID750 - __ eimulq(r14, r29, 1048576, true); // {NF}imul r14, r29, 1048576 IID751 - __ eimulq(rax, r22, 1048576, true); // {NF}imul rax, r22, 1048576 IID752 - __ eimulq(r8, r8, 268435456, true); // {NF}imul r8, r8, 268435456 IID753 - __ eorq(r30, r15, 4096, false); // {EVEX}or r30, r15, 4096 IID754 - __ eorq(rax, r28, 4096, false); // {EVEX}or rax, r28, 4096 IID755 - __ eorq(r26, r26, 1048576, false); // or r26, 1048576 IID756 - __ eorq(r16, r12, 268435456, true); // {NF}or r16, r12, 268435456 IID757 - __ eorq(rax, r9, 268435456, true); // {NF}or rax, r9, 268435456 IID758 - __ eorq(r23, r23, 256, true); // {NF}or r23, r23, 256 IID759 - __ erclq(r15, r9, 16); // {EVEX}rcl r15, r9, 16 IID760 - __ erclq(rax, r8, 16); // {EVEX}rcl rax, r8, 16 IID761 - __ erclq(r25, r25, 1); // rcl r25, 1 IID762 - __ erolq(r9, r17, 16, false); // {EVEX}rol r9, r17, 16 IID763 - __ erolq(rax, r20, 16, false); // {EVEX}rol rax, r20, 16 IID764 - __ erolq(r27, r27, 1, false); // rol r27, 1 IID765 - __ erolq(r20, r31, 1, true); // {NF}rol r20, r31, 1 IID766 - __ erolq(rax, r18, 1, true); // {NF}rol rax, r18, 1 IID767 - __ erolq(r28, r28, 16, true); // {NF}rol r28, r28, 16 IID768 - __ erorq(r26, r18, 16, false); // {EVEX}ror r26, r18, 16 IID769 - __ erorq(rax, r24, 16, false); // {EVEX}ror rax, r24, 16 IID770 - __ erorq(r22, r22, 16, false); // ror r22, 16 IID771 - __ erorq(r27, r29, 1, true); // {NF}ror r27, r29, 1 IID772 - __ erorq(rax, r18, 1, true); // {NF}ror rax, r18, 1 IID773 - __ erorq(r21, r21, 1, true); // {NF}ror r21, r21, 1 IID774 - __ esalq(r12, rcx, 2, false); // {EVEX}sal r12, rcx, 2 IID775 - __ esalq(rax, r24, 2, false); // {EVEX}sal rax, r24, 2 IID776 - __ esalq(r22, r22, 8, false); // sal r22, 8 IID777 - __ esalq(r17, r23, 8, true); // {NF}sal r17, r23, 8 IID778 - __ esalq(rax, r27, 8, true); // {NF}sal rax, r27, 8 IID779 - __ esalq(r23, r23, 1, true); // {NF}sal r23, r23, 1 IID780 - __ esarq(r8, r25, 16, false); // {EVEX}sar r8, r25, 16 IID781 - __ esarq(rax, r23, 16, false); // {EVEX}sar rax, r23, 16 IID782 - __ esarq(r9, r9, 4, false); // sar r9, 4 IID783 - __ esarq(r22, r13, 1, true); // {NF}sar r22, r13, 1 IID784 - __ esarq(rax, r11, 1, true); // {NF}sar rax, r11, 1 IID785 - __ esarq(r12, r12, 2, true); // {NF}sar r12, r12, 2 IID786 - __ eshlq(rcx, r30, 8, false); // {EVEX}shl rcx, r30, 8 IID787 - __ eshlq(rax, r19, 8, false); // {EVEX}shl rax, r19, 8 IID788 - __ eshlq(r13, r13, 2, false); // shl r13, 2 IID789 - __ eshlq(r18, r11, 8, true); // {NF}shl r18, r11, 8 IID790 - __ eshlq(rax, r9, 8, true); // {NF}shl rax, r9, 8 IID791 - __ eshlq(rcx, rcx, 16, true); // {NF}shl rcx, rcx, 16 IID792 - __ eshrq(r10, r22, 4, false); // {EVEX}shr r10, r22, 4 IID793 - __ eshrq(rax, r9, 4, false); // {EVEX}shr rax, r9, 4 IID794 - __ eshrq(r12, r12, 2, false); // shr r12, 2 IID795 - __ eshrq(r26, r31, 8, true); // {NF}shr r26, r31, 8 IID796 - __ eshrq(rax, r12, 8, true); // {NF}shr rax, r12, 8 IID797 - __ eshrq(r28, r28, 1, true); // {NF}shr r28, r28, 1 IID798 - __ esubq(r15, r30, 65536, false); // {EVEX}sub r15, r30, 65536 IID799 - __ esubq(rax, rcx, 65536, false); // {EVEX}sub rax, rcx, 65536 IID800 - __ esubq(r26, r26, 16, false); // sub r26, 16 IID801 - __ esubq(r12, r14, 1, true); // {NF}sub r12, r14, 1 IID802 - __ esubq(rax, r21, 1, true); // {NF}sub rax, r21, 1 IID803 - __ esubq(r20, r20, 1048576, true); // {NF}sub r20, r20, 1048576 IID804 - __ exorq(r11, rbx, 16777216, false); // {EVEX}xor r11, rbx, 16777216 IID805 - __ exorq(rax, r23, 16777216, false); // {EVEX}xor rax, r23, 16777216 IID806 - __ exorq(r31, r31, 268435456, false); // xor r31, 268435456 IID807 - __ exorq(r29, r28, 4096, true); // {NF}xor r29, r28, 4096 IID808 - __ exorq(rax, r19, 4096, true); // {NF}xor rax, r19, 4096 IID809 - __ exorq(rdx, rdx, 268435456, true); // {NF}xor rdx, rdx, 268435456 IID810 - __ eorq_imm32(rdx, rdx, 1048576, false); // or rdx, 1048576 IID811 - __ eorq_imm32(rax, r22, 1048576, false); // {EVEX}or rax, r22, 1048576 IID812 - __ eorq_imm32(r29, r29, 1048576, false); // or r29, 1048576 IID813 - __ eorq_imm32(r17, rcx, 4194304, false); // {EVEX}or r17, rcx, 4194304 IID814 - __ eorq_imm32(rax, r25, 4194304, false); // {EVEX}or rax, r25, 4194304 IID815 - __ eorq_imm32(r27, r27, 1073741824, false); // or r27, 1073741824 IID816 - __ esubq_imm32(r16, r19, 4194304, false); // {EVEX}sub r16, r19, 4194304 IID817 - __ esubq_imm32(rax, r31, 4194304, false); // {EVEX}sub rax, r31, 4194304 IID818 - __ esubq_imm32(r26, r26, 262144, false); // sub r26, 262144 IID819 - __ esubq_imm32(r17, r22, 1073741824, true); // {NF}sub r17, r22, 1073741824 IID820 - __ esubq_imm32(rax, r18, 1073741824, true); // {NF}sub rax, r18, 1073741824 IID821 - __ esubq_imm32(r23, r23, 268435456, true); // {NF}sub r23, r23, 268435456 IID822 - __ eaddq(r13, r30, Address(r24, r19, (Address::ScaleFactor)1, +0x56ea3a3b), false); // {EVEX}add r13, r30, qword ptr [r24+r19*2+0x56ea3a3b] IID823 - __ eaddq(r29, r15, Address(r26, r27, (Address::ScaleFactor)3, -0x4b113958), true); // {NF}add r29, r15, qword ptr [r26+r27*8-0x4b113958] IID824 - __ eandq(r12, r30, Address(r31, -0x46103c74), false); // {EVEX}and r12, r30, qword ptr [r31-0x46103c74] IID825 - __ eandq(r27, r10, Address(r22, r25, (Address::ScaleFactor)1, +0x6a1ebee5), true); // {NF}and r27, r10, qword ptr [r22+r25*2+0x6a1ebee5] IID826 - __ eorq(r30, r26, Address(r11, r18, (Address::ScaleFactor)2, -0x2b9fff29), false); // {EVEX}or r30, r26, qword ptr [r11+r18*4-0x2b9fff29] IID827 - __ eorq(r9, r12, Address(r18, r17, (Address::ScaleFactor)0, +0xb4859f6), true); // {NF}or r9, r12, qword ptr [r18+r17*1+0xb4859f6] IID828 - __ eimulq(rdx, r17, Address(r24, rdx, (Address::ScaleFactor)2, +0x3d284cd8), false); // {EVEX}imul rdx, r17, qword ptr [r24+rdx*4+0x3d284cd8] IID829 - __ eimulq(r29, r26, Address(r30, r12, (Address::ScaleFactor)1, +0x6e813124), true); // {NF}imul r29, r26, qword ptr [r30+r12*2+0x6e813124] IID830 - __ esubq(rbx, r13, Address(r22, -0x702a289e), false); // {EVEX}sub rbx, r13, qword ptr [r22-0x702a289e] IID831 - __ esubq(r23, r29, Address(r25, rdx, (Address::ScaleFactor)0, -0x6252a7ed), true); // {NF}sub r23, r29, qword ptr [r25+rdx*1-0x6252a7ed] IID832 - __ exorq(r8, r18, Address(r19, r14, (Address::ScaleFactor)2, -0xebfa697), false); // {EVEX}xor r8, r18, qword ptr [r19+r14*4-0xebfa697] IID833 - __ exorq(r10, r28, Address(r26, +0x168381ca), true); // {NF}xor r10, r28, qword ptr [r26+0x168381ca] IID834 - __ eaddq(rcx, r18, r8, false); // {load}{EVEX}add rcx, r18, r8 IID835 - __ eaddq(rcx, rcx, r14, false); // {load}add rcx, r14 IID836 - __ eaddq(r23, r10, r16, true); // {load}{NF}add r23, r10, r16 IID837 - __ eaddq(r11, r11, r24, true); // {load}{NF}add r11, r11, r24 IID838 - __ eadcxq(r9, r18, rdx); // {load}{EVEX}adcx r9, r18, rdx IID839 - __ eadcxq(r8, r8, r15); // {load}adcx r8, r15 IID840 - __ eadoxq(r15, r22, r26); // {load}{EVEX}adox r15, r22, r26 IID841 - __ eadoxq(r11, r11, rdx); // {load}adox r11, rdx IID842 - __ eandq(r19, rdx, r22, false); // {load}{EVEX}and r19, rdx, r22 IID843 - __ eandq(r29, r29, r17, false); // {load}and r29, r17 IID844 - __ eandq(r23, r27, r15, true); // {load}{NF}and r23, r27, r15 IID845 - __ eandq(r9, r9, r13, true); // {load}{NF}and r9, r9, r13 IID846 - __ eimulq(r18, r15, r16, false); // {load}{EVEX}imul r18, r15, r16 IID847 - __ eimulq(rcx, rcx, r17, false); // {load}imul rcx, r17 IID848 - __ eimulq(r23, r12, r20, true); // {load}{NF}imul r23, r12, r20 IID849 - __ eimulq(r10, r10, r9, true); // {load}{NF}imul r10, r10, r9 IID850 - __ eorq(rdx, r19, r14, false); // {load}{EVEX}or rdx, r19, r14 IID851 - __ eorq(rcx, rcx, r13, false); // {load}or rcx, r13 IID852 - __ eorq(r9, r25, r29, true); // {load}{NF}or r9, r25, r29 IID853 - __ eorq(rdx, rdx, r25, true); // {load}{NF}or rdx, rdx, r25 IID854 - __ esubq(r23, r8, r16, false); // {load}{EVEX}sub r23, r8, r16 IID855 - __ esubq(r13, r13, r13, false); // {load}sub r13, r13 IID856 - __ esubq(r19, r12, r15, true); // {load}{NF}sub r19, r12, r15 IID857 - __ esubq(r9, r9, rdx, true); // {load}{NF}sub r9, r9, rdx IID858 - __ exorq(r13, r16, r31, false); // {load}{EVEX}xor r13, r16, r31 IID859 - __ exorq(r17, r17, r30, false); // {load}xor r17, r30 IID860 - __ exorq(r19, r30, r20, true); // {load}{NF}xor r19, r30, r20 IID861 - __ exorq(r31, r31, r13, true); // {load}{NF}xor r31, r31, r13 IID862 - __ eshldq(r22, r10, r13, 4, false); // {EVEX}shld r22, r10, r13, 4 IID863 - __ eshldq(r24, r24, r21, 16, false); // shld r24, r21, 16 IID864 - __ eshldq(r20, r13, r27, 16, true); // {NF}shld r20, r13, r27, 16 IID865 - __ eshldq(r31, r31, r19, 2, true); // {NF}shld r31, r31, r19, 2 IID866 - __ eshrdq(r30, r20, r11, 8, false); // {EVEX}shrd r30, r20, r11, 8 IID867 - __ eshrdq(rdx, rdx, r15, 1, false); // shrd rdx, r15, 1 IID868 - __ eshrdq(r28, r30, r14, 2, true); // {NF}shrd r28, r30, r14, 2 IID869 - __ eshrdq(r20, r20, r16, 1, true); // {NF}shrd r20, r20, r16, 1 IID870 - __ ecmovq (Assembler::Condition::overflow, r21, r17, r28); // cmovo r21, r17, r28 IID871 - __ ecmovq (Assembler::Condition::overflow, r15, r15, r30); // cmovo r15, r30 IID872 - __ ecmovq (Assembler::Condition::noOverflow, rcx, r15, r15); // cmovno rcx, r15, r15 IID873 - __ ecmovq (Assembler::Condition::noOverflow, rcx, rcx, r13); // cmovno rcx, r13 IID874 - __ ecmovq (Assembler::Condition::below, rdx, r26, r26); // cmovb rdx, r26, r26 IID875 - __ ecmovq (Assembler::Condition::below, r28, r28, r15); // cmovb r28, r15 IID876 - __ ecmovq (Assembler::Condition::aboveEqual, r8, rdx, rcx); // cmovae r8, rdx, rcx IID877 - __ ecmovq (Assembler::Condition::aboveEqual, rcx, rcx, rcx); // cmovae rcx, rcx IID878 - __ ecmovq (Assembler::Condition::zero, r10, r13, r9); // cmovz r10, r13, r9 IID879 - __ ecmovq (Assembler::Condition::zero, r14, r14, r27); // cmovz r14, r27 IID880 - __ ecmovq (Assembler::Condition::notZero, r11, r23, r9); // cmovnz r11, r23, r9 IID881 - __ ecmovq (Assembler::Condition::notZero, r11, r11, rdx); // cmovnz r11, rdx IID882 - __ ecmovq (Assembler::Condition::belowEqual, r31, r14, r25); // cmovbe r31, r14, r25 IID883 - __ ecmovq (Assembler::Condition::belowEqual, r20, r20, r12); // cmovbe r20, r12 IID884 - __ ecmovq (Assembler::Condition::above, rdx, r10, r28); // cmova rdx, r10, r28 IID885 - __ ecmovq (Assembler::Condition::above, r8, r8, r17); // cmova r8, r17 IID886 - __ ecmovq (Assembler::Condition::negative, rcx, r30, r23); // cmovs rcx, r30, r23 IID887 - __ ecmovq (Assembler::Condition::negative, r26, r26, r18); // cmovs r26, r18 IID888 - __ ecmovq (Assembler::Condition::positive, rdx, rbx, r18); // cmovns rdx, rbx, r18 IID889 - __ ecmovq (Assembler::Condition::positive, r21, r21, r13); // cmovns r21, r13 IID890 - __ ecmovq (Assembler::Condition::parity, r27, r28, r27); // cmovp r27, r28, r27 IID891 - __ ecmovq (Assembler::Condition::parity, r11, r11, r30); // cmovp r11, r30 IID892 - __ ecmovq (Assembler::Condition::noParity, rcx, r21, r18); // cmovnp rcx, r21, r18 IID893 - __ ecmovq (Assembler::Condition::noParity, rcx, rcx, r29); // cmovnp rcx, r29 IID894 - __ ecmovq (Assembler::Condition::less, rdx, r21, r12); // cmovl rdx, r21, r12 IID895 - __ ecmovq (Assembler::Condition::less, rdx, rdx, r26); // cmovl rdx, r26 IID896 - __ ecmovq (Assembler::Condition::greaterEqual, r17, rbx, r22); // cmovge r17, rbx, r22 IID897 - __ ecmovq (Assembler::Condition::greaterEqual, rdx, rdx, r11); // cmovge rdx, r11 IID898 - __ ecmovq (Assembler::Condition::lessEqual, rdx, r14, r8); // cmovle rdx, r14, r8 IID899 - __ ecmovq (Assembler::Condition::lessEqual, r14, r14, r8); // cmovle r14, r8 IID900 - __ ecmovq (Assembler::Condition::greater, r25, r29, r21); // cmovg r25, r29, r21 IID901 - __ ecmovq (Assembler::Condition::greater, r26, r26, r30); // cmovg r26, r30 IID902 - __ ecmovq (Assembler::Condition::overflow, r24, r21, Address(r13, r11, (Address::ScaleFactor)1, +0x439c521e)); // cmovo r24, r21, qword ptr [r13+r11*2+0x439c521e] IID903 - __ ecmovq (Assembler::Condition::noOverflow, r11, r18, Address(r29, r16, (Address::ScaleFactor)0, +0x632127f)); // cmovno r11, r18, qword ptr [r29+r16*1+0x632127f] IID904 - __ ecmovq (Assembler::Condition::below, r16, r8, Address(r8, r26, (Address::ScaleFactor)1, +0x10633def)); // cmovb r16, r8, qword ptr [r8+r26*2+0x10633def] IID905 - __ ecmovq (Assembler::Condition::aboveEqual, r13, r14, Address(r18, -0x54f69e38)); // cmovae r13, r14, qword ptr [r18-0x54f69e38] IID906 - __ ecmovq (Assembler::Condition::zero, r12, r8, Address(r31, r26, (Address::ScaleFactor)1, -0x7a1e447a)); // cmovz r12, r8, qword ptr [r31+r26*2-0x7a1e447a] IID907 - __ ecmovq (Assembler::Condition::notZero, r29, r29, Address(r19, r11, (Address::ScaleFactor)2, -0x35d82dd2)); // cmovnz r29, qword ptr [r19+r11*4-0x35d82dd2] IID908 - __ ecmovq (Assembler::Condition::belowEqual, rcx, r18, Address(r25, r28, (Address::ScaleFactor)0, +0x30be64a0)); // cmovbe rcx, r18, qword ptr [r25+r28*1+0x30be64a0] IID909 - __ ecmovq (Assembler::Condition::above, r28, r12, Address(r10, r16, (Address::ScaleFactor)1, -0x22b8fefa)); // cmova r28, r12, qword ptr [r10+r16*2-0x22b8fefa] IID910 - __ ecmovq (Assembler::Condition::negative, r11, r8, Address(rbx, r11, (Address::ScaleFactor)3, +0x25cc9e96)); // cmovs r11, r8, qword ptr [rbx+r11*8+0x25cc9e96] IID911 - __ ecmovq (Assembler::Condition::positive, r12, r27, Address(r11, -0xc2d70fe)); // cmovns r12, r27, qword ptr [r11-0xc2d70fe] IID912 - __ ecmovq (Assembler::Condition::parity, r8, r26, Address(r19, rbx, (Address::ScaleFactor)1, -0x486db7ea)); // cmovp r8, r26, qword ptr [r19+rbx*2-0x486db7ea] IID913 - __ ecmovq (Assembler::Condition::noParity, r30, r10, Address(r14, r18, (Address::ScaleFactor)3, +0x14884884)); // cmovnp r30, r10, qword ptr [r14+r18*8+0x14884884] IID914 - __ ecmovq (Assembler::Condition::less, r27, r8, Address(r29, r14, (Address::ScaleFactor)2, +0x92b7a8)); // cmovl r27, r8, qword ptr [r29+r14*4+0x92b7a8] IID915 - __ ecmovq (Assembler::Condition::greaterEqual, r14, r28, Address(r19, rdx, (Address::ScaleFactor)0, +0x9c2d45)); // cmovge r14, r28, qword ptr [r19+rdx*1+0x9c2d45] IID916 - __ ecmovq (Assembler::Condition::lessEqual, r25, r8, Address(rcx, r18, (Address::ScaleFactor)2, +0x6655c86b)); // cmovle r25, r8, qword ptr [rcx+r18*4+0x6655c86b] IID917 - __ ecmovq (Assembler::Condition::greater, r19, r21, Address(r10, r25, (Address::ScaleFactor)0, -0x1005430b)); // cmovg r19, r21, qword ptr [r10+r25*1-0x1005430b] IID918 + __ adcq(r30, r31); // {load}adc r30, r31 IID528 + __ cmpq(r12, rdx); // {load}cmp r12, rdx IID529 + __ imulq(r21, r24); // {load}imul r21, r24 IID530 + __ popcntq(r9, r25); // {load}popcnt r9, r25 IID531 + __ sbbq(r8, r12); // {load}sbb r8, r12 IID532 + __ subq(r31, r24); // {load}sub r31, r24 IID533 + __ tzcntq(r10, r16); // {load}tzcnt r10, r16 IID534 + __ lzcntq(r20, r21); // {load}lzcnt r20, r21 IID535 + __ addq(rdx, r17); // {load}add rdx, r17 IID536 + __ andq(r14, r13); // {load}and r14, r13 IID537 + __ orq(r20, r24); // {load}or r20, r24 IID538 + __ xorq(r21, r22); // {load}xor r21, r22 IID539 + __ movq(r12, r27); // {load}mov r12, r27 IID540 + __ bsfq(r23, rdx); // {load}bsf r23, rdx IID541 + __ bsrq(r31, r28); // {load}bsr r31, r28 IID542 + __ btq(r8, r25); // {load}bt r8, r25 IID543 + __ xchgq(r21, rbx); // {load}xchg r21, rbx IID544 + __ testq(r23, r23); // {load}test r23, r23 IID545 + __ addq(Address(r19, -0x180d3ea1), r10); // add qword ptr [r19-0x180d3ea1], r10 IID546 + __ andq(Address(r11, r17, (Address::ScaleFactor)1, -0x78976be8), r25); // and qword ptr [r11+r17*2-0x78976be8], r25 IID547 + __ cmpq(Address(rbx, r28, (Address::ScaleFactor)3, +0x35f72102), r13); // cmp qword ptr [rbx+r28*8+0x35f72102], r13 IID548 + __ orq(Address(r8, -0x34465011), r21); // or qword ptr [r8-0x34465011], r21 IID549 + __ xorq(Address(r19, -0x404b22dd), r18); // xor qword ptr [r19-0x404b22dd], r18 IID550 + __ subq(Address(r23, r27, (Address::ScaleFactor)3, -0x428d2646), r14); // sub qword ptr [r23+r27*8-0x428d2646], r14 IID551 + __ movq(Address(r9, rcx, (Address::ScaleFactor)2, -0x72611661), r28); // mov qword ptr [r9+rcx*4-0x72611661], r28 IID552 + __ xaddq(Address(r24, r21, (Address::ScaleFactor)2, +0x3a6be990), rbx); // xadd qword ptr [r24+r21*4+0x3a6be990], rbx IID553 + __ andq(Address(r22, r10, (Address::ScaleFactor)0, +0x7ef8bdd), 1048576); // and qword ptr [r22+r10*1+0x7ef8bdd], 1048576 IID554 + __ addq(Address(r13, r28, (Address::ScaleFactor)0, -0x754789b1), 65536); // add qword ptr [r13+r28*1-0x754789b1], 65536 IID555 + __ cmpq(Address(r10, -0xbd2a8da), 268435456); // cmp qword ptr [r10-0xbd2a8da], 268435456 IID556 + __ sarq(Address(r23, r14, (Address::ScaleFactor)1, +0x6a16d9f5), 4); // sar qword ptr [r23+r14*2+0x6a16d9f5], 4 IID557 + __ salq(Address(rcx, r21, (Address::ScaleFactor)1, +0x5f66ac1e), 8); // sal qword ptr [rcx+r21*2+0x5f66ac1e], 8 IID558 + __ sbbq(Address(rcx, r22, (Address::ScaleFactor)3, -0x48c954c), 268435456); // sbb qword ptr [rcx+r22*8-0x48c954c], 268435456 IID559 + __ shrq(Address(r21, r30, (Address::ScaleFactor)0, +0xe405b0b), 8); // shr qword ptr [r21+r30*1+0xe405b0b], 8 IID560 + __ subq(Address(r19, r29, (Address::ScaleFactor)3, -0x7762044b), 4096); // sub qword ptr [r19+r29*8-0x7762044b], 4096 IID561 + __ xorq(Address(r30, r10, (Address::ScaleFactor)1, -0x19798323), 16); // xor qword ptr [r30+r10*2-0x19798323], 16 IID562 + __ orq(Address(rdx, r24, (Address::ScaleFactor)3, +0x18d9b316), 4096); // or qword ptr [rdx+r24*8+0x18d9b316], 4096 IID563 + __ movq(Address(rbx, -0x3058074d), 256); // mov qword ptr [rbx-0x3058074d], 256 IID564 + __ testq(Address(r28, r21, (Address::ScaleFactor)3, +0x65a0fdc4), -268435456); // test qword ptr [r28+r21*8+0x65a0fdc4], -268435456 IID565 + __ addq(r23, Address(r11, r18, (Address::ScaleFactor)0, -0x1d1af10c)); // add r23, qword ptr [r11+r18*1-0x1d1af10c] IID566 + __ andq(r22, Address(r18, r12, (Address::ScaleFactor)1, +0x1a5f1c38)); // and r22, qword ptr [r18+r12*2+0x1a5f1c38] IID567 + __ cmpq(r23, Address(r30, r19, (Address::ScaleFactor)0, -0x3e912f7f)); // cmp r23, qword ptr [r30+r19*1-0x3e912f7f] IID568 + __ lzcntq(r29, Address(rcx, +0x12e3fbe4)); // lzcnt r29, qword ptr [rcx+0x12e3fbe4] IID569 + __ orq(r14, Address(r21, r21, (Address::ScaleFactor)2, +0xd73042)); // or r14, qword ptr [r21+r21*4+0xd73042] IID570 + __ adcq(r31, Address(r17, r31, (Address::ScaleFactor)2, +0xabde912)); // adc r31, qword ptr [r17+r31*4+0xabde912] IID571 + __ imulq(r20, Address(r13, r27, (Address::ScaleFactor)0, -0x58dbfc1f)); // imul r20, qword ptr [r13+r27*1-0x58dbfc1f] IID572 + __ popcntq(rbx, Address(r22, -0x72c66c23)); // popcnt rbx, qword ptr [r22-0x72c66c23] IID573 + __ sbbq(r26, Address(r9, +0x334aba09)); // sbb r26, qword ptr [r9+0x334aba09] IID574 + __ subq(r9, Address(r9, r30, (Address::ScaleFactor)3, -0x219a6102)); // sub r9, qword ptr [r9+r30*8-0x219a6102] IID575 + __ tzcntq(r25, Address(r20, -0x2131bab1)); // tzcnt r25, qword ptr [r20-0x2131bab1] IID576 + __ xorq(r16, Address(r28, r16, (Address::ScaleFactor)1, +0x48c483b9)); // xor r16, qword ptr [r28+r16*2+0x48c483b9] IID577 + __ movq(r30, Address(r9, r16, (Address::ScaleFactor)0, -0x88ce84f)); // mov r30, qword ptr [r9+r16*1-0x88ce84f] IID578 + __ leaq(r11, Address(r30, r29, (Address::ScaleFactor)2, +0x3eeb8fd0)); // lea r11, qword ptr [r30+r29*4+0x3eeb8fd0] IID579 + __ cvttsd2siq(r26, Address(r29, r10, (Address::ScaleFactor)3, +0x3ef4822e)); // cvttsd2si r26, qword ptr [r29+r10*8+0x3ef4822e] IID580 + __ xchgq(r29, Address(r19, r20, (Address::ScaleFactor)2, -0x3f0f3db9)); // xchg r29, qword ptr [r19+r20*4-0x3f0f3db9] IID581 + __ testq(r8, Address(r30, r20, (Address::ScaleFactor)0, +0x15b56a17)); // test r8, qword ptr [r30+r20*1+0x15b56a17] IID582 + __ addq(r26, 4096); // add r26, 4096 IID583 + __ andq(r20, 16); // and r20, 16 IID584 + __ adcq(r23, 1048576); // adc r23, 1048576 IID585 + __ cmpq(r12, 4096); // cmp r12, 4096 IID586 + __ rclq(rcx, 4); // rcl rcx, 4 IID587 + __ rcrq(r14, 1); // rcr r14, 1 IID588 + __ rolq(r23, 2); // rol r23, 2 IID589 + __ rorq(r12, 4); // ror r12, 4 IID590 + __ sarq(r10, 4); // sar r10, 4 IID591 + __ salq(r20, 4); // sal r20, 4 IID592 + __ sbbq(rcx, 1048576); // sbb rcx, 1048576 IID593 + __ shlq(r23, 16); // shl r23, 16 IID594 + __ shrq(r27, 2); // shr r27, 2 IID595 + __ subq(rcx, 65536); // sub rcx, 65536 IID596 + __ xorq(r9, 1048576); // xor r9, 1048576 IID597 + __ movq(r16, 65536); // mov r16, 65536 IID598 + __ mov64(r24, 4503599627370496); // mov r24, 4503599627370496 IID599 + __ btq(r18, 64); // bt r18, 64 IID600 + __ testq(r29, -4096); // test r29, -4096 IID601 + __ orq_imm32(r30, 67108864); // or r30, 67108864 IID602 + __ subq_imm32(r25, 268435456); // sub r25, 268435456 IID603 + __ cmovq(Assembler::Condition::overflow, r30, Address(r17, r31, (Address::ScaleFactor)2, +0x47ff92f0)); // cmovo r30, qword ptr [r17+r31*4+0x47ff92f0] IID604 + __ cmovq(Assembler::Condition::noOverflow, r9, Address(r24, r28, (Address::ScaleFactor)1, +0x384904c0)); // cmovno r9, qword ptr [r24+r28*2+0x384904c0] IID605 + __ cmovq(Assembler::Condition::below, r23, Address(r23, r24, (Address::ScaleFactor)3, -0x197f1266)); // cmovb r23, qword ptr [r23+r24*8-0x197f1266] IID606 + __ cmovq(Assembler::Condition::aboveEqual, r9, Address(r29, r30, (Address::ScaleFactor)0, +0x2b5d49c8)); // cmovae r9, qword ptr [r29+r30*1+0x2b5d49c8] IID607 + __ cmovq(Assembler::Condition::zero, r16, Address(rbx, r15, (Address::ScaleFactor)1, +0x22379381)); // cmovz r16, qword ptr [rbx+r15*2+0x22379381] IID608 + __ cmovq(Assembler::Condition::notZero, r8, Address(r11, +0x49d67a0)); // cmovnz r8, qword ptr [r11+0x49d67a0] IID609 + __ cmovq(Assembler::Condition::belowEqual, r28, Address(r16, r16, (Address::ScaleFactor)2, -0x5e941da9)); // cmovbe r28, qword ptr [r16+r16*4-0x5e941da9] IID610 + __ cmovq(Assembler::Condition::above, r19, Address(r18, r8, (Address::ScaleFactor)0, -0xa5e55ec)); // cmova r19, qword ptr [r18+r8*1-0xa5e55ec] IID611 + __ cmovq(Assembler::Condition::negative, r28, Address(r17, r28, (Address::ScaleFactor)1, -0x3264220c)); // cmovs r28, qword ptr [r17+r28*2-0x3264220c] IID612 + __ cmovq(Assembler::Condition::positive, r31, Address(r14, r31, (Address::ScaleFactor)1, +0x5001bc5a)); // cmovns r31, qword ptr [r14+r31*2+0x5001bc5a] IID613 + __ cmovq(Assembler::Condition::parity, rbx, Address(r18, r17, (Address::ScaleFactor)2, -0x286f2379)); // cmovp rbx, qword ptr [r18+r17*4-0x286f2379] IID614 + __ cmovq(Assembler::Condition::noParity, r17, Address(r20, -0x5549f838)); // cmovnp r17, qword ptr [r20-0x5549f838] IID615 + __ cmovq(Assembler::Condition::less, r30, Address(r9, r28, (Address::ScaleFactor)1, -0x25b00cf3)); // cmovl r30, qword ptr [r9+r28*2-0x25b00cf3] IID616 + __ cmovq(Assembler::Condition::greaterEqual, r19, Address(r9, -0x2aabf22c)); // cmovge r19, qword ptr [r9-0x2aabf22c] IID617 + __ cmovq(Assembler::Condition::lessEqual, rbx, Address(rcx, r12, (Address::ScaleFactor)1, -0x432d68cc)); // cmovle rbx, qword ptr [rcx+r12*2-0x432d68cc] IID618 + __ cmovq(Assembler::Condition::greater, rbx, Address(r15, r17, (Address::ScaleFactor)3, -0x2b97565e)); // cmovg rbx, qword ptr [r15+r17*8-0x2b97565e] IID619 + __ call(r24); // call r24 IID620 + __ divq(r9); // div r9 IID621 + __ idivq(r28); // idiv r28 IID622 + __ imulq(rdx); // imul rdx IID623 + __ mulq(r31); // mul r31 IID624 + __ negq(r12); // neg r12 IID625 + __ notq(r12); // not r12 IID626 + __ rolq(r24); // rol r24, cl IID627 + __ rorq(r28); // ror r28, cl IID628 + __ sarq(r11); // sar r11, cl IID629 + __ salq(r27); // sal r27, cl IID630 + __ shlq(r23); // shl r23, cl IID631 + __ shrq(r17); // shr r17, cl IID632 + __ incrementq(r16); // inc r16 IID633 + __ decrementq(r12); // dec r12 IID634 + __ pushp(r23); // pushp r23 IID635 + __ popp(r24); // popp r24 IID636 + __ call(Address(r18, r14, (Address::ScaleFactor)0, -0x66639d32)); // call qword ptr [r18+r14*1-0x66639d32] IID637 + __ mulq(Address(r24, -0x660a2421)); // mul qword ptr [r24-0x660a2421] IID638 + __ negq(Address(r14, r18, (Address::ScaleFactor)0, +0x40f3936e)); // neg qword ptr [r14+r18*1+0x40f3936e] IID639 + __ sarq(Address(r10, r13, (Address::ScaleFactor)0, +0x7d04cb72)); // sar qword ptr [r10+r13*1+0x7d04cb72], cl IID640 + __ salq(Address(r18, r11, (Address::ScaleFactor)3, -0x2176b4dc)); // sal qword ptr [r18+r11*8-0x2176b4dc], cl IID641 + __ shrq(Address(r13, rcx, (Address::ScaleFactor)1, +0x7996aa80)); // shr qword ptr [r13+rcx*2+0x7996aa80], cl IID642 + __ incrementq(Address(r14, +0x67c2d02a)); // inc qword ptr [r14+0x67c2d02a] IID643 + __ decrementq(Address(r22, r26, (Address::ScaleFactor)0, +0x224f62c0)); // dec qword ptr [r22+r26*1+0x224f62c0] IID644 + __ imulq(rdx, Address(r31, rbx, (Address::ScaleFactor)1, +0x2b00bb10), 16777216); // imul rdx, qword ptr [r31+rbx*2+0x2b00bb10], 16777216 IID645 + __ imulq(r21, r31, 4096); // imul r21, r31, 4096 IID646 + __ shldq(rbx, r19, 1); // shld rbx, r19, 1 IID647 + __ shrdq(r11, r23, 4); // shrd r11, r23, 4 IID648 + __ pop2(r16, r30); // {load}pop2 r30, r16 IID649 + __ pop2p(r17, rbx); // {load}pop2p rbx, r17 IID650 + __ push2(r20, r30); // {load}push2 r30, r20 IID651 + __ push2p(r8, r31); // {load}push2p r31, r8 IID652 + __ movzbq(r28, Address(r8, r14, (Address::ScaleFactor)0, +0x469ae67a)); // movzx r28, byte ptr [r8+r14*1+0x469ae67a] IID653 + __ movzwq(r14, Address(r8, r18, (Address::ScaleFactor)2, -0x48699e02)); // movzx r14, word ptr [r8+r18*4-0x48699e02] IID654 + __ movsbq(r21, Address(rbx, -0x64dae06b)); // movsx r21, byte ptr [rbx-0x64dae06b] IID655 + __ movswq(r19, Address(r31, rbx, (Address::ScaleFactor)2, +0x60318819)); // movsx r19, word ptr [r31+rbx*4+0x60318819] IID656 + __ movzbq(r30, r13); // movzx r30, r13b IID657 + __ movzwq(r30, r18); // movzx r30, r18w IID658 + __ movsbq(r19, r15); // movsx r19, r15b IID659 + __ movswq(r20, r16); // movsx r20, r16w IID660 + __ cmpxchgq(r28, Address(r11, rbx, (Address::ScaleFactor)3, +0xfc3479d)); // cmpxchg qword ptr [r11+rbx*8+0xfc3479d], r28 IID661 + __ eidivq(r20, false); // {EVEX}idiv r20 IID662 + __ eidivq(r30, true); // {NF}idiv r30 IID663 + __ edivq(r22, false); // {EVEX}div r22 IID664 + __ edivq(r11, true); // {NF}div r11 IID665 + __ eimulq(rcx, false); // {EVEX}imul rcx IID666 + __ eimulq(r28, true); // {NF}imul r28 IID667 + __ emulq(r21, false); // {EVEX}mul r21 IID668 + __ emulq(r13, true); // {NF}mul r13 IID669 + __ emulq(Address(r26, r15, (Address::ScaleFactor)2, +0x70a1ce6e), false); // {EVEX}mul qword ptr [r26+r15*4+0x70a1ce6e] IID670 + __ emulq(Address(r24, r19, (Address::ScaleFactor)1, -0x1670855c), true); // {NF}mul qword ptr [r24+r19*2-0x1670855c] IID671 + __ eimulq(r10, r27, false); // {EVEX}imul r10, r27 IID672 + __ eimulq(r17, r17, false); // imul r17 IID673 + __ eimulq(rdx, r22, true); // {NF}imul rdx, r22 IID674 + __ eimulq(rbx, rbx, true); // {NF}imul rbx, rbx IID675 + __ elzcntq(r28, r15, false); // {EVEX}lzcnt r28, r15 IID676 + __ elzcntq(r15, r15, false); // {EVEX}lzcnt r15, r15 IID677 + __ elzcntq(rbx, r12, true); // {NF}lzcnt rbx, r12 IID678 + __ elzcntq(rbx, rbx, true); // {NF}lzcnt rbx, rbx IID679 + __ enegq(r26, r11, false); // {EVEX}neg r26, r11 IID680 + __ enegq(r17, r17, false); // neg r17 IID681 + __ enegq(rdx, r31, true); // {NF}neg rdx, r31 IID682 + __ enegq(r27, r27, true); // {NF}neg r27, r27 IID683 + __ enotq(r31, r15); // {EVEX}not r31, r15 IID684 + __ enotq(r21, r21); // not r21 IID685 + __ epopcntq(rbx, r24, false); // {EVEX}popcnt rbx, r24 IID686 + __ epopcntq(r28, r28, false); // {EVEX}popcnt r28, r28 IID687 + __ epopcntq(r23, r27, true); // {NF}popcnt r23, r27 IID688 + __ epopcntq(r13, r13, true); // {NF}popcnt r13, r13 IID689 + __ erolq(r25, r28, false); // {EVEX}rol r25, r28, cl IID690 + __ erolq(r31, r31, false); // rol r31, cl IID691 + __ erolq(r25, r23, true); // {NF}rol r25, r23, cl IID692 + __ erolq(rcx, rcx, true); // {NF}rol rcx, rcx, cl IID693 + __ erorq(r22, r14, false); // {EVEX}ror r22, r14, cl IID694 + __ erorq(r15, r15, false); // ror r15, cl IID695 + __ erorq(r11, r30, true); // {NF}ror r11, r30, cl IID696 + __ erorq(r24, r24, true); // {NF}ror r24, r24, cl IID697 + __ esalq(r10, r20, false); // {EVEX}sal r10, r20, cl IID698 + __ esalq(r19, r19, false); // sal r19, cl IID699 + __ esalq(r17, r25, true); // {NF}sal r17, r25, cl IID700 + __ esalq(r13, r13, true); // {NF}sal r13, r13, cl IID701 + __ esarq(r31, r30, false); // {EVEX}sar r31, r30, cl IID702 + __ esarq(r18, r18, false); // sar r18, cl IID703 + __ esarq(r25, r25, true); // {NF}sar r25, r25, cl IID704 + __ esarq(r28, r28, true); // {NF}sar r28, r28, cl IID705 + __ edecq(r22, r27, false); // {EVEX}dec r22, r27 IID706 + __ edecq(r12, r12, false); // dec r12 IID707 + __ edecq(r18, r11, true); // {NF}dec r18, r11 IID708 + __ edecq(r10, r10, true); // {NF}dec r10, r10 IID709 + __ eincq(r20, r24, false); // {EVEX}inc r20, r24 IID710 + __ eincq(r18, r18, false); // inc r18 IID711 + __ eincq(rbx, r11, true); // {NF}inc rbx, r11 IID712 + __ eincq(r26, r26, true); // {NF}inc r26, r26 IID713 + __ eshlq(r21, r8, false); // {EVEX}shl r21, r8, cl IID714 + __ eshlq(rbx, rbx, false); // shl rbx, cl IID715 + __ eshlq(r22, r21, true); // {NF}shl r22, r21, cl IID716 + __ eshlq(r27, r27, true); // {NF}shl r27, r27, cl IID717 + __ eshrq(r12, r16, false); // {EVEX}shr r12, r16, cl IID718 + __ eshrq(r8, r8, false); // shr r8, cl IID719 + __ eshrq(rdx, r9, true); // {NF}shr rdx, r9, cl IID720 + __ eshrq(r20, r20, true); // {NF}shr r20, r20, cl IID721 + __ etzcntq(r31, r21, false); // {EVEX}tzcnt r31, r21 IID722 + __ etzcntq(r20, r20, false); // {EVEX}tzcnt r20, r20 IID723 + __ etzcntq(rcx, r16, true); // {NF}tzcnt rcx, r16 IID724 + __ etzcntq(r14, r14, true); // {NF}tzcnt r14, r14 IID725 + __ eimulq(r27, Address(r25, r9, (Address::ScaleFactor)1, +0x445a2393), false); // {EVEX}imul r27, qword ptr [r25+r9*2+0x445a2393] IID726 + __ eimulq(r23, Address(rcx, r9, (Address::ScaleFactor)1, -0x1480ef0c), true); // {NF}imul r23, qword ptr [rcx+r9*2-0x1480ef0c] IID727 + __ elzcntq(r13, Address(r22, r17, (Address::ScaleFactor)1, -0x750c1996), false); // {EVEX}lzcnt r13, qword ptr [r22+r17*2-0x750c1996] IID728 + __ elzcntq(r13, Address(r31, -0x342b6259), true); // {NF}lzcnt r13, qword ptr [r31-0x342b6259] IID729 + __ enegq(r31, Address(r24, r13, (Address::ScaleFactor)1, -0x25b16a0e), false); // {EVEX}neg r31, qword ptr [r24+r13*2-0x25b16a0e] IID730 + __ enegq(r13, Address(r11, r28, (Address::ScaleFactor)3, +0x5c0013ab), true); // {NF}neg r13, qword ptr [r11+r28*8+0x5c0013ab] IID731 + __ epopcntq(rdx, Address(r18, rcx, (Address::ScaleFactor)2, -0x6113eaaf), false); // {EVEX}popcnt rdx, qword ptr [r18+rcx*4-0x6113eaaf] IID732 + __ epopcntq(r9, Address(r10, -0x5ca7d588), true); // {NF}popcnt r9, qword ptr [r10-0x5ca7d588] IID733 + __ esalq(r17, Address(r27, r30, (Address::ScaleFactor)0, +0x1b4cda2c), false); // {EVEX}sal r17, qword ptr [r27+r30*1+0x1b4cda2c], cl IID734 + __ esalq(r25, Address(r12, rdx, (Address::ScaleFactor)1, +0x62823bce), true); // {NF}sal r25, qword ptr [r12+rdx*2+0x62823bce], cl IID735 + __ esarq(r9, Address(r10, r18, (Address::ScaleFactor)2, -0x264a7a48), false); // {EVEX}sar r9, qword ptr [r10+r18*4-0x264a7a48], cl IID736 + __ esarq(rbx, Address(r14, r27, (Address::ScaleFactor)0, +0x20291e00), true); // {NF}sar rbx, qword ptr [r14+r27*1+0x20291e00], cl IID737 + __ edecq(r12, Address(r15, r14, (Address::ScaleFactor)2, -0x20f7dabb), false); // {EVEX}dec r12, qword ptr [r15+r14*4-0x20f7dabb] IID738 + __ edecq(r9, Address(r10, r25, (Address::ScaleFactor)1, +0x21411d84), true); // {NF}dec r9, qword ptr [r10+r25*2+0x21411d84] IID739 + __ eincq(r20, Address(rbx, r25, (Address::ScaleFactor)3, +0x2f0329e), false); // {EVEX}inc r20, qword ptr [rbx+r25*8+0x2f0329e] IID740 + __ eincq(r10, Address(r12, r31, (Address::ScaleFactor)0, -0x37505c8c), true); // {NF}inc r10, qword ptr [r12+r31*1-0x37505c8c] IID741 + __ eshrq(r24, Address(r23, r14, (Address::ScaleFactor)3, -0x71e75ab0), false); // {EVEX}shr r24, qword ptr [r23+r14*8-0x71e75ab0], cl IID742 + __ eshrq(r25, Address(r19, r10, (Address::ScaleFactor)1, +0x507b0a88), true); // {NF}shr r25, qword ptr [r19+r10*2+0x507b0a88], cl IID743 + __ etzcntq(r31, Address(rbx, r16, (Address::ScaleFactor)0, +0x19d5192a), false); // {EVEX}tzcnt r31, qword ptr [rbx+r16*1+0x19d5192a] IID744 + __ etzcntq(r9, Address(r22, r28, (Address::ScaleFactor)2, +0x211007cd), true); // {NF}tzcnt r9, qword ptr [r22+r28*4+0x211007cd] IID745 + __ eaddq(r16, Address(r21, rbx, (Address::ScaleFactor)3, -0x823fa1e), r28, false); // {EVEX}add r16, qword ptr [r21+rbx*8-0x823fa1e], r28 IID746 + __ eaddq(r15, Address(rdx, r8, (Address::ScaleFactor)3, -0x34b9a058), r15, false); // add r15, qword ptr [rdx+r8*8-0x34b9a058] IID747 + __ eaddq(r24, Address(r14, r24, (Address::ScaleFactor)3, +0x6cdc59d2), r13, true); // {NF}add r24, qword ptr [r14+r24*8+0x6cdc59d2], r13 IID748 + __ eaddq(rbx, Address(r27, r14, (Address::ScaleFactor)3, +0x36c5e8de), rbx, true); // {NF}add rbx, qword ptr [r27+r14*8+0x36c5e8de], rbx IID749 + __ eandq(r21, Address(r27, r27, (Address::ScaleFactor)1, -0x2c023b13), r27, false); // {EVEX}and r21, qword ptr [r27+r27*2-0x2c023b13], r27 IID750 + __ eandq(r31, Address(r21, r15, (Address::ScaleFactor)2, +0x6ef2c74a), r31, false); // and r31, qword ptr [r21+r15*4+0x6ef2c74a] IID751 + __ eandq(r13, Address(r31, r25, (Address::ScaleFactor)1, +0x734fe9ab), r27, true); // {NF}and r13, qword ptr [r31+r25*2+0x734fe9ab], r27 IID752 + __ eandq(r15, Address(r14, r29, (Address::ScaleFactor)3, -0x6e68556), r15, true); // {NF}and r15, qword ptr [r14+r29*8-0x6e68556], r15 IID753 + __ eorq(r12, Address(r30, r15, (Address::ScaleFactor)3, +0x3ba33f9e), r28, false); // {EVEX}or r12, qword ptr [r30+r15*8+0x3ba33f9e], r28 IID754 + __ eorq(r16, Address(r12, r9, (Address::ScaleFactor)0, -0x28e03b33), r16, false); // or r16, qword ptr [r12+r9*1-0x28e03b33] IID755 + __ eorq(r8, Address(r8, r25, (Address::ScaleFactor)3, -0x1e42bd95), r27, true); // {NF}or r8, qword ptr [r8+r25*8-0x1e42bd95], r27 IID756 + __ eorq(rcx, Address(r27, rbx, (Address::ScaleFactor)2, +0x7be4bcad), rcx, true); // {NF}or rcx, qword ptr [r27+rbx*4+0x7be4bcad], rcx IID757 + __ esubq(r24, Address(r23, r22, (Address::ScaleFactor)2, +0x6f8827d7), rdx, false); // {EVEX}sub r24, qword ptr [r23+r22*4+0x6f8827d7], rdx IID758 + __ esubq(r21, Address(r10, -0x635b8c8), r21, false); // {EVEX}sub r21, qword ptr [r10-0x635b8c8], r21 IID759 + __ esubq(r23, Address(r27, r26, (Address::ScaleFactor)3, +0x922bcc0), rbx, true); // {NF}sub r23, qword ptr [r27+r26*8+0x922bcc0], rbx IID760 + __ esubq(r25, Address(r23, r15, (Address::ScaleFactor)0, -0x38f494ac), r25, true); // {NF}sub r25, qword ptr [r23+r15*1-0x38f494ac], r25 IID761 + __ exorq(r11, Address(r12, r19, (Address::ScaleFactor)2, -0x5b71ec17), rcx, false); // {EVEX}xor r11, qword ptr [r12+r19*4-0x5b71ec17], rcx IID762 + __ exorq(r28, Address(r19, r18, (Address::ScaleFactor)0, +0x716b9b7e), r28, false); // xor r28, qword ptr [r19+r18*1+0x716b9b7e] IID763 + __ exorq(r21, Address(rcx, r29, (Address::ScaleFactor)0, -0x5af0441e), r16, true); // {NF}xor r21, qword ptr [rcx+r29*1-0x5af0441e], r16 IID764 + __ exorq(r12, Address(r20, r26, (Address::ScaleFactor)0, +0xe0b7fb1), r12, true); // {NF}xor r12, qword ptr [r20+r26*1+0xe0b7fb1], r12 IID765 + __ eaddq(r30, Address(rcx, +0x2d3b7b4f), 1048576, false); // {EVEX}add r30, qword ptr [rcx+0x2d3b7b4f], 1048576 IID766 + __ eaddq(r14, Address(r21, r15, (Address::ScaleFactor)2, -0x1222aee8), 4096, true); // {NF}add r14, qword ptr [r21+r15*4-0x1222aee8], 4096 IID767 + __ eandq(r23, Address(r20, r31, (Address::ScaleFactor)0, -0x96e4d6a), 16, false); // {EVEX}and r23, qword ptr [r20+r31*1-0x96e4d6a], 16 IID768 + __ eandq(r10, Address(rdx, rdx, (Address::ScaleFactor)3, +0x3875f17c), 1, true); // {NF}and r10, qword ptr [rdx+rdx*8+0x3875f17c], 1 IID769 + __ eimulq(r17, Address(rcx, r25, (Address::ScaleFactor)2, +0x32c71076), 4096, false); // {EVEX}imul r17, qword ptr [rcx+r25*4+0x32c71076], 4096 IID770 + __ eimulq(r19, Address(r31, rbx, (Address::ScaleFactor)2, +0x7bada60d), 1048576, true); // {NF}imul r19, qword ptr [r31+rbx*4+0x7bada60d], 1048576 IID771 + __ eorq(r25, Address(r18, r23, (Address::ScaleFactor)1, +0x48147444), 16777216, false); // {EVEX}or r25, qword ptr [r18+r23*2+0x48147444], 16777216 IID772 + __ eorq(r29, Address(r26, r27, (Address::ScaleFactor)1, -0x4b113958), 1048576, true); // {NF}or r29, qword ptr [r26+r27*2-0x4b113958], 1048576 IID773 + __ esalq(r31, Address(r18, -0x46103c74), 2, false); // {EVEX}sal r31, qword ptr [r18-0x46103c74], 2 IID774 + __ esalq(r25, Address(r10, r15, (Address::ScaleFactor)0, +0x48925da4), 16, true); // {NF}sal r25, qword ptr [r10+r15*1+0x48925da4], 16 IID775 + __ esarq(r26, Address(r18, -0x5ea1c542), 8, false); // {EVEX}sar r26, qword ptr [r18-0x5ea1c542], 8 IID776 + __ esarq(r12, Address(r10, r22, (Address::ScaleFactor)2, +0x5d958264), 8, true); // {NF}sar r12, qword ptr [r10+r22*4+0x5d958264], 8 IID777 + __ eshrq(rdx, Address(r17, r20, (Address::ScaleFactor)2, +0x295add23), 16, false); // {EVEX}shr rdx, qword ptr [r17+r20*4+0x295add23], 16 IID778 + __ eshrq(rbx, Address(r22, r28, (Address::ScaleFactor)1, +0x782929cb), 2, true); // {NF}shr rbx, qword ptr [r22+r28*2+0x782929cb], 2 IID779 + __ esubq(r19, Address(r23, -0x49811d72), 1, false); // {EVEX}sub r19, qword ptr [r23-0x49811d72], 1 IID780 + __ esubq(r8, Address(r19, r14, (Address::ScaleFactor)2, -0x1b2bae9a), 1048576, true); // {NF}sub r8, qword ptr [r19+r14*4-0x1b2bae9a], 1048576 IID781 + __ exorq(r19, Address(rcx, r10, (Address::ScaleFactor)0, +0x45a66ee9), 1048576, false); // {EVEX}xor r19, qword ptr [rcx+r10*1+0x45a66ee9], 1048576 IID782 + __ exorq(r28, Address(r9, r29, (Address::ScaleFactor)0, -0x28a19314), 16, true); // {NF}xor r28, qword ptr [r9+r29*1-0x28a19314], 16 IID783 + __ eaddq(r8, rcx, 16777216, false); // {EVEX}add r8, rcx, 16777216 IID784 + __ eaddq(rax, r14, 16777216, false); // {EVEX}add rax, r14, 16777216 IID785 + __ eaddq(r16, r16, 256, false); // add r16, 256 IID786 + __ eaddq(r24, r9, 4096, true); // {NF}add r24, r9, 4096 IID787 + __ eaddq(rax, r18, 4096, true); // {NF}add rax, r18, 4096 IID788 + __ eaddq(r8, r8, 1, true); // {NF}add r8, r8, 1 IID789 + __ eandq(r15, r22, 1048576, false); // {EVEX}and r15, r22, 1048576 IID790 + __ eandq(rax, r26, 1048576, false); // {EVEX}and rax, r26, 1048576 IID791 + __ eandq(rdx, rdx, 4096, false); // and rdx, 4096 IID792 + __ eandq(rdx, r22, 268435456, true); // {NF}and rdx, r22, 268435456 IID793 + __ eandq(rax, r29, 268435456, true); // {NF}and rax, r29, 268435456 IID794 + __ eandq(r23, r23, 16777216, true); // {NF}and r23, r23, 16777216 IID795 + __ eimulq(r9, r13, 1048576, false); // {EVEX}imul r9, r13, 1048576 IID796 + __ eimulq(rax, r18, 1048576, false); // {EVEX}imul rax, r18, 1048576 IID797 + __ eimulq(r16, r16, 1048576, false); // {EVEX}imul r16, r16, 1048576 IID798 + __ eimulq(r17, r23, 1, true); // {NF}imul r17, r23, 1 IID799 + __ eimulq(rax, r12, 1, true); // {NF}imul rax, r12, 1 IID800 + __ eimulq(r10, r10, 268435456, true); // {NF}imul r10, r10, 268435456 IID801 + __ eorq(rdx, r19, 256, false); // {EVEX}or rdx, r19, 256 IID802 + __ eorq(rax, r14, 256, false); // {EVEX}or rax, r14, 256 IID803 + __ eorq(r13, r13, 1, false); // or r13, 1 IID804 + __ eorq(r25, r29, 256, true); // {NF}or r25, r29, 256 IID805 + __ eorq(rax, rdx, 256, true); // {NF}or rax, rdx, 256 IID806 + __ eorq(r16, r16, 16, true); // {NF}or r16, r16, 16 IID807 + __ erclq(r13, r19, 4); // {EVEX}rcl r13, r19, 4 IID808 + __ erclq(rax, r12, 4); // {EVEX}rcl rax, r12, 4 IID809 + __ erclq(r9, r9, 4); // rcl r9, 4 IID810 + __ erolq(r13, r16, 1, false); // {EVEX}rol r13, r16, 1 IID811 + __ erolq(rax, r31, 1, false); // {EVEX}rol rax, r31, 1 IID812 + __ erolq(r30, r30, 8, false); // rol r30, 8 IID813 + __ erolq(r30, r20, 8, true); // {NF}rol r30, r20, 8 IID814 + __ erolq(rax, r31, 8, true); // {NF}rol rax, r31, 8 IID815 + __ erolq(r31, r31, 4, true); // {NF}rol r31, r31, 4 IID816 + __ erorq(r22, r10, 4, false); // {EVEX}ror r22, r10, 4 IID817 + __ erorq(rax, r13, 4, false); // {EVEX}ror rax, r13, 4 IID818 + __ erorq(r24, r24, 16, false); // ror r24, 16 IID819 + __ erorq(r29, r22, 16, true); // {NF}ror r29, r22, 16 IID820 + __ erorq(rax, r20, 16, true); // {NF}ror rax, r20, 16 IID821 + __ erorq(r27, r27, 4, true); // {NF}ror r27, r27, 4 IID822 + __ esalq(r31, r19, 2, false); // {EVEX}sal r31, r19, 2 IID823 + __ esalq(rax, r20, 2, false); // {EVEX}sal rax, r20, 2 IID824 + __ esalq(r11, r11, 8, false); // sal r11, 8 IID825 + __ esalq(rdx, r15, 1, true); // {NF}sal rdx, r15, 1 IID826 + __ esalq(rax, r10, 1, true); // {NF}sal rax, r10, 1 IID827 + __ esalq(r29, r29, 4, true); // {NF}sal r29, r29, 4 IID828 + __ esarq(r20, r16, 1, false); // {EVEX}sar r20, r16, 1 IID829 + __ esarq(rax, r21, 1, false); // {EVEX}sar rax, r21, 1 IID830 + __ esarq(r28, r28, 8, false); // sar r28, 8 IID831 + __ esarq(r30, rcx, 4, true); // {NF}sar r30, rcx, 4 IID832 + __ esarq(rax, r15, 4, true); // {NF}sar rax, r15, 4 IID833 + __ esarq(rcx, rcx, 4, true); // {NF}sar rcx, rcx, 4 IID834 + __ eshlq(rdx, r26, 4, false); // {EVEX}shl rdx, r26, 4 IID835 + __ eshlq(rax, r26, 4, false); // {EVEX}shl rax, r26, 4 IID836 + __ eshlq(r8, r8, 4, false); // shl r8, 4 IID837 + __ eshlq(rcx, rcx, 1, true); // {NF}shl rcx, rcx, 1 IID838 + __ eshlq(rax, rcx, 1, true); // {NF}shl rax, rcx, 1 IID839 + __ eshlq(r13, r13, 2, true); // {NF}shl r13, r13, 2 IID840 + __ eshrq(r14, r27, 2, false); // {EVEX}shr r14, r27, 2 IID841 + __ eshrq(rax, r11, 2, false); // {EVEX}shr rax, r11, 2 IID842 + __ eshrq(r9, r9, 16, false); // shr r9, 16 IID843 + __ eshrq(rdx, r31, 2, true); // {NF}shr rdx, r31, 2 IID844 + __ eshrq(rax, r14, 2, true); // {NF}shr rax, r14, 2 IID845 + __ eshrq(r12, r12, 8, true); // {NF}shr r12, r12, 8 IID846 + __ esubq(r10, r28, 1, false); // {EVEX}sub r10, r28, 1 IID847 + __ esubq(rax, r8, 1, false); // {EVEX}sub rax, r8, 1 IID848 + __ esubq(rcx, rcx, 16777216, false); // sub rcx, 16777216 IID849 + __ esubq(rdx, rbx, 16777216, true); // {NF}sub rdx, rbx, 16777216 IID850 + __ esubq(rax, r18, 16777216, true); // {NF}sub rax, r18, 16777216 IID851 + __ esubq(r27, r27, 65536, true); // {NF}sub r27, r27, 65536 IID852 + __ exorq(r30, rcx, 4096, false); // {EVEX}xor r30, rcx, 4096 IID853 + __ exorq(rax, r21, 4096, false); // {EVEX}xor rax, r21, 4096 IID854 + __ exorq(rcx, rcx, 16777216, false); // xor rcx, 16777216 IID855 + __ exorq(r21, r12, 1, true); // {NF}xor r21, r12, 1 IID856 + __ exorq(rax, rdx, 1, true); // {NF}xor rax, rdx, 1 IID857 + __ exorq(rbx, rbx, 16777216, true); // {NF}xor rbx, rbx, 16777216 IID858 + __ eorq_imm32(r11, rdx, 65536, false); // {EVEX}or r11, rdx, 65536 IID859 + __ eorq_imm32(rax, r14, 65536, false); // {EVEX}or rax, r14, 65536 IID860 + __ eorq_imm32(r14, r14, 262144, false); // or r14, 262144 IID861 + __ eorq_imm32(r25, r29, 262144, false); // {EVEX}or r25, r29, 262144 IID862 + __ eorq_imm32(rax, r21, 262144, false); // {EVEX}or rax, r21, 262144 IID863 + __ eorq_imm32(r11, r11, 16777216, false); // or r11, 16777216 IID864 + __ esubq_imm32(r29, r19, 67108864, false); // {EVEX}sub r29, r19, 67108864 IID865 + __ esubq_imm32(rax, r11, 67108864, false); // {EVEX}sub rax, r11, 67108864 IID866 + __ esubq_imm32(r18, r18, 67108864, false); // sub r18, 67108864 IID867 + __ esubq_imm32(r28, r23, 4194304, true); // {NF}sub r28, r23, 4194304 IID868 + __ esubq_imm32(rax, r21, 4194304, true); // {NF}sub rax, r21, 4194304 IID869 + __ esubq_imm32(r16, r16, 16777216, true); // {NF}sub r16, r16, 16777216 IID870 + __ eaddq(r8, r25, Address(r26, r8, (Address::ScaleFactor)1, +0x10633def), false); // {EVEX}add r8, r25, qword ptr [r26+r8*2+0x10633def] IID871 + __ eaddq(r13, r13, Address(r18, r16, (Address::ScaleFactor)1, -0x74204508), false); // add r13, qword ptr [r18+r16*2-0x74204508] IID872 + __ eaddq(r17, r26, Address(r12, +0x23a80abf), true); // {NF}add r17, r26, qword ptr [r12+0x23a80abf] IID873 + __ eaddq(r9, r9, Address(r29, r19, (Address::ScaleFactor)0, -0x29e9e52), true); // {NF}add r9, r9, qword ptr [r29+r19*1-0x29e9e52] IID874 + __ eandq(r9, r28, Address(rcx, r25, (Address::ScaleFactor)2, +0x4261ffaa), false); // {EVEX}and r9, r28, qword ptr [rcx+r25*4+0x4261ffaa] IID875 + __ eandq(r27, r27, Address(rdx, r28, (Address::ScaleFactor)0, -0x26bdc9c1), false); // and r27, qword ptr [rdx+r28*1-0x26bdc9c1] IID876 + __ eandq(r14, r11, Address(r16, +0x63ba0ddf), true); // {NF}and r14, r11, qword ptr [r16+0x63ba0ddf] IID877 + __ eandq(r8, r8, Address(r22, r25, (Address::ScaleFactor)1, -0x43b6ab44), true); // {NF}and r8, r8, qword ptr [r22+r25*2-0x43b6ab44] IID878 + __ eorq(r19, rcx, Address(r27, rcx, (Address::ScaleFactor)2, -0x7f687fc6), false); // {EVEX}or r19, rcx, qword ptr [r27+rcx*4-0x7f687fc6] IID879 + __ eorq(r19, r19, Address(rbx, r26, (Address::ScaleFactor)1, -0x486db7ea), false); // or r19, qword ptr [rbx+r26*2-0x486db7ea] IID880 + __ eorq(r30, r10, Address(r14, r18, (Address::ScaleFactor)3, +0x14884884), true); // {NF}or r30, r10, qword ptr [r14+r18*8+0x14884884] IID881 + __ eorq(r27, r27, Address(r29, +0x20337180), true); // {NF}or r27, r27, qword ptr [r29+0x20337180] IID882 + __ eimulq(rcx, r21, Address(r21, rbx, (Address::ScaleFactor)0, -0x3303888e), false); // {EVEX}imul rcx, r21, qword ptr [r21+rbx*1-0x3303888e] IID883 + __ eimulq(rdx, rdx, Address(r28, r9, (Address::ScaleFactor)3, -0x7ad8f741), false); // imul rdx, qword ptr [r28+r9*8-0x7ad8f741] IID884 + __ eimulq(r8, r29, Address(r17, r12, (Address::ScaleFactor)0, +0x6e85396a), true); // {NF}imul r8, r29, qword ptr [r17+r12*1+0x6e85396a] IID885 + __ eimulq(r16, r16, Address(r19, r10, (Address::ScaleFactor)3, -0x49599300), true); // {NF}imul r16, r16, qword ptr [r19+r10*8-0x49599300] IID886 + __ esubq(r20, r17, Address(r13, r22, (Address::ScaleFactor)0, +0x1d219a4f), false); // {EVEX}sub r20, r17, qword ptr [r13+r22*1+0x1d219a4f] IID887 + __ esubq(r25, r25, Address(r21, r21, (Address::ScaleFactor)3, -0x6868a8c7), false); // sub r25, qword ptr [r21+r21*8-0x6868a8c7] IID888 + __ esubq(r20, r24, Address(rbx, r20, (Address::ScaleFactor)2, +0x32c59da6), true); // {NF}sub r20, r24, qword ptr [rbx+r20*4+0x32c59da6] IID889 + __ esubq(r8, r8, Address(r12, r17, (Address::ScaleFactor)0, -0x26be2dcf), true); // {NF}sub r8, r8, qword ptr [r12+r17*1-0x26be2dcf] IID890 + __ exorq(rdx, r19, Address(r9, +0x7d903b91), false); // {EVEX}xor rdx, r19, qword ptr [r9+0x7d903b91] IID891 + __ exorq(r28, r28, Address(r29, r27, (Address::ScaleFactor)2, +0x53091f6f), false); // xor r28, qword ptr [r29+r27*4+0x53091f6f] IID892 + __ exorq(r17, r16, Address(r27, +0x7c6e9207), true); // {NF}xor r17, r16, qword ptr [r27+0x7c6e9207] IID893 + __ exorq(r15, r15, Address(r13, r24, (Address::ScaleFactor)3, -0x75c87960), true); // {NF}xor r15, r15, qword ptr [r13+r24*8-0x75c87960] IID894 + __ eaddq(r16, rbx, r18, false); // {load}{EVEX}add r16, rbx, r18 IID895 + __ eaddq(r24, r24, r18, false); // {load}add r24, r18 IID896 + __ eaddq(r9, r15, r9, false); // {load}add r9, r15 IID897 + __ eaddq(r19, r26, r13, true); // {load}{NF}add r19, r26, r13 IID898 + __ eaddq(r28, r28, r22, true); // {load}{NF}add r28, r28, r22 IID899 + __ eaddq(r22, r11, r22, true); // {load}{NF}add r22, r11, r22 IID900 + __ eadcxq(rcx, r12, r13); // {load}{EVEX}adcx rcx, r12, r13 IID901 + __ eadcxq(r30, r30, r12); // {load}adcx r30, r12 IID902 + __ eadoxq(r28, r14, r18); // {load}{EVEX}adox r28, r14, r18 IID903 + __ eadoxq(r30, r30, r19); // {load}adox r30, r19 IID904 + __ eandq(r20, r14, r14, false); // {load}{EVEX}and r20, r14, r14 IID905 + __ eandq(r17, r17, r23, false); // {load}and r17, r23 IID906 + __ eandq(r17, r14, r17, false); // {load}and r17, r14 IID907 + __ eandq(r19, r20, r15, true); // {load}{NF}and r19, r20, r15 IID908 + __ eandq(rbx, rbx, r13, true); // {load}{NF}and rbx, rbx, r13 IID909 + __ eandq(r22, r30, r22, true); // {load}{NF}and r22, r30, r22 IID910 + __ eimulq(r17, r24, rcx, false); // {load}{EVEX}imul r17, r24, rcx IID911 + __ eimulq(r21, r21, r8, false); // {load}imul r21, r8 IID912 + __ eimulq(r29, r21, r29, false); // {load}imul r29, r21 IID913 + __ eimulq(r27, r13, r23, true); // {load}{NF}imul r27, r13, r23 IID914 + __ eimulq(r26, r26, r8, true); // {load}{NF}imul r26, r26, r8 IID915 + __ eimulq(r22, r13, r22, true); // {load}{NF}imul r22, r13, r22 IID916 + __ eorq(r11, rdx, r29, false); // {load}{EVEX}or r11, rdx, r29 IID917 + __ eorq(rdx, rdx, r31, false); // {load}or rdx, r31 IID918 + __ eorq(r10, r29, r10, false); // {load}or r10, r29 IID919 + __ eorq(r27, r28, rcx, true); // {load}{NF}or r27, r28, rcx IID920 + __ eorq(r25, r25, r9, true); // {load}{NF}or r25, r25, r9 IID921 + __ eorq(rcx, r8, rcx, true); // {load}{NF}or rcx, r8, rcx IID922 + __ esubq(rcx, r10, r16, false); // {load}{EVEX}sub rcx, r10, r16 IID923 + __ esubq(r17, r17, rcx, false); // {load}sub r17, rcx IID924 + __ esubq(r13, r21, r24, true); // {load}{NF}sub r13, r21, r24 IID925 + __ esubq(r31, r31, r28, true); // {load}{NF}sub r31, r31, r28 IID926 + __ exorq(r23, r28, r23, false); // {load}xor r23, r28 IID927 + __ exorq(r10, r10, r11, false); // {load}xor r10, r11 IID928 + __ exorq(r19, r18, r19, false); // {load}xor r19, r18 IID929 + __ exorq(r31, r9, rdx, true); // {load}{NF}xor r31, r9, rdx IID930 + __ exorq(r13, r13, r9, true); // {load}{NF}xor r13, r13, r9 IID931 + __ exorq(rcx, r10, rcx, true); // {load}{NF}xor rcx, r10, rcx IID932 + __ eshldq(r12, r24, r22, 8, false); // {EVEX}shld r12, r24, r22, 8 IID933 + __ eshldq(r25, r25, r25, 8, false); // shld r25, r25, 8 IID934 + __ eshldq(r21, r20, r15, 8, true); // {NF}shld r21, r20, r15, 8 IID935 + __ eshldq(r21, r21, r10, 8, true); // {NF}shld r21, r21, r10, 8 IID936 + __ eshrdq(r18, r18, r8, 2, false); // shrd r18, r8, 2 IID937 + __ eshrdq(r26, r26, r29, 8, false); // shrd r26, r29, 8 IID938 + __ eshrdq(r29, r26, r19, 2, true); // {NF}shrd r29, r26, r19, 2 IID939 + __ eshrdq(r12, r12, rcx, 4, true); // {NF}shrd r12, r12, rcx, 4 IID940 + __ ecmovq (Assembler::Condition::overflow, r21, r22, r23); // cmovo r21, r22, r23 IID941 + __ ecmovq (Assembler::Condition::overflow, r9, r9, r13); // cmovo r9, r13 IID942 + __ ecmovq (Assembler::Condition::noOverflow, rcx, r23, r24); // cmovno rcx, r23, r24 IID943 + __ ecmovq (Assembler::Condition::noOverflow, r28, r28, rdx); // cmovno r28, rdx IID944 + __ ecmovq (Assembler::Condition::below, r14, r31, r23); // cmovb r14, r31, r23 IID945 + __ ecmovq (Assembler::Condition::below, r30, r30, r23); // cmovb r30, r23 IID946 + __ ecmovq (Assembler::Condition::aboveEqual, r10, r29, r22); // cmovae r10, r29, r22 IID947 + __ ecmovq (Assembler::Condition::aboveEqual, rbx, rbx, r26); // cmovae rbx, r26 IID948 + __ ecmovq (Assembler::Condition::zero, r23, r21, r13); // cmovz r23, r21, r13 IID949 + __ ecmovq (Assembler::Condition::zero, r10, r10, r20); // cmovz r10, r20 IID950 + __ ecmovq (Assembler::Condition::notZero, rbx, r9, r29); // cmovnz rbx, r9, r29 IID951 + __ ecmovq (Assembler::Condition::notZero, r16, r16, r30); // cmovnz r16, r30 IID952 + __ ecmovq (Assembler::Condition::belowEqual, r13, rcx, r29); // cmovbe r13, rcx, r29 IID953 + __ ecmovq (Assembler::Condition::belowEqual, r31, r31, r13); // cmovbe r31, r13 IID954 + __ ecmovq (Assembler::Condition::above, r27, r9, r30); // cmova r27, r9, r30 IID955 + __ ecmovq (Assembler::Condition::above, r26, r26, r20); // cmova r26, r20 IID956 + __ ecmovq (Assembler::Condition::negative, r8, r12, r22); // cmovs r8, r12, r22 IID957 + __ ecmovq (Assembler::Condition::negative, r31, r31, r17); // cmovs r31, r17 IID958 + __ ecmovq (Assembler::Condition::positive, r29, rcx, r25); // cmovns r29, rcx, r25 IID959 + __ ecmovq (Assembler::Condition::positive, r22, r22, r14); // cmovns r22, r14 IID960 + __ ecmovq (Assembler::Condition::parity, rcx, r27, r9); // cmovp rcx, r27, r9 IID961 + __ ecmovq (Assembler::Condition::parity, r22, r22, r11); // cmovp r22, r11 IID962 + __ ecmovq (Assembler::Condition::noParity, r14, r19, r24); // cmovnp r14, r19, r24 IID963 + __ ecmovq (Assembler::Condition::noParity, r24, r24, r17); // cmovnp r24, r17 IID964 + __ ecmovq (Assembler::Condition::less, r17, r19, r30); // cmovl r17, r19, r30 IID965 + __ ecmovq (Assembler::Condition::less, r19, r19, r14); // cmovl r19, r14 IID966 + __ ecmovq (Assembler::Condition::greaterEqual, r25, r11, r29); // cmovge r25, r11, r29 IID967 + __ ecmovq (Assembler::Condition::greaterEqual, r12, r12, r26); // cmovge r12, r26 IID968 + __ ecmovq (Assembler::Condition::lessEqual, r11, rbx, r10); // cmovle r11, rbx, r10 IID969 + __ ecmovq (Assembler::Condition::lessEqual, rdx, rdx, r22); // cmovle rdx, r22 IID970 + __ ecmovq (Assembler::Condition::greater, r14, r15, r23); // cmovg r14, r15, r23 IID971 + __ ecmovq (Assembler::Condition::greater, r8, r8, r24); // cmovg r8, r24 IID972 + __ ecmovq (Assembler::Condition::overflow, rbx, r31, Address(r10, r8, (Address::ScaleFactor)3, -0x313f60e0)); // cmovo rbx, r31, qword ptr [r10+r8*8-0x313f60e0] IID973 + __ ecmovq (Assembler::Condition::overflow, r23, r23, Address(rcx, r24, (Address::ScaleFactor)2, +0x17f41d9c)); // cmovo r23, qword ptr [rcx+r24*4+0x17f41d9c] IID974 + __ ecmovq (Assembler::Condition::noOverflow, r31, r11, Address(r16, +0x2c018942)); // cmovno r31, r11, qword ptr [r16+0x2c018942] IID975 + __ ecmovq (Assembler::Condition::noOverflow, r11, r11, Address(r16, r20, (Address::ScaleFactor)3, +0x674b6a55)); // cmovno r11, qword ptr [r16+r20*8+0x674b6a55] IID976 + __ ecmovq (Assembler::Condition::below, r9, r13, Address(r9, rcx, (Address::ScaleFactor)0, +0x394a11df)); // cmovb r9, r13, qword ptr [r9+rcx*1+0x394a11df] IID977 + __ ecmovq (Assembler::Condition::below, r30, r30, Address(rdx, r22, (Address::ScaleFactor)1, -0x6c362b88)); // cmovb r30, qword ptr [rdx+r22*2-0x6c362b88] IID978 + __ ecmovq (Assembler::Condition::aboveEqual, r13, rcx, Address(r24, rcx, (Address::ScaleFactor)3, +0x46500b66)); // cmovae r13, rcx, qword ptr [r24+rcx*8+0x46500b66] IID979 + __ ecmovq (Assembler::Condition::aboveEqual, r24, r24, Address(r18, r25, (Address::ScaleFactor)1, +0x53283b7c)); // cmovae r24, qword ptr [r18+r25*2+0x53283b7c] IID980 + __ ecmovq (Assembler::Condition::zero, r23, r25, Address(r15, r9, (Address::ScaleFactor)0, -0x5f03031e)); // cmovz r23, r25, qword ptr [r15+r9*1-0x5f03031e] IID981 + __ ecmovq (Assembler::Condition::zero, r25, r25, Address(r28, r16, (Address::ScaleFactor)1, -0x53cef514)); // cmovz r25, qword ptr [r28+r16*2-0x53cef514] IID982 + __ ecmovq (Assembler::Condition::notZero, rbx, r25, Address(r24, r25, (Address::ScaleFactor)2, -0x66caac87)); // cmovnz rbx, r25, qword ptr [r24+r25*4-0x66caac87] IID983 + __ ecmovq (Assembler::Condition::notZero, r16, r16, Address(r27, r30, (Address::ScaleFactor)3, +0x797f455d)); // cmovnz r16, qword ptr [r27+r30*8+0x797f455d] IID984 + __ ecmovq (Assembler::Condition::belowEqual, r25, r30, Address(r18, r18, (Address::ScaleFactor)1, +0x1c9daacd)); // cmovbe r25, r30, qword ptr [r18+r18*2+0x1c9daacd] IID985 + __ ecmovq (Assembler::Condition::belowEqual, r22, r22, Address(rcx, r25, (Address::ScaleFactor)1, -0x3dcbfaa9)); // cmovbe r22, qword ptr [rcx+r25*2-0x3dcbfaa9] IID986 + __ ecmovq (Assembler::Condition::above, r24, r26, Address(r25, +0x747060b5)); // cmova r24, r26, qword ptr [r25+0x747060b5] IID987 + __ ecmovq (Assembler::Condition::above, r8, r8, Address(r24, r20, (Address::ScaleFactor)3, +0x47d285f6)); // cmova r8, qword ptr [r24+r20*8+0x47d285f6] IID988 + __ ecmovq (Assembler::Condition::negative, r12, r16, Address(r13, r10, (Address::ScaleFactor)2, +0x34e5b214)); // cmovs r12, r16, qword ptr [r13+r10*4+0x34e5b214] IID989 + __ ecmovq (Assembler::Condition::negative, rdx, rdx, Address(r15, r19, (Address::ScaleFactor)0, -0x405138b1)); // cmovs rdx, qword ptr [r15+r19*1-0x405138b1] IID990 + __ ecmovq (Assembler::Condition::positive, r18, r21, Address(rbx, r13, (Address::ScaleFactor)2, +0x51b19197)); // cmovns r18, r21, qword ptr [rbx+r13*4+0x51b19197] IID991 + __ ecmovq (Assembler::Condition::positive, r24, r24, Address(r11, r31, (Address::ScaleFactor)3, +0x3e01520a)); // cmovns r24, qword ptr [r11+r31*8+0x3e01520a] IID992 + __ ecmovq (Assembler::Condition::parity, r29, r26, Address(r10, r25, (Address::ScaleFactor)3, -0x5f7c3872)); // cmovp r29, r26, qword ptr [r10+r25*8-0x5f7c3872] IID993 + __ ecmovq (Assembler::Condition::parity, r11, r11, Address(r22, r10, (Address::ScaleFactor)3, -0x68731453)); // cmovp r11, qword ptr [r22+r10*8-0x68731453] IID994 + __ ecmovq (Assembler::Condition::noParity, r20, r15, Address(r9, r25, (Address::ScaleFactor)0, +0x4a37edaa)); // cmovnp r20, r15, qword ptr [r9+r25*1+0x4a37edaa] IID995 + __ ecmovq (Assembler::Condition::noParity, r31, r31, Address(r9, r20, (Address::ScaleFactor)0, +0x4f999f86)); // cmovnp r31, qword ptr [r9+r20*1+0x4f999f86] IID996 + __ ecmovq (Assembler::Condition::less, r18, r23, Address(r9, r27, (Address::ScaleFactor)0, -0x3410441d)); // cmovl r18, r23, qword ptr [r9+r27*1-0x3410441d] IID997 + __ ecmovq (Assembler::Condition::less, r16, r16, Address(r24, r10, (Address::ScaleFactor)3, +0x52ed66ee)); // cmovl r16, qword ptr [r24+r10*8+0x52ed66ee] IID998 + __ ecmovq (Assembler::Condition::greaterEqual, r11, r18, Address(rcx, +0x1de09163)); // cmovge r11, r18, qword ptr [rcx+0x1de09163] IID999 + __ ecmovq (Assembler::Condition::greaterEqual, r14, r14, Address(r24, r23, (Address::ScaleFactor)1, +0x5df3b4da)); // cmovge r14, qword ptr [r24+r23*2+0x5df3b4da] IID1000 + __ ecmovq (Assembler::Condition::lessEqual, r15, r14, Address(r30, r20, (Address::ScaleFactor)1, +0x5c9ab976)); // cmovle r15, r14, qword ptr [r30+r20*2+0x5c9ab976] IID1001 + __ ecmovq (Assembler::Condition::lessEqual, r26, r26, Address(r18, r27, (Address::ScaleFactor)2, -0xd8c329)); // cmovle r26, qword ptr [r18+r27*4-0xd8c329] IID1002 + __ ecmovq (Assembler::Condition::greater, r29, r9, Address(r30, r20, (Address::ScaleFactor)3, -0x37a9cf8d)); // cmovg r29, r9, qword ptr [r30+r20*8-0x37a9cf8d] IID1003 + __ ecmovq (Assembler::Condition::greater, r20, r20, Address(r8, rbx, (Address::ScaleFactor)1, +0x1bdc7def)); // cmovg r20, qword ptr [r8+rbx*2+0x1bdc7def] IID1004 #endif // _LP64 static const uint8_t insns[] = @@ -1243,665 +1327,749 @@ 0x62, 0xd4, 0x68, 0x18, 0x81, 0xb4, 0x82, 0xb9, 0xe2, 0xe1, 0xe9, 0x00, 0x00, 0x00, 0x01, // IID265 0x62, 0xdc, 0x68, 0x1c, 0x81, 0xb4, 0x7d, 0xf8, 0xe2, 0x34, 0x1b, 0x00, 0x00, 0x00, 0x01, // IID266 0x62, 0x0c, 0x60, 0x10, 0x01, 0xac, 0x3b, 0xd8, 0xe7, 0x3c, 0x1f, // IID267 - 0x62, 0x4c, 0x1c, 0x10, 0x01, 0xa4, 0xc8, 0x3e, 0x12, 0xac, 0x9f, // IID268 + 0xd5, 0x55, 0x03, 0xa4, 0xc8, 0x3e, 0x12, 0xac, 0x9f, // IID268 0x62, 0x2c, 0x70, 0x14, 0x01, 0xac, 0xc2, 0x88, 0xe0, 0x08, 0xe4, // IID269 0x62, 0x94, 0x70, 0x1c, 0x01, 0x8c, 0x67, 0x16, 0x82, 0x5b, 0x01, // IID270 - 0x62, 0x64, 0x0c, 0x10, 0x09, 0xa4, 0xd3, 0x4c, 0xbf, 0xca, 0xb9, // IID271 - 0x62, 0x8c, 0x6c, 0x10, 0x09, 0x94, 0xd4, 0x3b, 0xa7, 0x23, 0x35, // IID272 - 0x62, 0x84, 0x34, 0x1c, 0x09, 0xac, 0x7f, 0xaa, 0x22, 0xf4, 0xd5, // IID273 - 0x62, 0xec, 0x7c, 0x14, 0x09, 0x87, 0x01, 0x9b, 0xaf, 0xe9, // IID274 - 0x62, 0x8c, 0x1c, 0x10, 0x08, 0xa4, 0x1e, 0x3a, 0x1e, 0x28, 0x17, // IID275 - 0x62, 0xb4, 0x68, 0x18, 0x08, 0x94, 0xbb, 0xbb, 0xb5, 0x77, 0x24, // IID276 - 0x62, 0x44, 0x7c, 0x14, 0x08, 0x84, 0x4b, 0x51, 0x2e, 0x8a, 0xce, // IID277 - 0x62, 0xd4, 0x60, 0x1c, 0x08, 0x9c, 0xe3, 0x2d, 0x84, 0x29, 0xdd, // IID278 - 0x62, 0x9c, 0x28, 0x10, 0x29, 0x94, 0x73, 0xd2, 0x31, 0x64, 0xc2, // IID279 - 0x62, 0x2c, 0x00, 0x10, 0x29, 0xbc, 0x6e, 0x19, 0x85, 0x21, 0x14, // IID280 - 0x62, 0x54, 0x54, 0x14, 0x29, 0xa9, 0x86, 0xed, 0xaf, 0xef, // IID281 - 0x62, 0x04, 0x04, 0x14, 0x29, 0xbc, 0x01, 0x9f, 0x76, 0x1e, 0xf5, // IID282 - 0x62, 0x7c, 0x04, 0x18, 0x31, 0xa2, 0xe5, 0xbc, 0x2b, 0x5c, // IID283 - 0x62, 0x4c, 0x20, 0x10, 0x31, 0x9c, 0x39, 0xb3, 0x78, 0x60, 0x5c, // IID284 - 0x62, 0x54, 0x6c, 0x14, 0x31, 0xb4, 0xd0, 0x7f, 0xc7, 0x12, 0xf6, // IID285 - 0x62, 0x54, 0x34, 0x1c, 0x31, 0x8f, 0xad, 0xcd, 0x5a, 0x77, // IID286 - 0x62, 0xac, 0x50, 0x10, 0x30, 0xbc, 0x52, 0xd5, 0x1f, 0xe3, 0x2f, // IID287 - 0x62, 0x5c, 0x2c, 0x18, 0x30, 0x93, 0xde, 0x50, 0x31, 0x0a, // IID288 - 0x62, 0x2c, 0x68, 0x14, 0x30, 0x84, 0xf6, 0x97, 0xe8, 0xd4, 0x1a, // IID289 - 0x62, 0x7c, 0x38, 0x1c, 0x30, 0x84, 0x20, 0x82, 0xae, 0x6e, 0x62, // IID290 - 0x62, 0xd4, 0x54, 0x10, 0x81, 0xc7, 0x00, 0x00, 0x10, 0x00, // IID291 - 0x62, 0xfc, 0x7c, 0x18, 0x81, 0xc2, 0x00, 0x00, 0x10, 0x00, // IID292 - 0xd5, 0x10, 0x81, 0xc2, 0x00, 0x01, 0x00, 0x00, // IID293 - 0x62, 0xfc, 0x14, 0x1c, 0x83, 0xc3, 0x10, // IID294 - 0x62, 0xfc, 0x7c, 0x1c, 0x83, 0xc7, 0x10, // IID295 - 0x62, 0xdc, 0x34, 0x14, 0x81, 0xc1, 0x00, 0x00, 0x00, 0x01, // IID296 - 0x62, 0xfc, 0x14, 0x10, 0x81, 0xe2, 0x00, 0x00, 0x10, 0x00, // IID297 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xe6, 0x00, 0x00, 0x10, 0x00, // IID298 - 0xd5, 0x10, 0x81, 0xe3, 0x00, 0x00, 0x01, 0x00, // IID299 - 0x62, 0xdc, 0x24, 0x14, 0x81, 0xe1, 0x00, 0x00, 0x10, 0x00, // IID300 - 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xe4, 0x00, 0x00, 0x10, 0x00, // IID301 - 0x62, 0xdc, 0x1c, 0x14, 0x83, 0xe4, 0x10, // IID302 - 0x62, 0x6c, 0x7c, 0x08, 0x69, 0xfe, 0x00, 0x10, 0x00, 0x00, // IID303 + 0x62, 0x64, 0x0c, 0x10, 0x21, 0xa4, 0xd3, 0x4c, 0xbf, 0xca, 0xb9, // IID271 + 0xd5, 0x53, 0x23, 0x94, 0xd4, 0x3b, 0xa7, 0x23, 0x35, // IID272 + 0x62, 0x84, 0x34, 0x1c, 0x21, 0xac, 0x7f, 0xaa, 0x22, 0xf4, 0xd5, // IID273 + 0x62, 0xec, 0x7c, 0x14, 0x21, 0x87, 0x01, 0x9b, 0xaf, 0xe9, // IID274 + 0x62, 0x8c, 0x1c, 0x10, 0x09, 0xa4, 0x1e, 0x3a, 0x1e, 0x28, 0x17, // IID275 + 0xd5, 0x22, 0x0b, 0x94, 0xbb, 0xbb, 0xb5, 0x77, 0x24, // IID276 + 0x62, 0x44, 0x7c, 0x14, 0x09, 0x84, 0x4b, 0x51, 0x2e, 0x8a, 0xce, // IID277 + 0x62, 0xd4, 0x60, 0x1c, 0x09, 0x9c, 0xe3, 0x2d, 0x84, 0x29, 0xdd, // IID278 + 0x62, 0x9c, 0x28, 0x10, 0x08, 0x94, 0x73, 0xd2, 0x31, 0x64, 0xc2, // IID279 + 0xd5, 0x76, 0x0a, 0xbc, 0x6e, 0x19, 0x85, 0x21, 0x14, // IID280 + 0x62, 0x54, 0x54, 0x14, 0x08, 0xa9, 0x86, 0xed, 0xaf, 0xef, // IID281 + 0x62, 0x04, 0x04, 0x14, 0x08, 0xbc, 0x01, 0x9f, 0x76, 0x1e, 0xf5, // IID282 + 0x62, 0x7c, 0x04, 0x18, 0x29, 0xa2, 0xe5, 0xbc, 0x2b, 0x5c, // IID283 + 0x62, 0x4c, 0x20, 0x10, 0x29, 0x9c, 0x39, 0xb3, 0x78, 0x60, 0x5c, // IID284 + 0x62, 0x54, 0x6c, 0x14, 0x29, 0xb4, 0xd0, 0x7f, 0xc7, 0x12, 0xf6, // IID285 + 0x62, 0x54, 0x34, 0x1c, 0x29, 0x8f, 0xad, 0xcd, 0x5a, 0x77, // IID286 + 0x62, 0xac, 0x50, 0x10, 0x31, 0xbc, 0x52, 0xd5, 0x1f, 0xe3, 0x2f, // IID287 + 0xd5, 0x15, 0x33, 0x93, 0xde, 0x50, 0x31, 0x0a, // IID288 + 0x62, 0x2c, 0x68, 0x14, 0x31, 0x84, 0xf6, 0x97, 0xe8, 0xd4, 0x1a, // IID289 + 0x62, 0x7c, 0x38, 0x1c, 0x31, 0x84, 0x20, 0x82, 0xae, 0x6e, 0x62, // IID290 + 0x62, 0xac, 0x7c, 0x10, 0x30, 0x94, 0x3d, 0xf3, 0x49, 0xfc, 0xeb, // IID291 + 0xd5, 0x34, 0x32, 0xac, 0xbb, 0xe1, 0xf1, 0x7e, 0x23, // IID292 + 0x62, 0x3c, 0x14, 0x14, 0x30, 0xb4, 0xb2, 0x5b, 0x09, 0xc0, 0x5c, // IID293 + 0x62, 0x4c, 0x20, 0x14, 0x30, 0x9c, 0xe1, 0x58, 0xb9, 0xf7, 0x1c, // IID294 + 0x62, 0xdc, 0x7c, 0x10, 0x83, 0xc0, 0x10, // IID295 + 0x62, 0xdc, 0x7c, 0x18, 0x83, 0xc0, 0x10, // IID296 + 0xd5, 0x10, 0x81, 0xc5, 0x00, 0x00, 0x01, 0x00, // IID297 + 0x62, 0xd4, 0x3c, 0x14, 0x81, 0xc0, 0x00, 0x00, 0x10, 0x00, // IID298 + 0x62, 0xd4, 0x7c, 0x1c, 0x81, 0xc5, 0x00, 0x00, 0x10, 0x00, // IID299 + 0x62, 0xdc, 0x14, 0x14, 0x81, 0xc5, 0x00, 0x00, 0x00, 0x01, // IID300 + 0x41, 0x83, 0xe4, 0x10, // IID301 + 0x62, 0xdc, 0x7c, 0x18, 0x83, 0xe6, 0x10, // IID302 + 0xd5, 0x11, 0x83, 0xe0, 0x10, // IID303 + 0x62, 0xd4, 0x3c, 0x1c, 0x83, 0xe4, 0x01, // IID304 + 0x62, 0xd4, 0x7c, 0x1c, 0x83, 0xe5, 0x01, // IID305 + 0x62, 0xdc, 0x34, 0x14, 0x83, 0xe1, 0x10, // IID306 + 0x62, 0xec, 0x7c, 0x08, 0x69, 0xd7, 0x00, 0x00, 0x01, 0x00, // IID307 + 0x62, 0xd4, 0x7c, 0x08, 0x69, 0xc1, 0x00, 0x00, 0x01, 0x00, // IID308 + 0x62, 0x4c, 0x7c, 0x08, 0x69, 0xd2, 0x00, 0x00, 0x00, 0x10, // IID309 + 0x62, 0x6c, 0x7c, 0x0c, 0x6b, 0xcd, 0x01, // IID310 + 0x62, 0xdc, 0x7c, 0x0c, 0x6b, 0xc0, 0x01, // IID311 + 0x62, 0x4c, 0x7c, 0x0c, 0x69, 0xc0, 0x00, 0x00, 0x00, 0x01, // IID312 + 0x62, 0xdc, 0x0c, 0x10, 0x83, 0xca, 0x01, // IID313 + 0x62, 0xfc, 0x7c, 0x18, 0x83, 0xce, 0x01, // IID314 + 0xd5, 0x10, 0x81, 0xc9, 0x00, 0x00, 0x10, 0x00, // IID315 + 0x62, 0xd4, 0x3c, 0x14, 0x83, 0xc8, 0x01, // IID316 + 0x62, 0xdc, 0x7c, 0x1c, 0x83, 0xcb, 0x01, // IID317 #endif // _LP64 - 0x62, 0xf4, 0x7c, 0x08, 0x69, 0xc3, 0x00, 0x10, 0x00, 0x00, // IID304 + 0x62, 0xf4, 0x6c, 0x1c, 0x81, 0xca, 0x00, 0x00, 0x00, 0x10, // IID318 #ifdef _LP64 - 0x62, 0x4c, 0x7c, 0x08, 0x69, 0xc0, 0x00, 0x00, 0x10, 0x00, // IID305 - 0x62, 0xec, 0x7c, 0x0c, 0x69, 0xe8, 0x00, 0x00, 0x01, 0x00, // IID306 - 0x62, 0xdc, 0x7c, 0x0c, 0x69, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID307 - 0x62, 0x54, 0x7c, 0x0c, 0x6b, 0xed, 0x10, // IID308 - 0x62, 0xd4, 0x14, 0x10, 0x81, 0xc8, 0x00, 0x00, 0x00, 0x01, // IID309 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xcc, 0x00, 0x00, 0x00, 0x01, // IID310 - 0xd5, 0x11, 0x81, 0xce, 0x00, 0x10, 0x00, 0x00, // IID311 - 0x62, 0xf4, 0x3c, 0x14, 0x83, 0xca, 0x10, // IID312 - 0x62, 0xd4, 0x7c, 0x1c, 0x83, 0xc8, 0x10, // IID313 - 0x62, 0xd4, 0x14, 0x1c, 0x81, 0xcd, 0x00, 0x10, 0x00, 0x00, // IID314 - 0x62, 0xd4, 0x34, 0x10, 0xd1, 0xd5, // IID315 - 0x62, 0xfc, 0x7c, 0x18, 0xd1, 0xd2, // IID316 - 0x41, 0xc1, 0xd1, 0x10, // IID317 - 0x62, 0xdc, 0x2c, 0x10, 0xc1, 0xc1, 0x08, // IID318 + 0xd5, 0x10, 0xc1, 0xd6, 0x08, // IID319 + 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xd7, 0x08, // IID320 + 0xd5, 0x10, 0xc1, 0xd3, 0x04, // IID321 + 0x62, 0xdc, 0x0c, 0x10, 0xc1, 0xc0, 0x02, // IID322 + 0x62, 0xdc, 0x7c, 0x18, 0xc1, 0xc5, 0x02, // IID323 + 0x41, 0xc1, 0xc0, 0x02, // IID324 + 0x62, 0xdc, 0x6c, 0x14, 0xc1, 0xc0, 0x10, // IID325 + 0x62, 0xd4, 0x7c, 0x1c, 0xc1, 0xc5, 0x10, // IID326 + 0x62, 0xdc, 0x3c, 0x14, 0xd1, 0xc0, // IID327 + 0x62, 0xfc, 0x1c, 0x10, 0xc1, 0xc9, 0x10, // IID328 + 0x62, 0xdc, 0x7c, 0x18, 0xc1, 0xc8, 0x10, // IID329 + 0xd5, 0x10, 0xc1, 0xc9, 0x04, // IID330 + 0x62, 0xf4, 0x3c, 0x14, 0xc1, 0xc9, 0x04, // IID331 + 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xc8, 0x04, // IID332 + 0x62, 0xd4, 0x04, 0x1c, 0xc1, 0xcf, 0x02, // IID333 + 0x62, 0xdc, 0x0c, 0x18, 0xc1, 0xe3, 0x04, // IID334 + 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xe7, 0x04, // IID335 + 0xd5, 0x11, 0xc1, 0xe6, 0x04, // IID336 + 0x62, 0xf4, 0x24, 0x14, 0xc1, 0xe2, 0x02, // IID337 + 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xe3, 0x02, // IID338 + 0x62, 0xfc, 0x5c, 0x14, 0xc1, 0xe4, 0x02, // IID339 + 0x62, 0xfc, 0x54, 0x10, 0xd1, 0xff, // IID340 + 0x62, 0xdc, 0x7c, 0x18, 0xd1, 0xfe, // IID341 + 0xd5, 0x11, 0xc1, 0xf9, 0x02, // IID342 + 0x62, 0xfc, 0x3c, 0x14, 0xc1, 0xfb, 0x04, // IID343 + 0x62, 0xd4, 0x7c, 0x1c, 0xc1, 0xfe, 0x04, // IID344 + 0x62, 0xdc, 0x2c, 0x14, 0xc1, 0xfa, 0x10, // IID345 + 0x62, 0xd4, 0x4c, 0x10, 0xc1, 0xe5, 0x08, // IID346 + 0x62, 0xdc, 0x7c, 0x18, 0xc1, 0xe0, 0x08, // IID347 + 0x41, 0xc1, 0xe6, 0x10, // IID348 + 0x62, 0xdc, 0x1c, 0x14, 0xc1, 0xe1, 0x08, // IID349 + 0x62, 0xd4, 0x7c, 0x1c, 0xc1, 0xe2, 0x08, // IID350 + 0x62, 0xfc, 0x5c, 0x14, 0xd1, 0xe4, // IID351 + 0x62, 0xf4, 0x1c, 0x18, 0xc1, 0xeb, 0x04, // IID352 + 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xef, 0x04, // IID353 + 0xd5, 0x11, 0xc1, 0xec, 0x10, // IID354 + 0x62, 0xdc, 0x3c, 0x14, 0xc1, 0xee, 0x04, // IID355 + 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xef, 0x04, // IID356 + 0x62, 0xdc, 0x04, 0x14, 0xc1, 0xef, 0x02, // IID357 + 0x62, 0xd4, 0x5c, 0x10, 0x81, 0xea, 0x00, 0x01, 0x00, 0x00, // IID358 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xed, 0x00, 0x01, 0x00, 0x00, // IID359 + 0xd5, 0x11, 0x81, 0xe9, 0x00, 0x01, 0x00, 0x00, // IID360 + 0x62, 0xd4, 0x44, 0x14, 0x81, 0xec, 0x00, 0x00, 0x00, 0x10, // IID361 + 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xe8, 0x00, 0x00, 0x00, 0x10, // IID362 + 0x62, 0xdc, 0x04, 0x14, 0x83, 0xef, 0x01, // IID363 + 0x62, 0xd4, 0x34, 0x18, 0x81, 0xf7, 0x00, 0x00, 0x00, 0x01, // IID364 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xf5, 0x00, 0x00, 0x00, 0x01, // IID365 + 0xd5, 0x11, 0x83, 0xf4, 0x10, // IID366 + 0x62, 0xfc, 0x14, 0x14, 0x83, 0xf6, 0x10, // IID367 #endif // _LP64 - 0x62, 0xf4, 0x7c, 0x18, 0xc1, 0xc2, 0x08, // IID319 + 0x62, 0xf4, 0x7c, 0x1c, 0x83, 0xf3, 0x10, // IID368 #ifdef _LP64 - 0xd5, 0x11, 0xc1, 0xc0, 0x10, // IID320 - 0x62, 0xf4, 0x3c, 0x14, 0xc1, 0xc1, 0x08, // IID321 - 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xc6, 0x08, // IID322 - 0x62, 0xdc, 0x1c, 0x14, 0xc1, 0xc4, 0x10, // IID323 - 0x62, 0xdc, 0x74, 0x10, 0xc1, 0xcc, 0x04, // IID324 + 0x62, 0xd4, 0x3c, 0x1c, 0x83, 0xf0, 0x10, // IID369 + 0x62, 0xd4, 0x7c, 0x10, 0x81, 0xed, 0x00, 0x00, 0x40, 0x00, // IID370 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xec, 0x00, 0x00, 0x40, 0x00, // IID371 + 0xd5, 0x10, 0x81, 0xe9, 0x00, 0x00, 0x00, 0x04, // IID372 + 0x62, 0xdc, 0x4c, 0x14, 0x81, 0xea, 0x00, 0x00, 0x00, 0x40, // IID373 + 0x62, 0xd4, 0x7c, 0x1c, 0x81, 0xea, 0x00, 0x00, 0x00, 0x40, // IID374 + 0x62, 0xd4, 0x24, 0x1c, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x40, // IID375 + 0x62, 0x1c, 0x64, 0x10, 0x03, 0xa4, 0x06, 0x73, 0x0a, 0x1a, 0x6a, // IID376 + 0xd5, 0x74, 0x03, 0xb4, 0x9a, 0xcf, 0x90, 0xf9, 0x25, // IID377 + 0x62, 0x6c, 0x70, 0x1c, 0x03, 0x8c, 0x03, 0xbc, 0x5d, 0x2d, 0x48, // IID378 + 0x62, 0x54, 0x34, 0x1c, 0x03, 0x8b, 0x01, 0xee, 0xd5, 0x43, // IID379 + 0x62, 0xac, 0x74, 0x18, 0x23, 0xbc, 0xbd, 0xbc, 0xc2, 0x25, 0x28, // IID380 + 0xd5, 0x47, 0x23, 0x9c, 0xfd, 0x6b, 0x47, 0x97, 0xed, // IID381 + 0x62, 0xac, 0x30, 0x1c, 0x23, 0xbc, 0x36, 0x45, 0x53, 0xea, 0xf8, // IID382 + 0x62, 0xdc, 0x60, 0x1c, 0x23, 0x9c, 0x84, 0xee, 0x23, 0x02, 0x0b, // IID383 + 0x62, 0x04, 0x00, 0x18, 0xaf, 0xac, 0x67, 0x97, 0x85, 0xd6, 0xe0, // IID384 + 0xd5, 0xd0, 0xaf, 0x8c, 0x5f, 0x45, 0x75, 0xdc, 0x0a, // IID385 + 0x62, 0x74, 0x20, 0x14, 0xaf, 0x8c, 0xb2, 0x9f, 0xf0, 0x26, 0xbc, // IID386 + 0x62, 0xdc, 0x60, 0x1c, 0xaf, 0x9c, 0xf4, 0xd9, 0x65, 0x62, 0xae, // IID387 + 0x62, 0xd4, 0x74, 0x10, 0x0b, 0x8e, 0x23, 0x22, 0x64, 0x10, // IID388 + 0xd5, 0x55, 0x0b, 0x97, 0x46, 0x7c, 0x65, 0x85, // IID389 + 0x62, 0x84, 0x04, 0x1c, 0x0b, 0xb4, 0xa4, 0x97, 0x69, 0x3b, 0x74, // IID390 + 0x62, 0x74, 0x38, 0x1c, 0x0b, 0x84, 0xf2, 0x24, 0xeb, 0x7b, 0xa7, // IID391 + 0x62, 0x0c, 0x74, 0x18, 0x2b, 0xa4, 0xae, 0xe5, 0x10, 0x93, 0x0e, // IID392 + 0xd5, 0x13, 0x2b, 0x8c, 0x56, 0x2f, 0x91, 0xf8, 0xe4, // IID393 + 0x62, 0xcc, 0x34, 0x1c, 0x2b, 0xae, 0xd3, 0xff, 0x79, 0x2f, // IID394 + 0x62, 0xa4, 0x7c, 0x14, 0x2b, 0x84, 0xb2, 0xc1, 0x71, 0x5d, 0x67, // IID395 + 0x62, 0x24, 0x20, 0x10, 0x33, 0xa4, 0x93, 0x7f, 0xf4, 0x3d, 0x87, // IID396 + 0xd5, 0x35, 0x33, 0xb4, 0x5f, 0x34, 0xae, 0x0d, 0xb0, // IID397 + 0x62, 0xc4, 0x58, 0x14, 0x33, 0x94, 0x85, 0x1e, 0x39, 0x10, 0xe6, // IID398 + 0x62, 0xc4, 0x60, 0x14, 0x33, 0x9c, 0x7d, 0x56, 0x27, 0xe4, 0xd2, // IID399 + 0x62, 0xa4, 0x10, 0x10, 0x32, 0x8c, 0xaa, 0x84, 0x3e, 0x57, 0x66, // IID400 + 0xd5, 0x73, 0x32, 0xb4, 0xc8, 0x3f, 0xa9, 0x94, 0x3a, // IID401 + 0x62, 0x44, 0x10, 0x1c, 0x32, 0xac, 0x7f, 0x32, 0x35, 0xd4, 0x76, // IID402 + 0x62, 0x14, 0x04, 0x1c, 0x32, 0xbc, 0x0d, 0xe6, 0x92, 0xb1, 0xb8, // IID403 + 0x62, 0xec, 0x75, 0x10, 0x33, 0x84, 0x17, 0x91, 0xa2, 0x62, 0x05, // IID404 + 0x66, 0xd5, 0x76, 0x33, 0xac, 0xe2, 0x0e, 0x98, 0xe6, 0xab, // IID405 + 0x62, 0x54, 0x25, 0x14, 0x33, 0x9a, 0x5a, 0x1c, 0x91, 0x0a, // IID406 + 0x62, 0x4c, 0x01, 0x14, 0x33, 0xbc, 0x9e, 0x26, 0x5c, 0x09, 0xff, // IID407 + 0x62, 0x7c, 0x1c, 0x18, 0x03, 0xef, // IID408 + 0xd5, 0x54, 0x03, 0xe4, // IID409 + 0xd5, 0x51, 0x03, 0xe0, // IID410 + 0x62, 0x54, 0x24, 0x1c, 0x03, 0xd7, // IID411 + 0x62, 0xec, 0x64, 0x14, 0x03, 0xdc, // IID412 + 0x62, 0x7c, 0x44, 0x14, 0x03, 0xff, // IID413 + 0x62, 0xcc, 0x2c, 0x10, 0x23, 0xd8, // IID414 + 0xd5, 0x51, 0x23, 0xfc, // IID415 + 0x45, 0x23, 0xdd, // IID416 + 0x62, 0xdc, 0x14, 0x1c, 0x23, 0xd7, // IID417 + 0x62, 0xec, 0x44, 0x14, 0x23, 0xff, // IID418 + 0x62, 0x44, 0x34, 0x1c, 0x23, 0xd9, // IID419 + 0x62, 0xcc, 0x54, 0x10, 0xaf, 0xe0, // IID420 + 0xd5, 0xd1, 0xaf, 0xed, // IID421 + 0x41, 0x0f, 0xaf, 0xdb, // IID422 + 0x62, 0xf4, 0x54, 0x14, 0xaf, 0xd9, // IID423 + 0x62, 0x6c, 0x04, 0x14, 0xaf, 0xfd, // IID424 + 0x62, 0x44, 0x04, 0x1c, 0xaf, 0xcf, // IID425 + 0x62, 0xcc, 0x0d, 0x10, 0x0b, 0xf9, // IID426 + 0x66, 0xd5, 0x40, 0x0b, 0xd1, // IID427 + 0x66, 0x44, 0x0b, 0xd1, // IID428 + 0x62, 0xcc, 0x05, 0x14, 0x0b, 0xea, // IID429 + 0x62, 0xec, 0x55, 0x14, 0x0b, 0xeb, // IID430 #endif // _LP64 - 0x62, 0xf4, 0x7c, 0x18, 0xc1, 0xca, 0x04, // IID325 + 0x62, 0xf4, 0x6d, 0x1c, 0x0b, 0xda, // IID431 #ifdef _LP64 - 0x41, 0xc1, 0xc8, 0x10, // IID326 - 0x62, 0xf4, 0x64, 0x14, 0xc1, 0xca, 0x10, // IID327 - 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xcf, 0x10, // IID328 - 0x62, 0xfc, 0x4c, 0x14, 0xc1, 0xce, 0x08, // IID329 - 0x62, 0xdc, 0x44, 0x10, 0xc1, 0xe1, 0x10, // IID330 - 0x62, 0xd4, 0x7c, 0x18, 0xc1, 0xe6, 0x10, // IID331 - 0xd5, 0x11, 0xc1, 0xe7, 0x08, // IID332 - 0x62, 0xdc, 0x0c, 0x14, 0xc1, 0xe0, 0x02, // IID333 - 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xe5, 0x02, // IID334 - 0x62, 0xd4, 0x3c, 0x1c, 0xc1, 0xe0, 0x02, // IID335 - 0x62, 0xdc, 0x6c, 0x10, 0xc1, 0xf8, 0x10, // IID336 - 0x62, 0xd4, 0x7c, 0x18, 0xc1, 0xfd, 0x10, // IID337 - 0xd5, 0x11, 0xd1, 0xf8, // IID338 - 0x62, 0xfc, 0x1c, 0x14, 0xc1, 0xf9, 0x10, // IID339 - 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xf8, 0x10, // IID340 - 0x62, 0xfc, 0x74, 0x14, 0xc1, 0xf9, 0x04, // IID341 - 0x62, 0xf4, 0x3c, 0x10, 0xc1, 0xe1, 0x04, // IID342 - 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xe0, 0x04, // IID343 - 0x41, 0xc1, 0xe7, 0x02, // IID344 - 0x62, 0xdc, 0x0c, 0x1c, 0xc1, 0xe3, 0x04, // IID345 - 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xe7, 0x04, // IID346 - 0x62, 0xdc, 0x0c, 0x14, 0xc1, 0xe6, 0x04, // IID347 - 0x62, 0xf4, 0x24, 0x10, 0xc1, 0xea, 0x02, // IID348 - 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xeb, 0x02, // IID349 - 0xd5, 0x10, 0xc1, 0xec, 0x02, // IID350 - 0x62, 0xfc, 0x54, 0x14, 0xd1, 0xef, // IID351 - 0x62, 0xdc, 0x7c, 0x1c, 0xd1, 0xee, // IID352 - 0x62, 0xdc, 0x34, 0x14, 0xc1, 0xe9, 0x02, // IID353 - 0x62, 0xfc, 0x3c, 0x10, 0x81, 0xeb, 0x00, 0x00, 0x10, 0x00, // IID354 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xee, 0x00, 0x00, 0x10, 0x00, // IID355 - 0xd5, 0x10, 0x81, 0xee, 0x00, 0x00, 0x00, 0x10, // IID356 - 0x62, 0xdc, 0x3c, 0x14, 0x81, 0xe8, 0x00, 0x00, 0x01, 0x00, // IID357 - 0x62, 0xd4, 0x7c, 0x1c, 0x81, 0xee, 0x00, 0x00, 0x01, 0x00, // IID358 - 0x62, 0xdc, 0x1c, 0x14, 0x81, 0xec, 0x00, 0x00, 0x00, 0x10, // IID359 - 0x62, 0xfc, 0x64, 0x18, 0x81, 0xf4, 0x00, 0x01, 0x00, 0x00, // IID360 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xf7, 0x00, 0x01, 0x00, 0x00, // IID361 -#endif // _LP64 - 0x81, 0xf3, 0x00, 0x10, 0x00, 0x00, // IID362 -#ifdef _LP64 - 0x62, 0xdc, 0x3c, 0x14, 0x81, 0xf6, 0x00, 0x00, 0x01, 0x00, // IID363 - 0x62, 0xdc, 0x7c, 0x1c, 0x81, 0xf7, 0x00, 0x00, 0x01, 0x00, // IID364 - 0x62, 0xdc, 0x04, 0x14, 0x81, 0xf7, 0x00, 0x10, 0x00, 0x00, // IID365 - 0x62, 0xd4, 0x5c, 0x10, 0x81, 0xea, 0x00, 0x00, 0x10, 0x00, // IID366 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xed, 0x00, 0x00, 0x10, 0x00, // IID367 - 0xd5, 0x11, 0x81, 0xe9, 0x00, 0x00, 0x10, 0x00, // IID368 - 0x62, 0xd4, 0x44, 0x14, 0x81, 0xec, 0x00, 0x00, 0x00, 0x40, // IID369 - 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xe8, 0x00, 0x00, 0x00, 0x40, // IID370 - 0x62, 0xdc, 0x04, 0x14, 0x81, 0xef, 0x00, 0x00, 0x01, 0x00, // IID371 - 0x62, 0x54, 0x74, 0x10, 0x03, 0xa9, 0x98, 0x2f, 0xef, 0x7f, // IID372 - 0x62, 0x7c, 0x14, 0x14, 0x03, 0x86, 0x54, 0xf5, 0x08, 0xb2, // IID373 - 0x62, 0x84, 0x14, 0x18, 0x23, 0x8c, 0xfc, 0x02, 0xa9, 0xa8, 0x50, // IID374 - 0x62, 0x0c, 0x4c, 0x14, 0x23, 0x8c, 0x92, 0x54, 0x27, 0xea, 0x70, // IID375 - 0x62, 0x1c, 0x64, 0x10, 0xaf, 0xa4, 0x06, 0x73, 0x0a, 0x1a, 0x6a, // IID376 - 0x62, 0xec, 0x08, 0x14, 0xaf, 0x94, 0x9a, 0x39, 0xd7, 0x32, 0x80, // IID377 - 0x62, 0x0c, 0x7c, 0x10, 0x0b, 0xbc, 0xd9, 0xbc, 0x5d, 0x2d, 0x48, // IID378 - 0x62, 0x44, 0x34, 0x1c, 0x0b, 0x9b, 0x01, 0xee, 0xd5, 0x43, // IID379 - 0x62, 0xac, 0x74, 0x18, 0x2b, 0xbc, 0xbd, 0xbc, 0xc2, 0x25, 0x28, // IID380 - 0x62, 0x84, 0x24, 0x14, 0x2b, 0xb4, 0x7d, 0xa7, 0x0d, 0x1f, 0x77, // IID381 - 0x62, 0x44, 0x30, 0x18, 0x33, 0xb4, 0xf1, 0x72, 0x37, 0x29, 0xb5, // IID382 - 0x62, 0xa4, 0x20, 0x1c, 0x33, 0x84, 0xa3, 0xee, 0x23, 0x02, 0x0b, // IID383 - 0x62, 0x04, 0x00, 0x18, 0x32, 0xac, 0x67, 0x97, 0x85, 0xd6, 0xe0, // IID384 - 0x62, 0x6c, 0x74, 0x14, 0x32, 0xb4, 0x5f, 0x45, 0x75, 0xdc, 0x0a, // IID385 - 0x62, 0x74, 0x21, 0x10, 0x33, 0x8c, 0xb2, 0x9f, 0xf0, 0x26, 0xbc, // IID386 - 0x62, 0xcc, 0x61, 0x1c, 0x33, 0xb4, 0x34, 0x4f, 0x5f, 0xcf, 0x82, // IID387 - 0x62, 0x64, 0x0c, 0x18, 0x03, 0xc1, // IID388 - 0xd5, 0x14, 0x03, 0xc1, // IID389 - 0x62, 0x44, 0x2c, 0x14, 0x03, 0xc4, // IID390 - 0x62, 0x6c, 0x3c, 0x14, 0x03, 0xc7, // IID391 - 0x62, 0x4c, 0x14, 0x18, 0x23, 0xd7, // IID392 - 0x45, 0x23, 0xd8, // IID393 - 0x62, 0xc4, 0x74, 0x1c, 0x23, 0xdf, // IID394 - 0x62, 0x54, 0x1c, 0x1c, 0x23, 0xe4, // IID395 - 0x62, 0xec, 0x4c, 0x10, 0xaf, 0xe3, // IID396 - 0x44, 0x0f, 0xaf, 0xc2, // IID397 - 0x62, 0x6c, 0x4c, 0x14, 0xaf, 0xdf, // IID398 - 0x62, 0x7c, 0x34, 0x1c, 0xaf, 0xca, // IID399 - 0x62, 0x44, 0x75, 0x18, 0x0b, 0xf5, // IID400 - 0x66, 0xd5, 0x54, 0x0b, 0xe3, // IID401 - 0x62, 0x4c, 0x1d, 0x1c, 0x0b, 0xf3, // IID402 - 0x62, 0x7c, 0x3d, 0x1c, 0x0b, 0xc6, // IID403 - 0x62, 0xdc, 0x7c, 0x10, 0x0b, 0xce, // IID404 - 0xd5, 0x15, 0x0b, 0xd1, // IID405 - 0x62, 0xec, 0x04, 0x1c, 0x0b, 0xc9, // IID406 - 0x62, 0x5c, 0x34, 0x1c, 0x0b, 0xce, // IID407 - 0x62, 0x7c, 0x5c, 0x10, 0xa5, 0xc5, // IID408 - 0xd5, 0x95, 0xa5, 0xf2, // IID409 - 0x62, 0x74, 0x7c, 0x14, 0xa5, 0xf2, // IID410 - 0x62, 0x7c, 0x64, 0x14, 0xa5, 0xc3, // IID411 - 0x62, 0x64, 0x24, 0x10, 0xad, 0xd3, // IID412 - 0xd5, 0xd1, 0xad, 0xdc, // IID413 - 0x62, 0x54, 0x74, 0x1c, 0xad, 0xf3, // IID414 - 0x62, 0xcc, 0x04, 0x14, 0xad, 0xdf, // IID415 - 0x62, 0x5c, 0x2c, 0x10, 0x2b, 0xe9, // IID416 - 0xd5, 0x45, 0x2b, 0xc3, // IID417 - 0x62, 0xc4, 0x6c, 0x14, 0x2b, 0xe5, // IID418 - 0x62, 0xec, 0x7c, 0x14, 0x2b, 0xc2, // IID419 - 0x62, 0xc4, 0x64, 0x10, 0x33, 0xc8, // IID420 - 0xd5, 0x41, 0x33, 0xdd, // IID421 - 0x62, 0x54, 0x44, 0x14, 0x33, 0xef, // IID422 - 0x62, 0x5c, 0x24, 0x1c, 0x33, 0xdd, // IID423 - 0x62, 0xec, 0x14, 0x10, 0x24, 0xc9, 0x01, // IID424 - 0xd5, 0xd4, 0xa4, 0xc6, 0x04, // IID425 - 0x62, 0x5c, 0x3c, 0x1c, 0x24, 0xdc, 0x10, // IID426 - 0x62, 0xc4, 0x04, 0x1c, 0x24, 0xff, 0x04, // IID427 - 0x62, 0xec, 0x14, 0x10, 0x2c, 0xc6, 0x04, // IID428 - 0x45, 0x0f, 0xac, 0xcd, 0x04, // IID429 - 0x62, 0x7c, 0x04, 0x1c, 0x2c, 0xe5, 0x02, // IID430 - 0x62, 0xec, 0x74, 0x14, 0x2c, 0xf9, 0x02, // IID431 - 0x62, 0xcc, 0x6c, 0x18, 0x40, 0xc5, // IID432 - 0xd5, 0x94, 0x40, 0xd5, // IID433 - 0x62, 0x6c, 0x74, 0x10, 0x41, 0xea, // IID434 - 0xd5, 0xd5, 0x41, 0xe0, // IID435 - 0x62, 0xcc, 0x2c, 0x18, 0x42, 0xe3, // IID436 - 0x45, 0x0f, 0x42, 0xd6, // IID437 - 0x62, 0x64, 0x24, 0x18, 0x43, 0xd9, // IID438 - 0xd5, 0xc1, 0x43, 0xf7, // IID439 - 0x62, 0x6c, 0x04, 0x10, 0x44, 0xf3, // IID440 - 0xd5, 0xd1, 0x44, 0xda, // IID441 - 0x62, 0x5c, 0x54, 0x10, 0x45, 0xf2, // IID442 - 0xd5, 0xc1, 0x45, 0xe7, // IID443 - 0x62, 0x7c, 0x1c, 0x18, 0x46, 0xef, // IID444 - 0xd5, 0xd4, 0x46, 0xe4, // IID445 - 0x62, 0x44, 0x5c, 0x10, 0x47, 0xc3, // IID446 - 0x45, 0x0f, 0x47, 0xd7, // IID447 - 0x62, 0xec, 0x64, 0x10, 0x48, 0xe7, // IID448 - 0xd5, 0x95, 0x48, 0xfa, // IID449 - 0x62, 0x6c, 0x64, 0x10, 0x49, 0xc7, // IID450 - 0xd5, 0xc5, 0x49, 0xe3, // IID451 - 0x44, 0x0f, 0x4a, 0xea, // IID452 - 0xd5, 0xd4, 0x4a, 0xff, // IID453 - 0x62, 0x5c, 0x44, 0x10, 0x4b, 0xcb, // IID454 - 0xd5, 0xd0, 0x4b, 0xec, // IID455 - 0x62, 0xcc, 0x3c, 0x10, 0x4c, 0xed, // IID456 - 0x41, 0x0f, 0x4c, 0xdb, // IID457 - 0x62, 0xf4, 0x54, 0x10, 0x4d, 0xd9, // IID458 - 0xd5, 0xd4, 0x4d, 0xfd, // IID459 - 0x62, 0x4c, 0x04, 0x18, 0x4e, 0xce, // IID460 - 0xd5, 0xd1, 0x4e, 0xf9, // IID461 - 0x62, 0xd4, 0x6c, 0x10, 0x4f, 0xca, // IID462 - 0xd5, 0x91, 0x4f, 0xcf, // IID463 - 0x62, 0xcc, 0x54, 0x10, 0x40, 0x9a, 0x8d, 0xf7, 0xd6, 0x91, // IID464 - 0x62, 0xec, 0x3c, 0x10, 0x41, 0x9c, 0x0e, 0x9a, 0x5f, 0xf8, 0x11, // IID465 - 0x62, 0x6c, 0x74, 0x10, 0x42, 0x84, 0x24, 0x5e, 0x77, 0x4d, 0x53, // IID466 - 0x62, 0xec, 0x5c, 0x10, 0x43, 0x94, 0x24, 0x33, 0xb1, 0x36, 0xb8, // IID467 - 0x62, 0x7c, 0x34, 0x18, 0x44, 0xaf, 0x9d, 0x3a, 0x7c, 0xb4, // IID468 - 0x62, 0x0c, 0x24, 0x18, 0x45, 0x8c, 0x70, 0x51, 0xf8, 0x9a, 0xbb, // IID469 - 0x62, 0x0c, 0x0c, 0x18, 0x46, 0x84, 0xae, 0x1d, 0x66, 0xd0, 0x00, // IID470 - 0x62, 0x04, 0x10, 0x18, 0x47, 0x8c, 0xde, 0x03, 0x14, 0x7e, 0x04, // IID471 - 0x62, 0xe4, 0x3c, 0x10, 0x48, 0x9c, 0xd1, 0xe8, 0xac, 0xb5, 0x9b, // IID472 - 0x62, 0x6c, 0x28, 0x10, 0x49, 0x84, 0x36, 0x46, 0x24, 0x35, 0x70, // IID473 - 0x62, 0x04, 0x60, 0x10, 0x4a, 0x94, 0xb0, 0x5c, 0x2f, 0xa1, 0x78, // IID474 - 0x62, 0x5c, 0x10, 0x10, 0x4b, 0x9c, 0x21, 0x3a, 0x30, 0xa8, 0x27, // IID475 - 0x62, 0x4c, 0x48, 0x10, 0x4c, 0x84, 0x43, 0x10, 0x1a, 0x54, 0x02, // IID476 - 0x62, 0x54, 0x00, 0x10, 0x4d, 0xbc, 0xc0, 0x51, 0x32, 0x8e, 0x55, // IID477 - 0x62, 0x84, 0x24, 0x10, 0x4e, 0x94, 0x10, 0x49, 0x78, 0xe6, 0xb8, // IID478 - 0x62, 0xec, 0x68, 0x10, 0x4f, 0x84, 0x9a, 0xe2, 0x17, 0xf5, 0xed, // IID479 - 0xd5, 0x19, 0x13, 0xdf, // IID480 - 0xd5, 0x5d, 0x3b, 0xf7, // IID481 - 0xd5, 0xdd, 0xaf, 0xec, // IID482 - 0xf3, 0xd5, 0xcd, 0xb8, 0xca, // IID483 - 0xd5, 0x5c, 0x1b, 0xc4, // IID484 - 0xd5, 0x48, 0x2b, 0xc2, // IID485 - 0xf3, 0xd5, 0xdd, 0xbc, 0xd4, // IID486 - 0xf3, 0xd5, 0xcd, 0xbd, 0xe1, // IID487 - 0xd5, 0x59, 0x03, 0xe0, // IID488 - 0xd5, 0x5d, 0x23, 0xc5, // IID489 - 0xd5, 0x59, 0x0b, 0xfb, // IID490 - 0x4d, 0x33, 0xfc, // IID491 - 0xd5, 0x58, 0x8b, 0xd3, // IID492 - 0xd5, 0xcc, 0xbc, 0xf9, // IID493 - 0x4d, 0x0f, 0xbd, 0xcd, // IID494 - 0xd5, 0x98, 0xa3, 0xcc, // IID495 - 0xd5, 0x1c, 0x87, 0xc5, // IID496 - 0xd5, 0x4d, 0x85, 0xc6, // IID497 - 0xd5, 0x6c, 0x01, 0xac, 0xb9, 0x4d, 0x6c, 0xf0, 0x4f, // IID498 - 0xd5, 0x5f, 0x21, 0x94, 0x50, 0x77, 0x5e, 0x26, 0x8a, // IID499 - 0xd5, 0x48, 0x39, 0x8c, 0x1b, 0x9c, 0xd5, 0x33, 0x40, // IID500 - 0xd5, 0x5a, 0x09, 0x94, 0xe6, 0x83, 0xcb, 0x6c, 0xc7, // IID501 - 0xd5, 0x3c, 0x31, 0xa4, 0xfc, 0x60, 0x15, 0x31, 0x4b, // IID502 - 0xd5, 0x6f, 0x29, 0xac, 0xa2, 0x57, 0x26, 0x3a, 0x5c, // IID503 - 0xd5, 0x6b, 0x89, 0xb4, 0xcd, 0x3f, 0x6f, 0x3d, 0x1a, // IID504 - 0xd5, 0xfe, 0xc1, 0x8c, 0xc1, 0x28, 0x24, 0x52, 0xca, // IID505 - 0xd5, 0x19, 0x81, 0xa1, 0xc3, 0x84, 0x21, 0x63, 0x00, 0x00, 0x00, 0x01, // IID506 - 0x4b, 0x81, 0x84, 0x2d, 0x3a, 0x15, 0x8d, 0xc6, 0x00, 0x00, 0x00, 0x01, // IID507 - 0x49, 0x81, 0xb9, 0xfa, 0x37, 0x4b, 0xec, 0x00, 0x10, 0x00, 0x00, // IID508 - 0xd5, 0x19, 0xd1, 0xbf, 0x51, 0xf5, 0xa7, 0x4f, // IID509 - 0xd5, 0x3a, 0xd1, 0xa4, 0xbd, 0x32, 0x82, 0xaa, 0x31, // IID510 - 0xd5, 0x3b, 0x81, 0x9c, 0xb8, 0x49, 0xc7, 0x9a, 0xb9, 0x00, 0x00, 0x00, 0x10, // IID511 - 0xd5, 0x39, 0xc1, 0xac, 0x34, 0x4f, 0x7a, 0x01, 0xc1, 0x02, // IID512 - 0xd5, 0x18, 0x81, 0xa8, 0x15, 0x5c, 0x76, 0xec, 0x00, 0x00, 0x10, 0x00, // IID513 - 0xd5, 0x1b, 0x83, 0xb4, 0x05, 0x15, 0x26, 0x02, 0x1d, 0x10, // IID514 - 0xd5, 0x2b, 0x83, 0x8c, 0x64, 0x1e, 0x67, 0x37, 0xcb, 0x01, // IID515 - 0xd5, 0x2a, 0xc7, 0x84, 0x81, 0xf8, 0x14, 0xbb, 0xe9, 0x00, 0x01, 0x00, 0x00, // IID516 - 0xd5, 0x19, 0xf7, 0x85, 0xf5, 0x76, 0xdc, 0x82, 0x00, 0x00, 0xff, 0xff, // IID517 - 0xd5, 0x68, 0x03, 0xbc, 0x99, 0x54, 0xc6, 0xea, 0x70, // IID518 - 0xd5, 0x1b, 0x23, 0x94, 0x38, 0x57, 0x25, 0xb2, 0xdf, // IID519 - 0xd5, 0x1a, 0x3b, 0x94, 0xdf, 0xbd, 0x30, 0xc9, 0x32, // IID520 - 0xf3, 0xd5, 0xcc, 0xbd, 0xa2, 0x71, 0x3d, 0xcc, 0xab, // IID521 - 0xd5, 0x5a, 0x0b, 0xb4, 0x73, 0xc8, 0x82, 0x39, 0xd3, // IID522 - 0x4d, 0x13, 0x92, 0x9f, 0xc5, 0xd7, 0x03, // IID523 - 0x4f, 0x0f, 0xaf, 0x94, 0xc0, 0xd3, 0x79, 0x9e, 0xf1, // IID524 - 0xf3, 0xd5, 0xd9, 0xb8, 0xbd, 0x93, 0x26, 0x81, 0x88, // IID525 - 0xd5, 0x28, 0x1b, 0x8c, 0x5b, 0xcb, 0x01, 0xc6, 0x53, // IID526 - 0xd5, 0x1c, 0x2b, 0xb4, 0x19, 0x8d, 0x0f, 0x74, 0x89, // IID527 - 0xf3, 0xd5, 0xed, 0xbc, 0xac, 0x5a, 0x3c, 0x8d, 0xc9, 0x30, // IID528 - 0xd5, 0x3e, 0x33, 0x94, 0x18, 0xfe, 0x29, 0xf7, 0xc2, // IID529 - 0xd5, 0x7b, 0x8b, 0x94, 0xe4, 0x6f, 0x53, 0x04, 0x9d, // IID530 - 0x48, 0x8d, 0x99, 0xa5, 0x02, 0x06, 0x45, // IID531 - 0xf2, 0xd5, 0xbf, 0x2c, 0xa4, 0x3e, 0xd0, 0x59, 0x67, 0x98, // IID532 - 0xd5, 0x5f, 0x87, 0xbc, 0x50, 0x13, 0xed, 0x98, 0x8f, // IID533 - 0xd5, 0x2d, 0x85, 0xb4, 0xe5, 0xf2, 0x81, 0x10, 0x17, // IID534 - 0xd5, 0x19, 0x83, 0xc7, 0x10, // IID535 - 0xd5, 0x19, 0x83, 0xe1, 0x10, // IID536 - 0xd5, 0x18, 0x81, 0xd7, 0x00, 0x01, 0x00, 0x00, // IID537 - 0xd5, 0x18, 0x81, 0xfb, 0x00, 0x00, 0x00, 0x10, // IID538 - 0xd5, 0x19, 0xd1, 0xd7, // IID539 - 0xd5, 0x18, 0xd1, 0xd9, // IID540 - 0xd5, 0x19, 0xc1, 0xc1, 0x02, // IID541 - 0xd5, 0x18, 0xc1, 0xc9, 0x04, // IID542 - 0xd5, 0x19, 0xd1, 0xfc, // IID543 - 0x49, 0xc1, 0xe7, 0x04, // IID544 - 0x48, 0x81, 0xdb, 0x00, 0x00, 0x01, 0x00, // IID545 - 0xd5, 0x18, 0xd1, 0xe5, // IID546 - 0x49, 0xd1, 0xea, // IID547 - 0x49, 0x83, 0xee, 0x10, // IID548 - 0xd5, 0x18, 0x81, 0xf2, 0x00, 0x00, 0x00, 0x10, // IID549 - 0xd5, 0x18, 0xc7, 0xc7, 0x10, 0x00, 0x00, 0x00, // IID550 - 0x49, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // IID551 - 0x49, 0x0f, 0xba, 0xe6, 0x04, // IID552 - 0xd5, 0x19, 0xf7, 0xc0, 0x00, 0xf0, 0xff, 0xff, // IID553 - 0xd5, 0x18, 0x81, 0xcb, 0x00, 0x00, 0x10, 0x00, // IID554 - 0x48, 0x81, 0xe9, 0x00, 0x00, 0x00, 0x10, // IID555 - 0xd5, 0x98, 0x40, 0x94, 0xdb, 0xc4, 0xc8, 0x11, 0x02, // IID556 - 0xd5, 0x98, 0x41, 0x9d, 0x43, 0x77, 0x26, 0x49, // IID557 - 0xd5, 0xeb, 0x42, 0xac, 0x60, 0xba, 0xd6, 0x73, 0xb3, // IID558 - 0xd5, 0xbd, 0x43, 0xa4, 0x22, 0x64, 0x07, 0xb2, 0xd9, // IID559 - 0xd5, 0xdb, 0x44, 0x8c, 0x8c, 0x6b, 0x19, 0x97, 0x34, // IID560 - 0xd5, 0xad, 0x45, 0xac, 0x7f, 0x67, 0xf6, 0x5c, 0xd8, // IID561 - 0xd5, 0xd8, 0x46, 0xb6, 0x05, 0xab, 0x39, 0x0f, // IID562 - 0xd5, 0xba, 0x47, 0x8c, 0xd6, 0xb4, 0x6a, 0x73, 0xfb, // IID563 - 0xd5, 0xfc, 0x48, 0x8c, 0x2b, 0x0b, 0x5b, 0x40, 0x0e, // IID564 - 0xd5, 0xbe, 0x49, 0xa4, 0xeb, 0xb5, 0xfb, 0x9d, 0x88, // IID565 - 0xd5, 0x9b, 0x4a, 0x9c, 0x56, 0xdd, 0x7c, 0x86, 0xe6, // IID566 - 0xd5, 0xfb, 0x4b, 0xac, 0x38, 0xd5, 0x9a, 0xce, 0xa8, // IID567 - 0xd5, 0xcb, 0x4c, 0x94, 0x50, 0x77, 0x41, 0xec, 0xa9, // IID568 - 0xd5, 0xfc, 0x4d, 0xa4, 0xed, 0xc4, 0xfd, 0xa0, 0x65, // IID569 - 0xd5, 0xe9, 0x4e, 0xbc, 0x13, 0xf4, 0x0e, 0xe5, 0xe2, // IID570 - 0xd5, 0xda, 0x4f, 0xb4, 0x62, 0x38, 0x1c, 0x5f, 0x1a, // IID571 - 0xd5, 0x10, 0xff, 0xd7, // IID572 - 0xd5, 0x19, 0xf7, 0xf6, // IID573 - 0xd5, 0x18, 0xf7, 0xfb, // IID574 - 0x49, 0xf7, 0xe9, // IID575 - 0x49, 0xf7, 0xe5, // IID576 - 0xd5, 0x18, 0xf7, 0xd8, // IID577 - 0xd5, 0x19, 0xf7, 0xd5, // IID578 - 0x48, 0xd3, 0xc1, // IID579 - 0xd5, 0x19, 0xd3, 0xc9, // IID580 - 0x49, 0xd3, 0xf8, // IID581 - 0xd5, 0x19, 0xd3, 0xe3, // IID582 - 0xd5, 0x19, 0xd3, 0xe6, // IID583 - 0xd5, 0x18, 0xd3, 0xef, // IID584 - 0x48, 0xff, 0xc3, // IID585 - 0x49, 0xff, 0xce, // IID586 - 0xd5, 0x18, 0x55, // IID587 - 0xd5, 0x18, 0x5d, // IID588 - 0xd5, 0x30, 0xff, 0x94, 0x6c, 0x2f, 0xaf, 0xc6, 0x56, // IID589 - 0xd5, 0x39, 0xf7, 0xa4, 0xdf, 0xdd, 0x14, 0x4b, 0xfe, // IID590 - 0xd5, 0x3b, 0xf7, 0x9c, 0x1b, 0xe1, 0x03, 0x24, 0xa7, // IID591 - 0xd5, 0x28, 0xd3, 0xbc, 0xb3, 0x2f, 0xb6, 0x9c, 0x9f, // IID592 - 0xd5, 0x39, 0xd3, 0xa4, 0xfa, 0x79, 0xa0, 0x95, 0x0b, // IID593 - 0xd5, 0x2b, 0xd3, 0xac, 0x16, 0x09, 0x4e, 0x54, 0x03, // IID594 - 0xd5, 0x19, 0xff, 0x84, 0x13, 0x50, 0x32, 0x0b, 0x12, // IID595 - 0xd5, 0x2b, 0xff, 0x8c, 0x89, 0x35, 0x13, 0x55, 0xcb, // IID596 - 0xd5, 0x7a, 0x69, 0xa4, 0x60, 0x5b, 0xfa, 0x21, 0xa6, 0x00, 0x00, 0x10, 0x00, // IID597 - 0xd5, 0x58, 0x69, 0xcf, 0x00, 0x01, 0x00, 0x00, // IID598 - 0xd5, 0x9c, 0xa4, 0xdb, 0x08, // IID599 - 0xd5, 0x9d, 0xac, 0xd4, 0x08, // IID600 - 0x62, 0xdc, 0x2c, 0x10, 0x8f, 0xc5, // IID601 - 0x62, 0xfc, 0xac, 0x18, 0x8f, 0xc6, // IID602 - 0x62, 0xdc, 0x0c, 0x10, 0xff, 0xf1, // IID603 - 0x62, 0xdc, 0x84, 0x18, 0xff, 0xf4, // IID604 - 0xd5, 0xbd, 0xb6, 0x9c, 0x9d, 0xcc, 0x72, 0xc9, 0xed, // IID605 - 0xd5, 0xaf, 0xb7, 0xb4, 0xb0, 0x22, 0x6d, 0x6c, 0xb5, // IID606 - 0xd5, 0xde, 0xbe, 0xa4, 0x3f, 0x54, 0xcb, 0x89, 0x61, // IID607 - 0xd5, 0xec, 0xbf, 0xa4, 0xfb, 0x9f, 0x9a, 0x17, 0xd2, // IID608 - 0x4c, 0x0f, 0xb6, 0xd9, // IID609 - 0xd5, 0xcd, 0xb7, 0xf7, // IID610 - 0x4c, 0x0f, 0xbe, 0xf1, // IID611 - 0xd5, 0xc9, 0xbf, 0xf9, // IID612 - 0x4f, 0x0f, 0xb1, 0xa4, 0x55, 0xc6, 0xd3, 0x39, 0xf8, // IID613 - 0x62, 0xf4, 0xfc, 0x08, 0xf7, 0xf9, // IID614 - 0x62, 0xd4, 0xfc, 0x0c, 0xf7, 0xff, // IID615 - 0x62, 0xfc, 0xfc, 0x08, 0xf7, 0xf7, // IID616 - 0x62, 0xdc, 0xfc, 0x0c, 0xf7, 0xf0, // IID617 - 0x62, 0xdc, 0xfc, 0x08, 0xf7, 0xeb, // IID618 - 0x62, 0xdc, 0xfc, 0x0c, 0xf7, 0xee, // IID619 - 0x62, 0xd4, 0xfc, 0x08, 0xf7, 0xe4, // IID620 - 0x62, 0xf4, 0xfc, 0x0c, 0xf7, 0xe1, // IID621 - 0x62, 0x94, 0xfc, 0x08, 0xf7, 0xa4, 0xcd, 0x6c, 0x54, 0x95, 0xdd, // IID622 - 0x62, 0x94, 0xf8, 0x0c, 0xf7, 0xa4, 0xc5, 0xfb, 0x89, 0x93, 0xd7, // IID623 - 0x62, 0xcc, 0xfc, 0x08, 0xaf, 0xee, // IID624 - 0xd5, 0x18, 0xf7, 0xe9, // IID625 - 0x62, 0x44, 0xfc, 0x0c, 0xaf, 0xec, // IID626 - 0x62, 0x4c, 0xfc, 0x0c, 0xaf, 0xf6, // IID627 - 0x62, 0x44, 0xfc, 0x08, 0xf5, 0xc7, // IID628 - 0x62, 0x4c, 0xfc, 0x08, 0xf5, 0xc9, // IID629 - 0x62, 0x6c, 0xfc, 0x0c, 0xf5, 0xcd, // IID630 - 0x62, 0xec, 0xfc, 0x0c, 0xf5, 0xf6, // IID631 - 0x62, 0xdc, 0xf4, 0x10, 0xf7, 0xde, // IID632 - 0xd5, 0x18, 0xf7, 0xd9, // IID633 - 0x62, 0xfc, 0x84, 0x14, 0xf7, 0xd9, // IID634 - 0x62, 0xdc, 0x94, 0x14, 0xf7, 0xdd, // IID635 - 0x62, 0xd4, 0xac, 0x18, 0xf7, 0xd1, // IID636 - 0xd5, 0x19, 0xf7, 0xd0, // IID637 - 0x62, 0x44, 0xfc, 0x08, 0x88, 0xe7, // IID638 - 0x62, 0x54, 0xfc, 0x08, 0x88, 0xd2, // IID639 - 0x62, 0x4c, 0xfc, 0x0c, 0x88, 0xde, // IID640 - 0x62, 0x4c, 0xfc, 0x0c, 0x88, 0xe4, // IID641 - 0x62, 0xd4, 0x9c, 0x10, 0xd3, 0xc6, // IID642 - 0xd5, 0x18, 0xd3, 0xc7, // IID643 - 0x62, 0xdc, 0xc4, 0x14, 0xd3, 0xc0, // IID644 - 0x62, 0xfc, 0xd4, 0x14, 0xd3, 0xc5, // IID645 - 0x62, 0xfc, 0x84, 0x10, 0xd3, 0xce, // IID646 - 0xd5, 0x19, 0xd3, 0xcc, // IID647 - 0x62, 0xd4, 0xf4, 0x14, 0xd3, 0xca, // IID648 - 0x62, 0xd4, 0xb4, 0x1c, 0xd3, 0xc9, // IID649 - 0x62, 0xdc, 0x94, 0x10, 0xd3, 0xe6, // IID650 - 0x49, 0xd3, 0xe3, // IID651 - 0x62, 0xd4, 0xac, 0x14, 0xd3, 0xe3, // IID652 - 0x62, 0xfc, 0xfc, 0x14, 0xd3, 0xe0, // IID653 - 0x62, 0xd4, 0xe4, 0x18, 0xd3, 0xff, // IID654 - 0x49, 0xd3, 0xfe, // IID655 - 0x62, 0xfc, 0xb4, 0x14, 0xd3, 0xf8, // IID656 - 0x62, 0xd4, 0xbc, 0x1c, 0xd3, 0xf8, // IID657 - 0x62, 0xd4, 0xa4, 0x18, 0xff, 0xcd, // IID658 - 0x48, 0xff, 0xc9, // IID659 - 0x62, 0xfc, 0xd4, 0x14, 0xff, 0xca, // IID660 - 0x62, 0xdc, 0x9c, 0x14, 0xff, 0xcc, // IID661 - 0xd5, 0x18, 0xff, 0xc0, // IID662 - 0xd5, 0x19, 0xff, 0xc5, // IID663 - 0x62, 0xd4, 0xec, 0x14, 0xff, 0xc1, // IID664 - 0x62, 0xfc, 0xe4, 0x14, 0xff, 0xc3, // IID665 - 0x62, 0xfc, 0xe4, 0x10, 0xd3, 0xe2, // IID666 - 0x49, 0xd3, 0xe0, // IID667 - 0x62, 0xd4, 0x9c, 0x1c, 0xd3, 0xe7, // IID668 - 0x62, 0xdc, 0x94, 0x14, 0xd3, 0xe5, // IID669 - 0x62, 0xdc, 0x9c, 0x10, 0xd3, 0xe8, // IID670 - 0xd5, 0x18, 0xd3, 0xeb, // IID671 - 0x62, 0xdc, 0xbc, 0x1c, 0xd3, 0xec, // IID672 - 0x62, 0xfc, 0xf4, 0x14, 0xd3, 0xe9, // IID673 - 0x62, 0x6c, 0xfc, 0x08, 0xf4, 0xe0, // IID674 - 0x62, 0x54, 0xfc, 0x08, 0xf4, 0xf6, // IID675 - 0x62, 0x5c, 0xfc, 0x0c, 0xf4, 0xe7, // IID676 - 0x62, 0x54, 0xfc, 0x0c, 0xf4, 0xf6, // IID677 - 0x62, 0x44, 0xfc, 0x08, 0xaf, 0xbd, 0xae, 0x4c, 0x3b, 0x96, // IID678 - 0x62, 0xec, 0xfc, 0x0c, 0xaf, 0x8a, 0xfb, 0xee, 0x54, 0x9f, // IID679 - 0x62, 0x04, 0xf8, 0x08, 0xf5, 0x9c, 0x8e, 0x83, 0xbf, 0x98, 0x27, // IID680 - 0x62, 0x84, 0xfc, 0x0c, 0xf5, 0xbc, 0x1a, 0xa3, 0x9c, 0x71, 0xc8, // IID681 - 0x62, 0xbc, 0xf4, 0x18, 0xf7, 0x9c, 0xcb, 0xc0, 0x2b, 0xb8, 0x97, // IID682 - 0x62, 0xf4, 0xf4, 0x1c, 0xf7, 0x9c, 0x0b, 0x8d, 0xd3, 0x92, 0x6f, // IID683 - 0x62, 0xc4, 0xfc, 0x08, 0x88, 0xa4, 0x24, 0x2a, 0xd8, 0x74, 0xd5, // IID684 - 0x62, 0x4c, 0xfc, 0x0c, 0x88, 0xbe, 0xd0, 0xf6, 0x03, 0x46, // IID685 - 0x62, 0xdc, 0xe4, 0x18, 0xd3, 0xa0, 0xf9, 0x06, 0x7d, 0x56, // IID686 - 0x62, 0x9c, 0x98, 0x1c, 0xd3, 0xa4, 0x20, 0xb2, 0xa7, 0xb3, 0xe3, // IID687 - 0x62, 0xbc, 0x98, 0x18, 0xd3, 0xbc, 0x87, 0x46, 0x43, 0xa8, 0xce, // IID688 - 0x62, 0x94, 0xb8, 0x1c, 0xd3, 0xbc, 0x86, 0x5b, 0x6f, 0xbd, 0x8e, // IID689 - 0x62, 0x94, 0xc4, 0x10, 0xff, 0x8c, 0x78, 0x23, 0x8d, 0x1d, 0xa5, // IID690 - 0x62, 0x9c, 0x94, 0x1c, 0xff, 0x8c, 0xcd, 0x57, 0x8b, 0xae, 0xa4, // IID691 - 0x62, 0xbc, 0xa0, 0x18, 0xff, 0x84, 0xfd, 0x24, 0x4b, 0x89, 0xde, // IID692 - 0x62, 0xf4, 0x90, 0x1c, 0xff, 0x84, 0x01, 0x37, 0xb7, 0x4b, 0xc9, // IID693 - 0x62, 0xdc, 0xac, 0x10, 0xd3, 0xac, 0x89, 0x6d, 0xb6, 0x76, 0xa0, // IID694 - 0x62, 0xd4, 0xb4, 0x14, 0xd3, 0xa9, 0x21, 0x8d, 0x79, 0x51, // IID695 - 0x62, 0x04, 0xf8, 0x08, 0xf4, 0xa4, 0x95, 0xf6, 0x96, 0x71, 0x20, // IID696 - 0x62, 0xbc, 0xfc, 0x0c, 0xf4, 0x9c, 0x2b, 0x2b, 0xc8, 0x26, 0xdb, // IID697 - 0x62, 0x4c, 0xf4, 0x10, 0x01, 0xbe, 0xff, 0xcc, 0x35, 0x39, // IID698 - 0x62, 0x1c, 0x8c, 0x18, 0x01, 0xb4, 0x93, 0x55, 0x64, 0x52, 0xcb, // IID699 - 0x62, 0x6c, 0xe8, 0x14, 0x01, 0xb4, 0x3c, 0x4b, 0xed, 0xd3, 0x5a, // IID700 - 0x62, 0xe4, 0xdc, 0x14, 0x01, 0xa2, 0x1b, 0x66, 0xd5, 0xcd, // IID701 - 0x62, 0xa4, 0x80, 0x10, 0x21, 0x8c, 0xdb, 0xd2, 0x47, 0xe2, 0x4c, // IID702 - 0x62, 0x6c, 0x88, 0x10, 0x21, 0xb4, 0x5a, 0xec, 0xc2, 0x11, 0xfb, // IID703 - 0x62, 0x44, 0x9c, 0x14, 0x21, 0x84, 0xdb, 0x41, 0xb4, 0x66, 0xd7, // IID704 - 0x62, 0x6c, 0x8c, 0x14, 0x21, 0xb6, 0x24, 0x1c, 0xd2, 0x07, // IID705 - 0x62, 0xc4, 0xa8, 0x10, 0x09, 0xa4, 0xdf, 0x92, 0x17, 0xc2, 0x58, // IID706 - 0x62, 0x14, 0x90, 0x18, 0x09, 0xac, 0x9a, 0xcd, 0x2c, 0x8f, 0xd3, // IID707 - 0x62, 0x44, 0xe4, 0x1c, 0x09, 0x94, 0x1c, 0x44, 0x0e, 0x4f, 0xe0, // IID708 - 0x62, 0x0c, 0x80, 0x14, 0x09, 0xbc, 0x7b, 0x56, 0x17, 0x8d, 0x02, // IID709 - 0x62, 0x4c, 0xb8, 0x10, 0x29, 0x9c, 0x7c, 0x10, 0xf6, 0x80, 0x69, // IID710 - 0x62, 0x14, 0x80, 0x18, 0x29, 0xbc, 0xf3, 0x19, 0x88, 0x68, 0xfb, // IID711 - 0x62, 0x0c, 0xf4, 0x14, 0x29, 0xbc, 0xa9, 0x46, 0x9e, 0x61, 0x31, // IID712 - 0x62, 0x84, 0xec, 0x14, 0x29, 0x94, 0x93, 0x1a, 0x86, 0x22, 0x19, // IID713 - 0x62, 0xc4, 0xe4, 0x18, 0x31, 0xab, 0xe0, 0x2b, 0xe9, 0xb8, // IID714 - 0x62, 0x34, 0xbc, 0x18, 0x31, 0x84, 0x8a, 0x64, 0x1c, 0x30, 0xfb, // IID715 - 0x62, 0x04, 0xf8, 0x14, 0x31, 0x8c, 0x1e, 0xd9, 0x54, 0x66, 0x7c, // IID716 - 0x62, 0x44, 0x94, 0x14, 0x31, 0xaf, 0x87, 0x4b, 0x05, 0xa1, // IID717 - 0x62, 0xd4, 0xe0, 0x10, 0x81, 0x84, 0xb5, 0x59, 0x45, 0xb6, 0x68, 0x00, 0x00, 0x00, 0x01, // IID718 - 0x62, 0x94, 0xf8, 0x14, 0x83, 0x84, 0xfd, 0x0b, 0xc5, 0xeb, 0x9a, 0x01, // IID719 - 0x62, 0x9c, 0x84, 0x10, 0x83, 0xa4, 0x68, 0xf2, 0x95, 0x4e, 0xda, 0x01, // IID720 - 0x62, 0xdc, 0xa4, 0x1c, 0x81, 0xa4, 0x24, 0xda, 0xb4, 0x92, 0xf0, 0x00, 0x00, 0x01, 0x00, // IID721 - 0x62, 0xbc, 0xfc, 0x08, 0x69, 0x8c, 0x12, 0xa1, 0x6d, 0xec, 0x46, 0x00, 0x00, 0x00, 0x01, // IID722 - 0x62, 0x14, 0xfc, 0x0c, 0x6b, 0xbc, 0xd1, 0x0d, 0x95, 0x3c, 0x80, 0x10, // IID723 - 0x62, 0x9c, 0xf0, 0x10, 0x83, 0x8c, 0x33, 0x2c, 0xda, 0x4c, 0x1b, 0x01, // IID724 - 0x62, 0x9c, 0xec, 0x1c, 0x81, 0x8c, 0xb1, 0x7b, 0x94, 0x55, 0xa6, 0x00, 0x10, 0x00, 0x00, // IID725 - 0x62, 0xdc, 0xf0, 0x10, 0xc1, 0xa4, 0x6a, 0xa1, 0x0e, 0x4e, 0x95, 0x08, // IID726 - 0x62, 0xfc, 0x98, 0x1c, 0xc1, 0xa4, 0x0e, 0x55, 0xeb, 0x53, 0xbc, 0x02, // IID727 - 0x62, 0xfc, 0x90, 0x10, 0xc1, 0xbc, 0x02, 0x9f, 0xf3, 0x23, 0xa6, 0x04, // IID728 - 0x62, 0xd4, 0xfc, 0x14, 0xc1, 0xbb, 0xec, 0x2c, 0x42, 0xf8, 0x04, // IID729 - 0x62, 0xbc, 0xa8, 0x10, 0xc1, 0xac, 0xdf, 0xec, 0xdc, 0x46, 0xaa, 0x10, // IID730 - 0x62, 0xbc, 0xc0, 0x14, 0xc1, 0xac, 0x68, 0x1d, 0x1a, 0x31, 0x71, 0x02, // IID731 - 0x62, 0xd4, 0xb4, 0x10, 0x81, 0xa9, 0x54, 0xd4, 0xac, 0xf6, 0x00, 0x00, 0x10, 0x00, // IID732 - 0x62, 0xd4, 0xf0, 0x14, 0x81, 0xac, 0x38, 0xa2, 0x6c, 0xd0, 0x55, 0x00, 0x00, 0x10, 0x00, // IID733 - 0x62, 0x94, 0x90, 0x10, 0x81, 0xb4, 0x01, 0x3f, 0xbe, 0x3e, 0xfd, 0x00, 0x00, 0x10, 0x00, // IID734 - 0x62, 0xfc, 0x98, 0x14, 0x83, 0xb4, 0x5e, 0x43, 0x65, 0x62, 0xd2, 0x10, // IID735 - 0x62, 0xd4, 0xcc, 0x10, 0x83, 0xc6, 0x10, // IID736 - 0x62, 0xd4, 0xfc, 0x18, 0x83, 0xc4, 0x10, // IID737 - 0xd5, 0x19, 0x81, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID738 - 0x62, 0xf4, 0xd4, 0x14, 0x81, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID739 - 0x62, 0xf4, 0xfc, 0x1c, 0x81, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID740 - 0x62, 0xdc, 0xbc, 0x14, 0x81, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID741 - 0x62, 0xdc, 0xd4, 0x10, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x01, // IID742 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x01, // IID743 - 0xd5, 0x19, 0x81, 0xe0, 0x00, 0x00, 0x01, 0x00, // IID744 - 0x62, 0xdc, 0x94, 0x1c, 0x81, 0xe7, 0x00, 0x00, 0x10, 0x00, // IID745 - 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xe5, 0x00, 0x00, 0x10, 0x00, // IID746 - 0x62, 0xdc, 0x8c, 0x14, 0x81, 0xe6, 0x00, 0x00, 0x10, 0x00, // IID747 - 0x62, 0x54, 0xfc, 0x08, 0x69, 0xc5, 0x00, 0x00, 0x00, 0x10, // IID748 - 0x62, 0xdc, 0xfc, 0x08, 0x69, 0xc7, 0x00, 0x00, 0x00, 0x10, // IID749 - 0x62, 0x54, 0xfc, 0x08, 0x69, 0xed, 0x00, 0x00, 0x01, 0x00, // IID750 - 0x62, 0x5c, 0xfc, 0x0c, 0x69, 0xf5, 0x00, 0x00, 0x10, 0x00, // IID751 - 0x62, 0xfc, 0xfc, 0x0c, 0x69, 0xc6, 0x00, 0x00, 0x10, 0x00, // IID752 - 0x62, 0x54, 0xfc, 0x0c, 0x69, 0xc0, 0x00, 0x00, 0x00, 0x10, // IID753 - 0x62, 0xd4, 0x8c, 0x10, 0x81, 0xcf, 0x00, 0x10, 0x00, 0x00, // IID754 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xcc, 0x00, 0x10, 0x00, 0x00, // IID755 - 0xd5, 0x19, 0x81, 0xca, 0x00, 0x00, 0x10, 0x00, // IID756 - 0x62, 0xd4, 0xfc, 0x14, 0x81, 0xcc, 0x00, 0x00, 0x00, 0x10, // IID757 - 0x62, 0xd4, 0xfc, 0x1c, 0x81, 0xc9, 0x00, 0x00, 0x00, 0x10, // IID758 - 0x62, 0xfc, 0xc4, 0x14, 0x81, 0xcf, 0x00, 0x01, 0x00, 0x00, // IID759 - 0x62, 0xd4, 0x84, 0x18, 0xc1, 0xd1, 0x10, // IID760 - 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xd0, 0x10, // IID761 - 0xd5, 0x19, 0xd1, 0xd1, // IID762 - 0x62, 0xfc, 0xb4, 0x18, 0xc1, 0xc1, 0x10, // IID763 - 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xc4, 0x10, // IID764 - 0xd5, 0x19, 0xd1, 0xc3, // IID765 - 0x62, 0xdc, 0xdc, 0x14, 0xd1, 0xc7, // IID766 - 0x62, 0xfc, 0xfc, 0x1c, 0xd1, 0xc2, // IID767 - 0x62, 0xdc, 0x9c, 0x14, 0xc1, 0xc4, 0x10, // IID768 - 0x62, 0xfc, 0xac, 0x10, 0xc1, 0xca, 0x10, // IID769 - 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xc8, 0x10, // IID770 - 0xd5, 0x18, 0xc1, 0xce, 0x10, // IID771 - 0x62, 0xdc, 0xa4, 0x14, 0xd1, 0xcd, // IID772 - 0x62, 0xfc, 0xfc, 0x1c, 0xd1, 0xca, // IID773 - 0x62, 0xfc, 0xd4, 0x14, 0xd1, 0xcd, // IID774 - 0x62, 0xf4, 0x9c, 0x18, 0xc1, 0xe1, 0x02, // IID775 - 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xe0, 0x02, // IID776 - 0xd5, 0x18, 0xc1, 0xe6, 0x08, // IID777 - 0x62, 0xfc, 0xf4, 0x14, 0xc1, 0xe7, 0x08, // IID778 - 0x62, 0xdc, 0xfc, 0x1c, 0xc1, 0xe3, 0x08, // IID779 - 0x62, 0xfc, 0xc4, 0x14, 0xd1, 0xe7, // IID780 - 0x62, 0xdc, 0xbc, 0x18, 0xc1, 0xf9, 0x10, // IID781 - 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xff, 0x10, // IID782 - 0x49, 0xc1, 0xf9, 0x04, // IID783 - 0x62, 0xd4, 0xcc, 0x14, 0xd1, 0xfd, // IID784 - 0x62, 0xd4, 0xfc, 0x1c, 0xd1, 0xfb, // IID785 - 0x62, 0xd4, 0x9c, 0x1c, 0xc1, 0xfc, 0x02, // IID786 - 0x62, 0xdc, 0xf4, 0x18, 0xc1, 0xe6, 0x08, // IID787 - 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xe3, 0x08, // IID788 - 0x49, 0xc1, 0xe5, 0x02, // IID789 - 0x62, 0xd4, 0xec, 0x14, 0xc1, 0xe3, 0x08, // IID790 - 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xe1, 0x08, // IID791 - 0x62, 0xf4, 0xf4, 0x1c, 0xc1, 0xe1, 0x10, // IID792 - 0x62, 0xfc, 0xac, 0x18, 0xc1, 0xee, 0x04, // IID793 - 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xe9, 0x04, // IID794 - 0x49, 0xc1, 0xec, 0x02, // IID795 - 0x62, 0xdc, 0xac, 0x14, 0xc1, 0xef, 0x08, // IID796 - 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xec, 0x08, // IID797 - 0x62, 0xdc, 0x9c, 0x14, 0xd1, 0xec, // IID798 - 0x62, 0xdc, 0x84, 0x18, 0x81, 0xee, 0x00, 0x00, 0x01, 0x00, // IID799 - 0x62, 0xf4, 0xfc, 0x18, 0x81, 0xe9, 0x00, 0x00, 0x01, 0x00, // IID800 - 0xd5, 0x19, 0x83, 0xea, 0x10, // IID801 - 0x62, 0xd4, 0x9c, 0x1c, 0x83, 0xee, 0x01, // IID802 - 0x62, 0xfc, 0xfc, 0x1c, 0x83, 0xed, 0x01, // IID803 - 0x62, 0xfc, 0xdc, 0x14, 0x81, 0xec, 0x00, 0x00, 0x10, 0x00, // IID804 - 0x62, 0xf4, 0xa4, 0x18, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x01, // IID805 - 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xf7, 0x00, 0x00, 0x00, 0x01, // IID806 - 0xd5, 0x19, 0x81, 0xf7, 0x00, 0x00, 0x00, 0x10, // IID807 - 0x62, 0xdc, 0x94, 0x14, 0x81, 0xf4, 0x00, 0x10, 0x00, 0x00, // IID808 - 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xf3, 0x00, 0x10, 0x00, 0x00, // IID809 - 0x62, 0xf4, 0xec, 0x1c, 0x81, 0xf2, 0x00, 0x00, 0x00, 0x10, // IID810 - 0x48, 0x81, 0xca, 0x00, 0x00, 0x10, 0x00, // IID811 - 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xce, 0x00, 0x00, 0x10, 0x00, // IID812 - 0xd5, 0x19, 0x81, 0xcd, 0x00, 0x00, 0x10, 0x00, // IID813 - 0x62, 0xf4, 0xf4, 0x10, 0x81, 0xc9, 0x00, 0x00, 0x40, 0x00, // IID814 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xc9, 0x00, 0x00, 0x40, 0x00, // IID815 - 0xd5, 0x19, 0x81, 0xcb, 0x00, 0x00, 0x00, 0x40, // IID816 - 0x62, 0xfc, 0xfc, 0x10, 0x81, 0xeb, 0x00, 0x00, 0x40, 0x00, // IID817 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xef, 0x00, 0x00, 0x40, 0x00, // IID818 - 0xd5, 0x19, 0x81, 0xea, 0x00, 0x00, 0x04, 0x00, // IID819 - 0x62, 0xfc, 0xf4, 0x14, 0x81, 0xee, 0x00, 0x00, 0x00, 0x40, // IID820 - 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xea, 0x00, 0x00, 0x00, 0x40, // IID821 - 0x62, 0xfc, 0xc4, 0x14, 0x81, 0xef, 0x00, 0x00, 0x00, 0x10, // IID822 - 0x62, 0x4c, 0x90, 0x18, 0x03, 0xb4, 0x58, 0x3b, 0x3a, 0xea, 0x56, // IID823 - 0x62, 0x1c, 0x90, 0x14, 0x03, 0xbc, 0xda, 0xa8, 0xc6, 0xee, 0xb4, // IID824 - 0x62, 0x4c, 0x9c, 0x18, 0x23, 0xb7, 0x8c, 0xc3, 0xef, 0xb9, // IID825 - 0x62, 0x3c, 0xa0, 0x14, 0x23, 0x94, 0x4e, 0xe5, 0xbe, 0x1e, 0x6a, // IID826 - 0x62, 0x44, 0x88, 0x10, 0x0b, 0x94, 0x93, 0xd7, 0x00, 0x60, 0xd4, // IID827 - 0x62, 0x7c, 0xb0, 0x1c, 0x0b, 0xa4, 0x0a, 0xf6, 0x59, 0x48, 0x0b, // IID828 - 0x62, 0xcc, 0xec, 0x18, 0xaf, 0x8c, 0x90, 0xd8, 0x4c, 0x28, 0x3d, // IID829 - 0x62, 0x0c, 0x94, 0x14, 0xaf, 0x94, 0x66, 0x24, 0x31, 0x81, 0x6e, // IID830 - 0x62, 0x7c, 0xe4, 0x18, 0x2b, 0xae, 0x62, 0xd7, 0xd5, 0x8f, // IID831 - 0x62, 0x4c, 0xc4, 0x14, 0x2b, 0xac, 0x11, 0x13, 0x58, 0xad, 0x9d, // IID832 - 0x62, 0xac, 0xbc, 0x18, 0x33, 0x94, 0xb3, 0x69, 0x59, 0x40, 0xf1, // IID833 - 0x62, 0x4c, 0xac, 0x1c, 0x33, 0xa2, 0xca, 0x81, 0x83, 0x16, // IID834 - 0x62, 0xc4, 0xf4, 0x18, 0x03, 0xd0, // IID835 - 0x49, 0x03, 0xce, // IID836 - 0x62, 0x7c, 0xc4, 0x14, 0x03, 0xd0, // IID837 - 0x62, 0x5c, 0xa4, 0x1c, 0x03, 0xd8, // IID838 - 0x62, 0xe4, 0xb5, 0x18, 0x66, 0xd2, // IID839 - 0x66, 0x4d, 0x0f, 0x38, 0xf6, 0xc7, // IID840 - 0x62, 0xcc, 0x86, 0x18, 0x66, 0xf2, // IID841 - 0xf3, 0x4c, 0x0f, 0x38, 0xf6, 0xda, // IID842 - 0x62, 0xfc, 0xe4, 0x10, 0x23, 0xd6, // IID843 - 0xd5, 0x5c, 0x23, 0xe9, // IID844 - 0x62, 0x44, 0xc4, 0x14, 0x23, 0xdf, // IID845 - 0x62, 0x54, 0xb4, 0x1c, 0x23, 0xcd, // IID846 - 0x62, 0x7c, 0xec, 0x10, 0xaf, 0xf8, // IID847 - 0xd5, 0x98, 0xaf, 0xc9, // IID848 - 0x62, 0x7c, 0xc4, 0x14, 0xaf, 0xe4, // IID849 - 0x62, 0x54, 0xac, 0x1c, 0xaf, 0xd1, // IID850 - 0x62, 0xc4, 0xec, 0x18, 0x0b, 0xde, // IID851 - 0x49, 0x0b, 0xcd, // IID852 - 0x62, 0x4c, 0xb4, 0x1c, 0x0b, 0xcd, // IID853 - 0x62, 0xdc, 0xec, 0x1c, 0x0b, 0xd1, // IID854 - 0x62, 0x7c, 0xc4, 0x10, 0x2b, 0xc0, // IID855 - 0x4d, 0x2b, 0xed, // IID856 - 0x62, 0x54, 0xe4, 0x14, 0x2b, 0xe7, // IID857 - 0x62, 0x74, 0xb4, 0x1c, 0x2b, 0xca, // IID858 - 0x62, 0xcc, 0x94, 0x18, 0x33, 0xc7, // IID859 - 0xd5, 0x59, 0x33, 0xce, // IID860 - 0x62, 0x6c, 0xe4, 0x14, 0x33, 0xf4, // IID861 - 0x62, 0x44, 0x84, 0x14, 0x33, 0xfd, // IID862 - 0x62, 0x54, 0xcc, 0x10, 0x24, 0xea, 0x04, // IID863 - 0xd5, 0xd9, 0xa4, 0xe8, 0x10, // IID864 - 0x62, 0x44, 0xdc, 0x14, 0x24, 0xdd, 0x10, // IID865 - 0x62, 0xcc, 0x84, 0x14, 0x24, 0xdf, 0x02, // IID866 - 0x62, 0x7c, 0x8c, 0x10, 0x2c, 0xdc, 0x08, // IID867 - 0x4c, 0x0f, 0xac, 0xfa, 0x01, // IID868 - 0x62, 0x5c, 0x9c, 0x14, 0x2c, 0xf6, 0x02, // IID869 - 0x62, 0xec, 0xdc, 0x14, 0x2c, 0xc4, 0x01, // IID870 - 0x62, 0xcc, 0xd4, 0x10, 0x40, 0xcc, // IID871 - 0xd5, 0x9d, 0x40, 0xfe, // IID872 - 0x62, 0x54, 0xf4, 0x18, 0x41, 0xff, // IID873 - 0x49, 0x0f, 0x41, 0xcd, // IID874 - 0x62, 0x4c, 0xec, 0x18, 0x42, 0xd2, // IID875 - 0xd5, 0xcd, 0x42, 0xe7, // IID876 - 0x62, 0xf4, 0xbc, 0x18, 0x43, 0xd1, // IID877 - 0x48, 0x0f, 0x43, 0xc9, // IID878 - 0x62, 0x54, 0xac, 0x18, 0x44, 0xe9, // IID879 - 0xd5, 0x9d, 0x44, 0xf3, // IID880 - 0x62, 0xc4, 0xa4, 0x18, 0x45, 0xf9, // IID881 - 0x4c, 0x0f, 0x45, 0xda, // IID882 - 0x62, 0x5c, 0x84, 0x10, 0x46, 0xf1, // IID883 - 0xd5, 0xc9, 0x46, 0xe4, // IID884 - 0x62, 0x5c, 0xec, 0x18, 0x47, 0xd4, // IID885 - 0xd5, 0x9c, 0x47, 0xc1, // IID886 - 0x62, 0x6c, 0xf4, 0x18, 0x48, 0xf7, // IID887 - 0xd5, 0xdc, 0x48, 0xd2, // IID888 - 0x62, 0xfc, 0xec, 0x18, 0x49, 0xda, // IID889 - 0xd5, 0xc9, 0x49, 0xed, // IID890 - 0x62, 0x4c, 0xa4, 0x10, 0x4a, 0xe3, // IID891 - 0xd5, 0x9d, 0x4a, 0xde, // IID892 - 0x62, 0xec, 0xf4, 0x18, 0x4b, 0xea, // IID893 - 0xd5, 0x99, 0x4b, 0xcd, // IID894 - 0x62, 0xc4, 0xec, 0x18, 0x4c, 0xec, // IID895 - 0xd5, 0x99, 0x4c, 0xd2, // IID896 - 0x62, 0xfc, 0xf4, 0x10, 0x4d, 0xde, // IID897 - 0x49, 0x0f, 0x4d, 0xd3, // IID898 - 0x62, 0x54, 0xec, 0x18, 0x4e, 0xf0, // IID899 - 0x4d, 0x0f, 0x4e, 0xf0, // IID900 - 0x62, 0x6c, 0xb4, 0x10, 0x4f, 0xed, // IID901 - 0xd5, 0xdd, 0x4f, 0xd6, // IID902 - 0x62, 0x84, 0xbc, 0x10, 0x40, 0xac, 0x5d, 0x1e, 0x52, 0x9c, 0x43, // IID903 - 0x62, 0xcc, 0xa0, 0x18, 0x41, 0x94, 0x05, 0x7f, 0x12, 0x32, 0x06, // IID904 - 0x62, 0x14, 0xf8, 0x10, 0x42, 0x84, 0x50, 0xef, 0x3d, 0x63, 0x10, // IID905 - 0x62, 0x7c, 0x94, 0x18, 0x43, 0xb2, 0xc8, 0x61, 0x09, 0xab, // IID906 - 0x62, 0x1c, 0x98, 0x18, 0x44, 0x84, 0x57, 0x86, 0xbb, 0xe1, 0x85, // IID907 - 0xd5, 0xde, 0x45, 0xac, 0x9b, 0x2e, 0xd2, 0x27, 0xca, // IID908 - 0x62, 0x8c, 0xf0, 0x18, 0x46, 0x94, 0x21, 0xa0, 0x64, 0xbe, 0x30, // IID909 - 0x62, 0x54, 0x98, 0x10, 0x47, 0xa4, 0x42, 0x06, 0x01, 0x47, 0xdd, // IID910 - 0x62, 0x34, 0xa4, 0x18, 0x48, 0x84, 0xdb, 0x96, 0x9e, 0xcc, 0x25, // IID911 - 0x62, 0x44, 0x9c, 0x18, 0x49, 0x9b, 0x02, 0x8f, 0xd2, 0xf3, // IID912 - 0x62, 0x6c, 0xbc, 0x18, 0x4a, 0x94, 0x5b, 0x16, 0x48, 0x92, 0xb7, // IID913 - 0x62, 0x54, 0x88, 0x10, 0x4b, 0x94, 0xd6, 0x84, 0x48, 0x88, 0x14, // IID914 - 0x62, 0x1c, 0xa4, 0x10, 0x4c, 0x84, 0xb5, 0xa8, 0xb7, 0x92, 0x00, // IID915 - 0x62, 0x6c, 0x8c, 0x18, 0x4d, 0xa4, 0x13, 0x45, 0x2d, 0x9c, 0x00, // IID916 - 0x62, 0x74, 0xb0, 0x10, 0x4e, 0x84, 0x91, 0x6b, 0xc8, 0x55, 0x66, // IID917 - 0x62, 0x84, 0xe0, 0x10, 0x4f, 0xac, 0x0a, 0xf5, 0xbc, 0xfa, 0xef, // IID918 + 0x62, 0x6c, 0x74, 0x18, 0x0b, 0xc6, // IID432 + 0xd5, 0x10, 0x0b, 0xcb, // IID433 + 0xd5, 0x55, 0x0b, 0xdb, // IID434 + 0x62, 0x54, 0x04, 0x14, 0x0b, 0xcd, // IID435 + 0x62, 0x6c, 0x04, 0x14, 0x0b, 0xff, // IID436 + 0x62, 0xec, 0x64, 0x14, 0x0b, 0xcb, // IID437 + 0x62, 0x6c, 0x5c, 0x10, 0xa5, 0xc0, // IID438 + 0x44, 0x0f, 0xa5, 0xe2, // IID439 + 0x62, 0x44, 0x14, 0x14, 0xa5, 0xf9, // IID440 + 0x62, 0xec, 0x74, 0x14, 0xa5, 0xe1, // IID441 + 0x62, 0xc4, 0x5c, 0x10, 0xad, 0xd7, // IID442 + 0x44, 0x0f, 0xad, 0xe1, // IID443 + 0x62, 0xc4, 0x0c, 0x1c, 0xad, 0xf9, // IID444 + 0x62, 0x7c, 0x64, 0x14, 0xad, 0xeb, // IID445 + 0x62, 0x4c, 0x0c, 0x10, 0x2b, 0xdb, // IID446 + 0x41, 0x2b, 0xd3, // IID447 + 0x62, 0x5c, 0x04, 0x1c, 0x2b, 0xd8, // IID448 + 0x62, 0x5c, 0x0c, 0x1c, 0x2b, 0xf1, // IID449 + 0x62, 0xc4, 0x04, 0x10, 0x33, 0xc4, // IID450 + 0xd5, 0x41, 0x33, 0xe6, // IID451 + 0xd5, 0x45, 0x33, 0xf5, // IID452 + 0x62, 0xec, 0x3c, 0x14, 0x33, 0xc9, // IID453 + 0x62, 0x6c, 0x2c, 0x14, 0x33, 0xd5, // IID454 + 0x62, 0x54, 0x24, 0x1c, 0x33, 0xeb, // IID455 + 0x62, 0xcc, 0x24, 0x10, 0x24, 0xe9, 0x04, // IID456 + 0xd5, 0x94, 0xa4, 0xd6, 0x04, // IID457 + 0x62, 0x44, 0x54, 0x14, 0x24, 0xc7, 0x10, // IID458 + 0x62, 0xe4, 0x6c, 0x1c, 0x24, 0xda, 0x01, // IID459 + 0x62, 0x54, 0x44, 0x10, 0x2c, 0xc5, 0x10, // IID460 + 0xd5, 0xd1, 0xac, 0xf2, 0x01, // IID461 + 0x62, 0x44, 0x3c, 0x14, 0x2c, 0xf1, 0x10, // IID462 + 0x62, 0x7c, 0x64, 0x14, 0x2c, 0xc3, 0x04, // IID463 + 0x62, 0x6c, 0x0c, 0x10, 0x40, 0xd1, // IID464 + 0xd5, 0x95, 0x40, 0xf2, // IID465 + 0x62, 0xcc, 0x3c, 0x10, 0x41, 0xdd, // IID466 + 0xd5, 0xd4, 0x41, 0xcc, // IID467 + 0x62, 0x54, 0x24, 0x18, 0x42, 0xd6, // IID468 + 0xd5, 0xd5, 0x42, 0xf1, // IID469 + 0x62, 0xcc, 0x14, 0x18, 0x43, 0xf3, // IID470 + 0xd5, 0xd1, 0x43, 0xc0, // IID471 + 0x62, 0x5c, 0x1c, 0x10, 0x44, 0xee, // IID472 + 0xd5, 0xd5, 0x44, 0xf0, // IID473 + 0x62, 0xcc, 0x54, 0x10, 0x45, 0xe7, // IID474 + 0xd5, 0x94, 0x45, 0xc0, // IID475 + 0x62, 0x6c, 0x04, 0x18, 0x46, 0xd6, // IID476 + 0xd5, 0xc4, 0x46, 0xfa, // IID477 + 0x62, 0x54, 0x24, 0x10, 0x47, 0xc2, // IID478 + 0xd5, 0xc1, 0x47, 0xd3, // IID479 + 0x62, 0xfc, 0x24, 0x10, 0x48, 0xdd, // IID480 + 0xd5, 0x95, 0x48, 0xe7, // IID481 + 0x62, 0xfc, 0x1c, 0x18, 0x49, 0xd2, // IID482 + 0xd5, 0xd0, 0x49, 0xd3, // IID483 + 0x62, 0xec, 0x7c, 0x10, 0x4a, 0xe7, // IID484 + 0xd5, 0xd0, 0x4a, 0xd0, // IID485 + 0x62, 0x4c, 0x64, 0x18, 0x4b, 0xfe, // IID486 + 0xd5, 0xd5, 0x4b, 0xfd, // IID487 + 0x62, 0x44, 0x1c, 0x10, 0x4c, 0xca, // IID488 + 0xd5, 0xd4, 0x4c, 0xc4, // IID489 + 0x62, 0xdc, 0x7c, 0x10, 0x4d, 0xd2, // IID490 + 0xd5, 0xd5, 0x4d, 0xe4, // IID491 + 0x62, 0xcc, 0x34, 0x18, 0x4e, 0xe0, // IID492 + 0xd5, 0xd5, 0x4e, 0xc5, // IID493 + 0x62, 0x44, 0x44, 0x10, 0x4f, 0xdf, // IID494 + 0xd5, 0x94, 0x4f, 0xe2, // IID495 + 0x62, 0x5c, 0x64, 0x10, 0x40, 0x8c, 0x4f, 0x43, 0x67, 0x41, 0xfd, // IID496 + 0xd5, 0xb6, 0x40, 0x84, 0x45, 0xcb, 0xa0, 0xe6, 0x41, // IID497 + 0x62, 0x3c, 0x40, 0x10, 0x41, 0xbc, 0xf3, 0xd3, 0x01, 0x52, 0xaa, // IID498 + 0xd5, 0x91, 0x41, 0x94, 0x13, 0xcb, 0xd8, 0x5e, 0xe5, // IID499 + 0x62, 0x0c, 0x64, 0x18, 0x42, 0xac, 0x27, 0x46, 0x22, 0xd4, 0x0b, // IID500 + 0xd5, 0xf0, 0x42, 0xac, 0x6b, 0xe8, 0x77, 0xae, 0xbe, // IID501 + 0x62, 0x2c, 0x44, 0x10, 0x43, 0xac, 0x8e, 0x28, 0x24, 0x52, 0xca, // IID502 + 0xd5, 0xd1, 0x43, 0x91, 0xc3, 0x84, 0x21, 0x63, // IID503 + 0x62, 0x3c, 0x14, 0x10, 0x44, 0xac, 0x2a, 0x3a, 0x15, 0x8d, 0xc6, // IID504 + 0xd5, 0xc7, 0x44, 0xac, 0xcc, 0x2e, 0x20, 0x73, 0x99, // IID505 + 0x62, 0xc4, 0x30, 0x10, 0x45, 0x94, 0xb1, 0x1f, 0xc9, 0x6a, 0x7f, // IID506 + 0xd5, 0xd5, 0x45, 0xa6, 0x94, 0x65, 0x2e, 0x56, // IID507 + 0x62, 0x44, 0x20, 0x10, 0x46, 0x84, 0xa7, 0x49, 0xc7, 0x9a, 0xb9, // IID508 + 0xd5, 0xd7, 0x46, 0x8c, 0xda, 0x57, 0xed, 0xc7, 0xa6, // IID509 + 0x62, 0xec, 0x74, 0x18, 0x47, 0xa0, 0x15, 0x5c, 0x76, 0xec, // IID510 + 0xd5, 0x93, 0x47, 0x9c, 0x05, 0x15, 0x26, 0x02, 0x1d, // IID511 + 0x62, 0x14, 0x68, 0x18, 0x48, 0xb4, 0x64, 0x6f, 0xa5, 0x8d, 0xae, // IID512 + 0xd5, 0xf4, 0x48, 0x84, 0x51, 0x1c, 0x3b, 0xda, 0xe8, // IID513 + 0xd5, 0xa1, 0x49, 0x8c, 0xbf, 0x31, 0xd3, 0x2d, 0x94, // IID514 + 0xd5, 0xc7, 0x49, 0x84, 0x57, 0xf7, 0xc2, 0x04, 0x80, // IID515 + 0x62, 0xd4, 0x40, 0x10, 0x4a, 0x8c, 0x3b, 0x85, 0xc5, 0x38, 0x37, // IID516 + 0xd5, 0xd7, 0x4a, 0x84, 0x16, 0xa8, 0x15, 0xcc, 0x0f, // IID517 + 0x62, 0x44, 0x08, 0x18, 0x4b, 0x94, 0x6e, 0x61, 0x31, 0xcf, 0xbb, // IID518 + 0xd5, 0x95, 0x4b, 0x94, 0x24, 0x9f, 0xc5, 0xd7, 0x03, // IID519 + 0x62, 0x84, 0x2c, 0x18, 0x4c, 0xac, 0xc0, 0xb4, 0x84, 0x65, 0x4a, // IID520 + 0xd5, 0xf4, 0x4c, 0x94, 0xe3, 0xef, 0x60, 0xc6, 0x47, // IID521 + 0x62, 0x74, 0x2c, 0x10, 0x4d, 0x91, 0x97, 0x7a, 0x97, 0x61, // IID522 + 0xd5, 0xe5, 0x4d, 0xb4, 0xdf, 0xcb, 0x01, 0xc6, 0x53, // IID523 + 0x62, 0x7c, 0x0c, 0x18, 0x4e, 0x89, 0x1e, 0x11, 0x93, 0xa9, // IID524 + 0xd5, 0xb5, 0x4e, 0xbc, 0x23, 0x92, 0x47, 0x16, 0x76, // IID525 + 0x62, 0x14, 0x24, 0x10, 0x4f, 0xb4, 0xa9, 0xd7, 0x52, 0x57, 0x0f, // IID526 + 0x44, 0x0f, 0x4f, 0xa4, 0xcb, 0x3a, 0x4b, 0xfe, 0xaa, // IID527 + 0xd5, 0x5d, 0x13, 0xf7, // IID528 + 0x4c, 0x3b, 0xe2, // IID529 + 0xd5, 0xd9, 0xaf, 0xe8, // IID530 + 0xf3, 0xd5, 0x9d, 0xb8, 0xc9, // IID531 + 0x4d, 0x1b, 0xc4, // IID532 + 0xd5, 0x5d, 0x2b, 0xf8, // IID533 + 0xf3, 0xd5, 0x9c, 0xbc, 0xd0, // IID534 + 0xf3, 0xd5, 0xd8, 0xbd, 0xe5, // IID535 + 0xd5, 0x18, 0x03, 0xd1, // IID536 + 0x4d, 0x23, 0xf5, // IID537 + 0xd5, 0x59, 0x0b, 0xe0, // IID538 + 0xd5, 0x58, 0x33, 0xee, // IID539 + 0xd5, 0x1d, 0x8b, 0xe3, // IID540 + 0xd5, 0xc8, 0xbc, 0xfa, // IID541 + 0xd5, 0xdd, 0xbd, 0xfc, // IID542 + 0xd5, 0xcd, 0xa3, 0xc8, // IID543 + 0xd5, 0x48, 0x87, 0xeb, // IID544 + 0xd5, 0x58, 0x85, 0xff, // IID545 + 0xd5, 0x1c, 0x01, 0x93, 0x5f, 0xc1, 0xf2, 0xe7, // IID546 + 0xd5, 0x6d, 0x21, 0x8c, 0x4b, 0x18, 0x94, 0x68, 0x87, // IID547 + 0xd5, 0x2e, 0x39, 0xac, 0xe3, 0x02, 0x21, 0xf7, 0x35, // IID548 + 0xd5, 0x49, 0x09, 0xa8, 0xef, 0xaf, 0xb9, 0xcb, // IID549 + 0xd5, 0x58, 0x31, 0x93, 0x23, 0xdd, 0xb4, 0xbf, // IID550 + 0xd5, 0x3e, 0x29, 0xb4, 0xdf, 0xba, 0xd9, 0x72, 0xbd, // IID551 + 0xd5, 0x4d, 0x89, 0xa4, 0x89, 0x9f, 0xe9, 0x9e, 0x8d, // IID552 + 0xd5, 0xb9, 0xc1, 0x9c, 0xa8, 0x90, 0xe9, 0x6b, 0x3a, // IID553 + 0xd5, 0x1a, 0x81, 0xa4, 0x16, 0xdd, 0x8b, 0xef, 0x07, 0x00, 0x00, 0x10, 0x00, // IID554 + 0xd5, 0x2b, 0x81, 0x84, 0x25, 0x4f, 0x76, 0xb8, 0x8a, 0x00, 0x00, 0x01, 0x00, // IID555 + 0x49, 0x81, 0xba, 0x26, 0x57, 0x2d, 0xf4, 0x00, 0x00, 0x00, 0x10, // IID556 + 0xd5, 0x1a, 0xc1, 0xbc, 0x77, 0xf5, 0xd9, 0x16, 0x6a, 0x04, // IID557 + 0xd5, 0x28, 0xc1, 0xa4, 0x69, 0x1e, 0xac, 0x66, 0x5f, 0x08, // IID558 + 0xd5, 0x28, 0x81, 0x9c, 0xf1, 0xb4, 0x6a, 0x73, 0xfb, 0x00, 0x00, 0x00, 0x10, // IID559 + 0xd5, 0x3a, 0xc1, 0xac, 0x35, 0x0b, 0x5b, 0x40, 0x0e, 0x08, // IID560 + 0xd5, 0x3a, 0x81, 0xac, 0xeb, 0xb5, 0xfb, 0x9d, 0x88, 0x00, 0x10, 0x00, 0x00, // IID561 + 0xd5, 0x1b, 0x83, 0xb4, 0x56, 0xdd, 0x7c, 0x86, 0xe6, 0x10, // IID562 + 0xd5, 0x2a, 0x81, 0x8c, 0xc2, 0x16, 0xb3, 0xd9, 0x18, 0x00, 0x10, 0x00, 0x00, // IID563 + 0x48, 0xc7, 0x83, 0xb3, 0xf8, 0xa7, 0xcf, 0x00, 0x01, 0x00, 0x00, // IID564 + 0xd5, 0x39, 0xf7, 0x84, 0xec, 0xc4, 0xfd, 0xa0, 0x65, 0x00, 0x00, 0x00, 0xf0, // IID565 + 0xd5, 0x69, 0x03, 0xbc, 0x13, 0xf4, 0x0e, 0xe5, 0xe2, // IID566 + 0xd5, 0x5a, 0x23, 0xb4, 0x62, 0x38, 0x1c, 0x5f, 0x1a, // IID567 + 0xd5, 0x79, 0x3b, 0xbc, 0x1e, 0x81, 0xd0, 0x6e, 0xc1, // IID568 + 0xf3, 0xd5, 0xcc, 0xbd, 0xa9, 0xe4, 0xfb, 0xe3, 0x12, // IID569 + 0xd5, 0x3c, 0x0b, 0xb4, 0xad, 0x42, 0x30, 0xd7, 0x00, // IID570 + 0xd5, 0x7e, 0x13, 0xbc, 0xb9, 0x12, 0xe9, 0xbd, 0x0a, // IID571 + 0xd5, 0xeb, 0xaf, 0xa4, 0x1d, 0xe1, 0x03, 0x24, 0xa7, // IID572 + 0xf3, 0xd5, 0x98, 0xb8, 0x9e, 0xdd, 0x93, 0x39, 0x8d, // IID573 + 0xd5, 0x4d, 0x1b, 0x91, 0x09, 0xba, 0x4a, 0x33, // IID574 + 0xd5, 0x2f, 0x2b, 0x8c, 0xf1, 0xfe, 0x9e, 0x65, 0xde, // IID575 + 0xf3, 0xd5, 0xdc, 0xbc, 0x8c, 0x24, 0x4f, 0x45, 0xce, 0xde, // IID576 + 0xd5, 0x79, 0x33, 0x84, 0x44, 0xb9, 0x83, 0xc4, 0x48, // IID577 + 0xd5, 0x6d, 0x8b, 0xb4, 0x01, 0xb1, 0x17, 0x73, 0xf7, // IID578 + 0xd5, 0x3f, 0x8d, 0x9c, 0xae, 0xd0, 0x8f, 0xeb, 0x3e, // IID579 + 0xf2, 0xd5, 0xdf, 0x2c, 0x94, 0xd5, 0x2e, 0x82, 0xf4, 0x3e, // IID580 + 0xd5, 0x7c, 0x87, 0xac, 0xa3, 0x47, 0xc2, 0xf0, 0xc0, // IID581 + 0xd5, 0x3d, 0x85, 0x84, 0x26, 0x17, 0x6a, 0xb5, 0x15, // IID582 + 0xd5, 0x19, 0x81, 0xc2, 0x00, 0x10, 0x00, 0x00, // IID583 + 0xd5, 0x18, 0x83, 0xe4, 0x10, // IID584 + 0xd5, 0x18, 0x81, 0xd7, 0x00, 0x00, 0x10, 0x00, // IID585 + 0x49, 0x81, 0xfc, 0x00, 0x10, 0x00, 0x00, // IID586 + 0x48, 0xc1, 0xd1, 0x04, // IID587 + 0x49, 0xd1, 0xde, // IID588 + 0xd5, 0x18, 0xc1, 0xc7, 0x02, // IID589 + 0x49, 0xc1, 0xcc, 0x04, // IID590 + 0x49, 0xc1, 0xfa, 0x04, // IID591 + 0xd5, 0x18, 0xc1, 0xe4, 0x04, // IID592 + 0x48, 0x81, 0xd9, 0x00, 0x00, 0x10, 0x00, // IID593 + 0xd5, 0x18, 0xc1, 0xe7, 0x10, // IID594 + 0xd5, 0x19, 0xc1, 0xeb, 0x02, // IID595 + 0x48, 0x81, 0xe9, 0x00, 0x00, 0x01, 0x00, // IID596 + 0x49, 0x81, 0xf1, 0x00, 0x00, 0x10, 0x00, // IID597 + 0xd5, 0x18, 0xc7, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID598 + 0xd5, 0x19, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, // IID599 + 0xd5, 0x98, 0xba, 0xe2, 0x40, // IID600 + 0xd5, 0x19, 0xf7, 0xc5, 0x00, 0xf0, 0xff, 0xff, // IID601 + 0xd5, 0x19, 0x81, 0xce, 0x00, 0x00, 0x00, 0x04, // IID602 + 0xd5, 0x19, 0x81, 0xe9, 0x00, 0x00, 0x00, 0x10, // IID603 + 0xd5, 0xfe, 0x40, 0xb4, 0xb9, 0xf0, 0x92, 0xff, 0x47, // IID604 + 0xd5, 0xbf, 0x41, 0x8c, 0x60, 0xc0, 0x04, 0x49, 0x38, // IID605 + 0xd5, 0xfa, 0x42, 0xbc, 0xc7, 0x9a, 0xed, 0x80, 0xe6, // IID606 + 0xd5, 0xbf, 0x43, 0x8c, 0x35, 0xc8, 0x49, 0x5d, 0x2b, // IID607 + 0xd5, 0xca, 0x44, 0x84, 0x7b, 0x81, 0x93, 0x37, 0x22, // IID608 + 0x4d, 0x0f, 0x45, 0x83, 0xa0, 0x67, 0x9d, 0x04, // IID609 + 0xd5, 0xfc, 0x46, 0xa4, 0x80, 0x57, 0xe2, 0x6b, 0xa1, // IID610 + 0xd5, 0xda, 0x47, 0x9c, 0x02, 0x14, 0xaa, 0xa1, 0xf5, // IID611 + 0xd5, 0xfe, 0x48, 0xa4, 0x61, 0xf4, 0xdd, 0x9b, 0xcd, // IID612 + 0xd5, 0xef, 0x49, 0xbc, 0x7e, 0x5a, 0xbc, 0x01, 0x50, // IID613 + 0xd5, 0xb8, 0x4a, 0x9c, 0x8a, 0x87, 0xdc, 0x90, 0xd7, // IID614 + 0xd5, 0xd8, 0x4b, 0x8c, 0x24, 0xc8, 0x07, 0xb6, 0xaa, // IID615 + 0xd5, 0xef, 0x4c, 0xb4, 0x61, 0x0d, 0xf3, 0x4f, 0xda, // IID616 + 0xd5, 0xc9, 0x4d, 0x99, 0xd4, 0x0d, 0x54, 0xd5, // IID617 + 0x4a, 0x0f, 0x4e, 0x9c, 0x61, 0x34, 0x97, 0xd2, 0xbc, // IID618 + 0xd5, 0xa9, 0x4f, 0x9c, 0xcf, 0xa2, 0xa9, 0x68, 0xd4, // IID619 + 0xd5, 0x11, 0xff, 0xd0, // IID620 + 0x49, 0xf7, 0xf1, // IID621 + 0xd5, 0x19, 0xf7, 0xfc, // IID622 + 0x48, 0xf7, 0xea, // IID623 + 0xd5, 0x19, 0xf7, 0xe7, // IID624 + 0x49, 0xf7, 0xdc, // IID625 + 0x49, 0xf7, 0xd4, // IID626 + 0xd5, 0x19, 0xd3, 0xc0, // IID627 + 0xd5, 0x19, 0xd3, 0xcc, // IID628 + 0x49, 0xd3, 0xfb, // IID629 + 0xd5, 0x19, 0xd3, 0xe3, // IID630 + 0xd5, 0x18, 0xd3, 0xe7, // IID631 + 0xd5, 0x18, 0xd3, 0xe9, // IID632 + 0xd5, 0x18, 0xff, 0xc0, // IID633 + 0x49, 0xff, 0xcc, // IID634 + 0xd5, 0x18, 0x57, // IID635 + 0xd5, 0x19, 0x58, // IID636 + 0xd5, 0x12, 0xff, 0x94, 0x32, 0xce, 0x62, 0x9c, 0x99, // IID637 + 0xd5, 0x19, 0xf7, 0xa0, 0xdf, 0xdb, 0xf5, 0x99, // IID638 + 0xd5, 0x29, 0xf7, 0x9c, 0x16, 0x6e, 0x93, 0xf3, 0x40, // IID639 + 0x4b, 0xd3, 0xbc, 0x2a, 0x72, 0xcb, 0x04, 0x7d, // IID640 + 0xd5, 0x1a, 0xd3, 0xa4, 0xda, 0x24, 0x4b, 0x89, 0xde, // IID641 + 0x49, 0xd3, 0xac, 0x4d, 0x80, 0xaa, 0x96, 0x79, // IID642 + 0x49, 0xff, 0x86, 0x2a, 0xd0, 0xc2, 0x67, // IID643 + 0xd5, 0x3a, 0xff, 0x8c, 0x16, 0xc0, 0x62, 0x4f, 0x22, // IID644 + 0xd5, 0x19, 0x69, 0x94, 0x5f, 0x10, 0xbb, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, // IID645 + 0xd5, 0x59, 0x69, 0xef, 0x00, 0x10, 0x00, 0x00, // IID646 + 0xd5, 0xc8, 0xa4, 0xdb, 0x01, // IID647 + 0xd5, 0xc9, 0xac, 0xfb, 0x04, // IID648 + 0x62, 0xfc, 0x0c, 0x10, 0x8f, 0xc0, // IID649 + 0x62, 0xfc, 0xe4, 0x18, 0x8f, 0xc1, // IID650 + 0x62, 0xfc, 0x0c, 0x10, 0xff, 0xf4, // IID651 + 0x62, 0xd4, 0x84, 0x10, 0xff, 0xf0, // IID652 + 0xd5, 0xcf, 0xb6, 0xa4, 0x30, 0x7a, 0xe6, 0x9a, 0x46, // IID653 + 0xd5, 0xad, 0xb7, 0xb4, 0x90, 0xfe, 0x61, 0x96, 0xb7, // IID654 + 0xd5, 0xc8, 0xbe, 0xab, 0x95, 0x1f, 0x25, 0x9b, // IID655 + 0xd5, 0xd9, 0xbf, 0x9c, 0x9f, 0x19, 0x88, 0x31, 0x60, // IID656 + 0xd5, 0xcd, 0xb6, 0xf5, // IID657 + 0xd5, 0xdc, 0xb7, 0xf2, // IID658 + 0xd5, 0xc9, 0xbe, 0xdf, // IID659 + 0xd5, 0xd8, 0xbf, 0xe0, // IID660 + 0xd5, 0xcd, 0xb1, 0xa4, 0xdb, 0x9d, 0x47, 0xc3, 0x0f, // IID661 + 0x62, 0xfc, 0xfc, 0x08, 0xf7, 0xfc, // IID662 + 0x62, 0xdc, 0xfc, 0x0c, 0xf7, 0xfe, // IID663 + 0x62, 0xfc, 0xfc, 0x08, 0xf7, 0xf6, // IID664 + 0x62, 0xd4, 0xfc, 0x0c, 0xf7, 0xf3, // IID665 + 0x62, 0xf4, 0xfc, 0x08, 0xf7, 0xe9, // IID666 + 0x62, 0xdc, 0xfc, 0x0c, 0xf7, 0xec, // IID667 + 0x62, 0xfc, 0xfc, 0x08, 0xf7, 0xe5, // IID668 + 0x62, 0xd4, 0xfc, 0x0c, 0xf7, 0xe5, // IID669 + 0x62, 0x9c, 0xfc, 0x08, 0xf7, 0xa4, 0xba, 0x6e, 0xce, 0xa1, 0x70, // IID670 + 0x62, 0xdc, 0xf8, 0x0c, 0xf7, 0xa4, 0x58, 0xa4, 0x7a, 0x8f, 0xe9, // IID671 + 0x62, 0x5c, 0xfc, 0x08, 0xaf, 0xd3, // IID672 + 0xd5, 0x18, 0xf7, 0xe9, // IID673 + 0x62, 0xfc, 0xfc, 0x0c, 0xaf, 0xd6, // IID674 + 0x62, 0xf4, 0xfc, 0x0c, 0xaf, 0xdb, // IID675 + 0x62, 0x44, 0xfc, 0x08, 0xf5, 0xe7, // IID676 + 0x62, 0x54, 0xfc, 0x08, 0xf5, 0xff, // IID677 + 0x62, 0xd4, 0xfc, 0x0c, 0xf5, 0xdc, // IID678 + 0x62, 0xf4, 0xfc, 0x0c, 0xf5, 0xdb, // IID679 + 0x62, 0xd4, 0xac, 0x10, 0xf7, 0xdb, // IID680 + 0xd5, 0x18, 0xf7, 0xd9, // IID681 + 0x62, 0xdc, 0xec, 0x1c, 0xf7, 0xdf, // IID682 + 0x62, 0xdc, 0xa4, 0x14, 0xf7, 0xdb, // IID683 + 0x62, 0xd4, 0x84, 0x10, 0xf7, 0xd7, // IID684 + 0xd5, 0x18, 0xf7, 0xd5, // IID685 + 0x62, 0xdc, 0xfc, 0x08, 0x88, 0xd8, // IID686 + 0x62, 0x4c, 0xfc, 0x08, 0x88, 0xe4, // IID687 + 0x62, 0xcc, 0xfc, 0x0c, 0x88, 0xfb, // IID688 + 0x62, 0x54, 0xfc, 0x0c, 0x88, 0xed, // IID689 + 0x62, 0xdc, 0xb4, 0x10, 0xd3, 0xc4, // IID690 + 0xd5, 0x19, 0xd3, 0xc7, // IID691 + 0x62, 0xfc, 0xb4, 0x14, 0xd3, 0xc7, // IID692 + 0x62, 0xf4, 0xf4, 0x1c, 0xd3, 0xc1, // IID693 + 0x62, 0xd4, 0xcc, 0x10, 0xd3, 0xce, // IID694 + 0x49, 0xd3, 0xcf, // IID695 + 0x62, 0xdc, 0xa4, 0x1c, 0xd3, 0xce, // IID696 + 0x62, 0xdc, 0xbc, 0x14, 0xd3, 0xc8, // IID697 + 0x62, 0xfc, 0xac, 0x18, 0xd3, 0xe4, // IID698 + 0xd5, 0x18, 0xd3, 0xe3, // IID699 + 0x62, 0xdc, 0xf4, 0x14, 0xd3, 0xe1, // IID700 + 0x62, 0xd4, 0x94, 0x1c, 0xd3, 0xe5, // IID701 + 0x62, 0xdc, 0x84, 0x10, 0xd3, 0xfe, // IID702 + 0xd5, 0x18, 0xd3, 0xfa, // IID703 + 0x62, 0xdc, 0xb4, 0x14, 0xd3, 0xf9, // IID704 + 0x62, 0xdc, 0x9c, 0x14, 0xd3, 0xfc, // IID705 + 0x62, 0xdc, 0xcc, 0x10, 0xff, 0xcb, // IID706 + 0x49, 0xff, 0xcc, // IID707 + 0x62, 0xd4, 0xec, 0x14, 0xff, 0xcb, // IID708 + 0x62, 0xd4, 0xac, 0x1c, 0xff, 0xca, // IID709 + 0x62, 0xdc, 0xdc, 0x10, 0xff, 0xc0, // IID710 + 0xd5, 0x18, 0xff, 0xc2, // IID711 + 0x62, 0xd4, 0xe4, 0x1c, 0xff, 0xc3, // IID712 + 0x62, 0xdc, 0xac, 0x14, 0xff, 0xc2, // IID713 + 0x62, 0xd4, 0xd4, 0x10, 0xd3, 0xe0, // IID714 + 0x48, 0xd3, 0xe3, // IID715 + 0x62, 0xfc, 0xcc, 0x14, 0xd3, 0xe5, // IID716 + 0x62, 0xdc, 0xa4, 0x14, 0xd3, 0xe3, // IID717 + 0x62, 0xfc, 0x9c, 0x18, 0xd3, 0xe8, // IID718 + 0x49, 0xd3, 0xe8, // IID719 + 0x62, 0xd4, 0xec, 0x1c, 0xd3, 0xe9, // IID720 + 0x62, 0xfc, 0xdc, 0x14, 0xd3, 0xec, // IID721 + 0x62, 0x6c, 0xfc, 0x08, 0xf4, 0xfd, // IID722 + 0x62, 0xec, 0xfc, 0x08, 0xf4, 0xe4, // IID723 + 0x62, 0xfc, 0xfc, 0x0c, 0xf4, 0xc8, // IID724 + 0x62, 0x54, 0xfc, 0x0c, 0xf4, 0xf6, // IID725 + 0x62, 0x0c, 0xfc, 0x08, 0xaf, 0x9c, 0x49, 0x93, 0x23, 0x5a, 0x44, // IID726 + 0x62, 0xa4, 0xfc, 0x0c, 0xaf, 0xbc, 0x49, 0xf4, 0x10, 0x7f, 0xeb, // IID727 + 0x62, 0x7c, 0xf8, 0x08, 0xf5, 0xac, 0x4e, 0x6a, 0xe6, 0xf3, 0x8a, // IID728 + 0x62, 0x5c, 0xfc, 0x0c, 0xf5, 0xaf, 0xa7, 0x9d, 0xd4, 0xcb, // IID729 + 0x62, 0x9c, 0x84, 0x10, 0xf7, 0x9c, 0x68, 0xf2, 0x95, 0x4e, 0xda, // IID730 + 0x62, 0x94, 0x90, 0x1c, 0xf7, 0x9c, 0xe3, 0xab, 0x13, 0x00, 0x5c, // IID731 + 0x62, 0xfc, 0xfc, 0x08, 0x88, 0x94, 0x8a, 0x51, 0x15, 0xec, 0x9e, // IID732 + 0x62, 0x54, 0xfc, 0x0c, 0x88, 0x8a, 0x78, 0x2a, 0x58, 0xa3, // IID733 + 0x62, 0x9c, 0xf0, 0x10, 0xd3, 0xa4, 0x33, 0x2c, 0xda, 0x4c, 0x1b, // IID734 + 0x62, 0xd4, 0xb4, 0x14, 0xd3, 0xa4, 0x54, 0xce, 0x3b, 0x82, 0x62, // IID735 + 0x62, 0xd4, 0xb0, 0x18, 0xd3, 0xbc, 0x92, 0xb8, 0x85, 0xb5, 0xd9, // IID736 + 0x62, 0x94, 0xe0, 0x1c, 0xd3, 0xbc, 0x1e, 0x00, 0x1e, 0x29, 0x20, // IID737 + 0x62, 0x94, 0x9c, 0x18, 0xff, 0x8c, 0xb7, 0x45, 0x25, 0x08, 0xdf, // IID738 + 0x62, 0x94, 0xb0, 0x1c, 0xff, 0x8c, 0x4a, 0x84, 0x1d, 0x41, 0x21, // IID739 + 0x62, 0xb4, 0xd8, 0x10, 0xff, 0x84, 0xcb, 0x9e, 0x32, 0xf0, 0x02, // IID740 + 0x62, 0x94, 0xa8, 0x1c, 0xff, 0x84, 0x3c, 0x74, 0xa3, 0xaf, 0xc8, // IID741 + 0x62, 0xbc, 0xbc, 0x10, 0xd3, 0xac, 0xf7, 0x50, 0xa5, 0x18, 0x8e, // IID742 + 0x62, 0xbc, 0xb4, 0x14, 0xd3, 0xac, 0x53, 0x88, 0x0a, 0x7b, 0x50, // IID743 + 0x62, 0x64, 0xf8, 0x08, 0xf4, 0xbc, 0x03, 0x2a, 0x19, 0xd5, 0x19, // IID744 + 0x62, 0x3c, 0xf8, 0x0c, 0xf4, 0x8c, 0xa6, 0xcd, 0x07, 0x10, 0x21, // IID745 + 0x62, 0x6c, 0xfc, 0x10, 0x01, 0xa4, 0xdd, 0xe2, 0x05, 0xdc, 0xf7, // IID746 + 0x4e, 0x03, 0xbc, 0xc2, 0xa8, 0x5f, 0x46, 0xcb, // IID747 + 0x62, 0x14, 0xb8, 0x14, 0x01, 0xac, 0xc6, 0xd2, 0x59, 0xdc, 0x6c, // IID748 + 0x62, 0x9c, 0xe4, 0x1c, 0x01, 0x9c, 0xf3, 0xde, 0xe8, 0xc5, 0x36, // IID749 + 0x62, 0x0c, 0xd0, 0x10, 0x21, 0x9c, 0x5b, 0xed, 0xc4, 0xfd, 0xd3, // IID750 + 0xd5, 0x5e, 0x23, 0xbc, 0xbd, 0x4a, 0xc7, 0xf2, 0x6e, // IID751 + 0x62, 0x0c, 0x90, 0x1c, 0x21, 0x9c, 0x4f, 0xab, 0xe9, 0x4f, 0x73, // IID752 + 0x62, 0x14, 0x80, 0x1c, 0x21, 0xbc, 0xee, 0xaa, 0x7a, 0x19, 0xf9, // IID753 + 0x62, 0x0c, 0x9c, 0x18, 0x09, 0xa4, 0xfe, 0x9e, 0x3f, 0xa3, 0x3b, // IID754 + 0xd5, 0x4b, 0x0b, 0x84, 0x0c, 0xcd, 0xc4, 0x1f, 0xd7, // IID755 + 0x62, 0x04, 0xb8, 0x1c, 0x09, 0x9c, 0xc8, 0x6b, 0x42, 0xbd, 0xe1, // IID756 + 0x62, 0xdc, 0xf4, 0x1c, 0x09, 0x8c, 0x9b, 0xad, 0xbc, 0xe4, 0x7b, // IID757 + 0x62, 0xfc, 0xb8, 0x10, 0x29, 0x94, 0xb7, 0xd7, 0x27, 0x88, 0x6f, // IID758 + 0x62, 0xc4, 0xd4, 0x10, 0x29, 0xaa, 0x38, 0x47, 0xca, 0xf9, // IID759 + 0x62, 0x9c, 0xc0, 0x14, 0x29, 0x9c, 0xd3, 0xc0, 0xbc, 0x22, 0x09, // IID760 + 0x62, 0x2c, 0xb4, 0x14, 0x29, 0x8c, 0x3f, 0x54, 0x6b, 0x0b, 0xc7, // IID761 + 0x62, 0xd4, 0xa0, 0x18, 0x31, 0x8c, 0x9c, 0xe9, 0x13, 0x8e, 0xa4, // IID762 + 0xd5, 0x7c, 0x33, 0xa4, 0x13, 0x7e, 0x9b, 0x6b, 0x71, // IID763 + 0x62, 0xa4, 0xd0, 0x14, 0x31, 0x84, 0x29, 0xe2, 0xbb, 0x0f, 0xa5, // IID764 + 0x62, 0x3c, 0x98, 0x1c, 0x31, 0xa4, 0x14, 0xb1, 0x7f, 0x0b, 0x0e, // IID765 + 0x62, 0xf4, 0x8c, 0x10, 0x81, 0x81, 0x4f, 0x7b, 0x3b, 0x2d, 0x00, 0x00, 0x10, 0x00, // IID766 + 0x62, 0xbc, 0x8c, 0x1c, 0x81, 0x84, 0xbd, 0x18, 0x51, 0xdd, 0xed, 0x00, 0x10, 0x00, 0x00, // IID767 + 0x62, 0xbc, 0xc0, 0x10, 0x83, 0xa4, 0x3c, 0x96, 0xb2, 0x91, 0xf6, 0x10, // IID768 + 0x62, 0xf4, 0xac, 0x1c, 0x83, 0xa4, 0xd2, 0x7c, 0xf1, 0x75, 0x38, 0x01, // IID769 + 0x62, 0xa4, 0xf8, 0x08, 0x69, 0x8c, 0x89, 0x76, 0x10, 0xc7, 0x32, 0x00, 0x10, 0x00, 0x00, // IID770 + 0x62, 0xcc, 0xfc, 0x0c, 0x69, 0x9c, 0x9f, 0x0d, 0xa6, 0xad, 0x7b, 0x00, 0x00, 0x10, 0x00, // IID771 + 0x62, 0xfc, 0xb0, 0x10, 0x81, 0x8c, 0x7a, 0x44, 0x74, 0x14, 0x48, 0x00, 0x00, 0x00, 0x01, // IID772 + 0x62, 0x9c, 0x90, 0x14, 0x81, 0x8c, 0x5a, 0xa8, 0xc6, 0xee, 0xb4, 0x00, 0x00, 0x10, 0x00, // IID773 + 0x62, 0xfc, 0x84, 0x10, 0xc1, 0xa2, 0x8c, 0xc3, 0xef, 0xb9, 0x02, // IID774 + 0x62, 0x94, 0xb4, 0x14, 0xc1, 0xa4, 0x3a, 0xa4, 0x5d, 0x92, 0x48, 0x10, // IID775 + 0x62, 0xfc, 0xac, 0x10, 0xc1, 0xba, 0xbe, 0x3a, 0x5e, 0xa1, 0x08, // IID776 + 0x62, 0xd4, 0x98, 0x1c, 0xc1, 0xbc, 0xb2, 0x64, 0x82, 0x95, 0x5d, 0x08, // IID777 + 0x62, 0xfc, 0xe8, 0x18, 0xc1, 0xac, 0xa1, 0x23, 0xdd, 0x5a, 0x29, 0x10, // IID778 + 0x62, 0xbc, 0xe0, 0x1c, 0xc1, 0xac, 0x66, 0xcb, 0x29, 0x29, 0x78, 0x02, // IID779 + 0x62, 0xfc, 0xe4, 0x10, 0x83, 0xaf, 0x8e, 0xe2, 0x7e, 0xb6, 0x01, // IID780 + 0x62, 0xbc, 0xbc, 0x1c, 0x81, 0xac, 0xb3, 0x66, 0x51, 0xd4, 0xe4, 0x00, 0x00, 0x10, 0x00, // IID781 + 0x62, 0xb4, 0xe4, 0x10, 0x81, 0xb4, 0x11, 0xe9, 0x6e, 0xa6, 0x45, 0x00, 0x00, 0x10, 0x00, // IID782 + 0x62, 0x94, 0x98, 0x14, 0x83, 0xb4, 0x29, 0xec, 0x6c, 0x5e, 0xd7, 0x10, // IID783 + 0x62, 0xf4, 0xbc, 0x18, 0x81, 0xc1, 0x00, 0x00, 0x00, 0x01, // IID784 + 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xc6, 0x00, 0x00, 0x00, 0x01, // IID785 + 0xd5, 0x18, 0x81, 0xc0, 0x00, 0x01, 0x00, 0x00, // IID786 + 0x62, 0xd4, 0xbc, 0x14, 0x81, 0xc1, 0x00, 0x10, 0x00, 0x00, // IID787 + 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xc2, 0x00, 0x10, 0x00, 0x00, // IID788 + 0x62, 0xd4, 0xbc, 0x1c, 0x83, 0xc0, 0x01, // IID789 + 0x62, 0xfc, 0x84, 0x18, 0x81, 0xe6, 0x00, 0x00, 0x10, 0x00, // IID790 + 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xe2, 0x00, 0x00, 0x10, 0x00, // IID791 + 0x48, 0x81, 0xe2, 0x00, 0x10, 0x00, 0x00, // IID792 + 0x62, 0xfc, 0xec, 0x1c, 0x81, 0xe6, 0x00, 0x00, 0x00, 0x10, // IID793 + 0x62, 0xdc, 0xfc, 0x1c, 0x81, 0xe5, 0x00, 0x00, 0x00, 0x10, // IID794 + 0x62, 0xfc, 0xc4, 0x14, 0x81, 0xe7, 0x00, 0x00, 0x00, 0x01, // IID795 + 0x62, 0x54, 0xfc, 0x08, 0x69, 0xcd, 0x00, 0x00, 0x10, 0x00, // IID796 + 0x62, 0xfc, 0xfc, 0x08, 0x69, 0xc2, 0x00, 0x00, 0x10, 0x00, // IID797 + 0x62, 0xec, 0xfc, 0x08, 0x69, 0xc0, 0x00, 0x00, 0x10, 0x00, // IID798 + 0x62, 0xec, 0xfc, 0x0c, 0x6b, 0xcf, 0x01, // IID799 + 0x62, 0xd4, 0xfc, 0x0c, 0x6b, 0xc4, 0x01, // IID800 + 0x62, 0x54, 0xfc, 0x0c, 0x69, 0xd2, 0x00, 0x00, 0x00, 0x10, // IID801 + 0x62, 0xfc, 0xec, 0x18, 0x81, 0xcb, 0x00, 0x01, 0x00, 0x00, // IID802 + 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xce, 0x00, 0x01, 0x00, 0x00, // IID803 + 0x49, 0x83, 0xcd, 0x01, // IID804 + 0x62, 0xdc, 0xb4, 0x14, 0x81, 0xcd, 0x00, 0x01, 0x00, 0x00, // IID805 + 0x62, 0xf4, 0xfc, 0x1c, 0x81, 0xca, 0x00, 0x01, 0x00, 0x00, // IID806 + 0x62, 0xfc, 0xfc, 0x14, 0x83, 0xc8, 0x10, // IID807 + 0x62, 0xfc, 0x94, 0x18, 0xc1, 0xd3, 0x04, // IID808 + 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xd4, 0x04, // IID809 + 0x49, 0xc1, 0xd1, 0x04, // IID810 + 0x62, 0xfc, 0x94, 0x18, 0xd1, 0xc0, // IID811 + 0x62, 0xdc, 0xfc, 0x18, 0xd1, 0xc7, // IID812 + 0xd5, 0x19, 0xc1, 0xc6, 0x08, // IID813 + 0x62, 0xfc, 0x8c, 0x14, 0xc1, 0xc4, 0x08, // IID814 + 0x62, 0xdc, 0xfc, 0x1c, 0xc1, 0xc7, 0x08, // IID815 + 0x62, 0xdc, 0x84, 0x14, 0xc1, 0xc7, 0x04, // IID816 + 0x62, 0xd4, 0xcc, 0x10, 0xc1, 0xca, 0x04, // IID817 + 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xcd, 0x04, // IID818 + 0xd5, 0x19, 0xc1, 0xc8, 0x10, // IID819 + 0x62, 0xfc, 0x94, 0x14, 0xc1, 0xce, 0x10, // IID820 + 0x62, 0xfc, 0xfc, 0x1c, 0xc1, 0xcc, 0x10, // IID821 + 0x62, 0xdc, 0xa4, 0x14, 0xc1, 0xcb, 0x04, // IID822 + 0x62, 0xfc, 0x84, 0x10, 0xc1, 0xe3, 0x02, // IID823 + 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xe4, 0x02, // IID824 + 0x49, 0xc1, 0xe3, 0x08, // IID825 + 0x62, 0xd4, 0xec, 0x1c, 0xd1, 0xe7, // IID826 + 0x62, 0xd4, 0xfc, 0x1c, 0xd1, 0xe2, // IID827 + 0x62, 0xdc, 0x94, 0x14, 0xc1, 0xe5, 0x04, // IID828 + 0x62, 0xfc, 0xdc, 0x10, 0xd1, 0xf8, // IID829 + 0x62, 0xfc, 0xfc, 0x18, 0xd1, 0xfd, // IID830 + 0xd5, 0x19, 0xc1, 0xfc, 0x08, // IID831 + 0x62, 0xf4, 0x8c, 0x14, 0xc1, 0xf9, 0x04, // IID832 + 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xff, 0x04, // IID833 + 0x62, 0xf4, 0xf4, 0x1c, 0xc1, 0xf9, 0x04, // IID834 + 0x62, 0xdc, 0xec, 0x18, 0xc1, 0xe2, 0x04, // IID835 + 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xe2, 0x04, // IID836 + 0x49, 0xc1, 0xe0, 0x04, // IID837 + 0x62, 0xf4, 0xf4, 0x1c, 0xd1, 0xe1, // IID838 + 0x62, 0xf4, 0xfc, 0x1c, 0xd1, 0xe1, // IID839 + 0x62, 0xd4, 0x94, 0x1c, 0xc1, 0xe5, 0x02, // IID840 + 0x62, 0xdc, 0x8c, 0x18, 0xc1, 0xeb, 0x02, // IID841 + 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xeb, 0x02, // IID842 + 0x49, 0xc1, 0xe9, 0x10, // IID843 + 0x62, 0xdc, 0xec, 0x1c, 0xc1, 0xef, 0x02, // IID844 + 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xee, 0x02, // IID845 + 0x62, 0xd4, 0x9c, 0x1c, 0xc1, 0xec, 0x08, // IID846 + 0x62, 0xdc, 0xac, 0x18, 0x83, 0xec, 0x01, // IID847 + 0x62, 0xd4, 0xfc, 0x18, 0x83, 0xe8, 0x01, // IID848 + 0x48, 0x81, 0xe9, 0x00, 0x00, 0x00, 0x01, // IID849 + 0x62, 0xf4, 0xec, 0x1c, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x01, // IID850 + 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xea, 0x00, 0x00, 0x00, 0x01, // IID851 + 0x62, 0xdc, 0xa4, 0x14, 0x81, 0xeb, 0x00, 0x00, 0x01, 0x00, // IID852 + 0x62, 0xf4, 0x8c, 0x10, 0x81, 0xf1, 0x00, 0x10, 0x00, 0x00, // IID853 + 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xf5, 0x00, 0x10, 0x00, 0x00, // IID854 + 0x48, 0x81, 0xf1, 0x00, 0x00, 0x00, 0x01, // IID855 + 0x62, 0xd4, 0xd4, 0x14, 0x83, 0xf4, 0x01, // IID856 + 0x62, 0xf4, 0xfc, 0x1c, 0x83, 0xf2, 0x01, // IID857 + 0x62, 0xf4, 0xe4, 0x1c, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x01, // IID858 + 0x62, 0xf4, 0xa4, 0x18, 0x81, 0xca, 0x00, 0x00, 0x01, 0x00, // IID859 + 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xce, 0x00, 0x00, 0x01, 0x00, // IID860 + 0x49, 0x81, 0xce, 0x00, 0x00, 0x04, 0x00, // IID861 + 0x62, 0xdc, 0xb4, 0x10, 0x81, 0xcd, 0x00, 0x00, 0x04, 0x00, // IID862 + 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xcd, 0x00, 0x00, 0x04, 0x00, // IID863 + 0x49, 0x81, 0xcb, 0x00, 0x00, 0x00, 0x01, // IID864 + 0x62, 0xfc, 0x94, 0x10, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x04, // IID865 + 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x04, // IID866 + 0xd5, 0x18, 0x81, 0xea, 0x00, 0x00, 0x00, 0x04, // IID867 + 0x62, 0xfc, 0x9c, 0x14, 0x81, 0xef, 0x00, 0x00, 0x40, 0x00, // IID868 + 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xed, 0x00, 0x00, 0x40, 0x00, // IID869 + 0x62, 0xfc, 0xfc, 0x14, 0x81, 0xe8, 0x00, 0x00, 0x00, 0x01, // IID870 + 0x62, 0x0c, 0xbc, 0x18, 0x03, 0x8c, 0x42, 0xef, 0x3d, 0x63, 0x10, // IID871 + 0xd5, 0x3c, 0x03, 0xac, 0x42, 0xf8, 0xba, 0xdf, 0x8b, // IID872 + 0x62, 0x44, 0xf4, 0x14, 0x03, 0x94, 0x24, 0xbf, 0x0a, 0xa8, 0x23, // IID873 + 0x62, 0x5c, 0xb0, 0x1c, 0x03, 0x8c, 0x1d, 0xae, 0x61, 0x61, 0xfd, // IID874 + 0x62, 0x24, 0xb0, 0x18, 0x23, 0xa4, 0x89, 0xaa, 0xff, 0x61, 0x42, // IID875 + 0xd5, 0x6e, 0x23, 0x9c, 0x22, 0x3f, 0x36, 0x42, 0xd9, // IID876 + 0x62, 0x7c, 0x8c, 0x1c, 0x23, 0x98, 0xdf, 0x0d, 0xba, 0x63, // IID877 + 0x62, 0x3c, 0xb8, 0x1c, 0x23, 0x84, 0x4e, 0xbc, 0x54, 0x49, 0xbc, // IID878 + 0x62, 0xdc, 0xe4, 0x10, 0x0b, 0x8c, 0x8b, 0x3a, 0x80, 0x97, 0x80, // IID879 + 0xd5, 0x6a, 0x0b, 0x9c, 0x53, 0x16, 0x48, 0x92, 0xb7, // IID880 + 0x62, 0x54, 0x88, 0x14, 0x0b, 0x94, 0xd6, 0x84, 0x48, 0x88, 0x14, // IID881 + 0x62, 0x4c, 0xa4, 0x14, 0x0b, 0x9d, 0x80, 0x71, 0x33, 0x20, // IID882 + 0x62, 0xec, 0xf4, 0x18, 0xaf, 0xac, 0x1d, 0x72, 0x77, 0xfc, 0xcc, // IID883 + 0xd5, 0x9b, 0xaf, 0x94, 0xcc, 0xbf, 0x08, 0x27, 0x85, // IID884 + 0x62, 0x2c, 0xbc, 0x1c, 0xaf, 0xac, 0x21, 0x6a, 0x39, 0x85, 0x6e, // IID885 + 0x62, 0xac, 0xfc, 0x14, 0xaf, 0x84, 0xd3, 0x00, 0x6d, 0xa6, 0xb6, // IID886 + 0x62, 0xc4, 0xd8, 0x10, 0x2b, 0x8c, 0x35, 0x4f, 0x9a, 0x21, 0x1d, // IID887 + 0xd5, 0x7c, 0x2b, 0x8c, 0xed, 0x39, 0x57, 0x97, 0x97, // IID888 + 0x62, 0x64, 0xd8, 0x14, 0x2b, 0x84, 0xa3, 0xa6, 0x9d, 0xc5, 0x32, // IID889 + 0x62, 0x54, 0xb8, 0x1c, 0x2b, 0x84, 0x0c, 0x31, 0xd2, 0x41, 0xd9, // IID890 + 0x62, 0xc4, 0xec, 0x18, 0x33, 0x99, 0x91, 0x3b, 0x90, 0x7d, // IID891 + 0xd5, 0x7f, 0x33, 0xa4, 0x9d, 0x6f, 0x1f, 0x09, 0x53, // IID892 + 0x62, 0xcc, 0xf4, 0x14, 0x33, 0x83, 0x07, 0x92, 0x6e, 0x7c, // IID893 + 0x62, 0x14, 0x80, 0x1c, 0x33, 0xbc, 0xc5, 0xa0, 0x86, 0x37, 0x8a, // IID894 + 0x62, 0xfc, 0xfc, 0x10, 0x03, 0xda, // IID895 + 0xd5, 0x5c, 0x03, 0xc2, // IID896 + 0x4d, 0x03, 0xcf, // IID897 + 0x62, 0x44, 0xe4, 0x14, 0x03, 0xd5, // IID898 + 0x62, 0x6c, 0x9c, 0x14, 0x03, 0xe6, // IID899 + 0x62, 0x7c, 0xcc, 0x14, 0x03, 0xde, // IID900 + 0x62, 0x54, 0xf5, 0x18, 0x66, 0xe5, // IID901 + 0x62, 0x44, 0xfd, 0x08, 0x66, 0xf4, // IID902 + 0x62, 0x7c, 0x9e, 0x10, 0x66, 0xf2, // IID903 + 0x62, 0x6c, 0xfe, 0x08, 0x66, 0xf3, // IID904 + 0x62, 0x54, 0xdc, 0x10, 0x23, 0xf6, // IID905 + 0xd5, 0x58, 0x23, 0xcf, // IID906 + 0xd5, 0x49, 0x23, 0xce, // IID907 + 0x62, 0xc4, 0xe4, 0x14, 0x23, 0xe7, // IID908 + 0x62, 0xd4, 0xe4, 0x1c, 0x23, 0xdd, // IID909 + 0x62, 0x6c, 0xcc, 0x14, 0x23, 0xf6, // IID910 + 0x62, 0x64, 0xf4, 0x10, 0xaf, 0xc1, // IID911 + 0xd5, 0xc9, 0xaf, 0xe8, // IID912 + 0xd5, 0xdc, 0xaf, 0xed, // IID913 + 0x62, 0x7c, 0xa4, 0x14, 0xaf, 0xef, // IID914 + 0x62, 0x44, 0xac, 0x14, 0xaf, 0xd0, // IID915 + 0x62, 0x7c, 0xcc, 0x14, 0xaf, 0xee, // IID916 + 0x62, 0xdc, 0xa4, 0x18, 0x0b, 0xd5, // IID917 + 0xd5, 0x19, 0x0b, 0xd7, // IID918 + 0xd5, 0x1d, 0x0b, 0xd5, // IID919 + 0x62, 0x64, 0xa4, 0x14, 0x0b, 0xe1, // IID920 + 0x62, 0x44, 0xb4, 0x14, 0x0b, 0xc9, // IID921 + 0x62, 0x74, 0xf4, 0x1c, 0x0b, 0xc1, // IID922 + 0x62, 0x7c, 0xf4, 0x18, 0x2b, 0xd0, // IID923 + 0xd5, 0x48, 0x2b, 0xc9, // IID924 + 0x62, 0xcc, 0x94, 0x1c, 0x2b, 0xe8, // IID925 + 0x62, 0x4c, 0x84, 0x14, 0x2b, 0xfc, // IID926 + 0xd5, 0x59, 0x33, 0xfc, // IID927 + 0x4d, 0x33, 0xd3, // IID928 + 0xd5, 0x58, 0x33, 0xda, // IID929 + 0x62, 0x74, 0x84, 0x14, 0x33, 0xca, // IID930 + 0x62, 0x54, 0x94, 0x1c, 0x33, 0xe9, // IID931 + 0x62, 0x74, 0xf4, 0x1c, 0x33, 0xd1, // IID932 + 0x62, 0xcc, 0x9c, 0x18, 0x24, 0xf0, 0x08, // IID933 + 0xd5, 0xdd, 0xa4, 0xc9, 0x08, // IID934 + 0x62, 0x7c, 0xd4, 0x14, 0x24, 0xfc, 0x08, // IID935 + 0x62, 0x7c, 0xd4, 0x14, 0x24, 0xd5, 0x08, // IID936 + 0xd5, 0x9c, 0xac, 0xc2, 0x02, // IID937 + 0xd5, 0xdd, 0xac, 0xea, 0x08, // IID938 + 0x62, 0xcc, 0x94, 0x14, 0x2c, 0xda, 0x02, // IID939 + 0x62, 0xd4, 0x9c, 0x1c, 0x2c, 0xcc, 0x04, // IID940 + 0x62, 0xec, 0xd4, 0x10, 0x40, 0xf7, // IID941 + 0x4d, 0x0f, 0x40, 0xcd, // IID942 + 0x62, 0xcc, 0xf4, 0x18, 0x41, 0xf8, // IID943 + 0xd5, 0xcc, 0x41, 0xe2, // IID944 + 0x62, 0x6c, 0x8c, 0x18, 0x42, 0xff, // IID945 + 0xd5, 0xdc, 0x42, 0xf7, // IID946 + 0x62, 0x6c, 0xac, 0x18, 0x43, 0xee, // IID947 + 0xd5, 0x99, 0x43, 0xda, // IID948 + 0x62, 0xc4, 0xc4, 0x10, 0x44, 0xed, // IID949 + 0xd5, 0x9c, 0x44, 0xd4, // IID950 + 0x62, 0x5c, 0xe4, 0x18, 0x45, 0xcd, // IID951 + 0xd5, 0xd9, 0x45, 0xc6, // IID952 + 0x62, 0xdc, 0x94, 0x18, 0x46, 0xcd, // IID953 + 0xd5, 0xcd, 0x46, 0xfd, // IID954 + 0x62, 0x5c, 0xa4, 0x10, 0x47, 0xce, // IID955 + 0xd5, 0xdc, 0x47, 0xd4, // IID956 + 0x62, 0x7c, 0xbc, 0x18, 0x48, 0xe6, // IID957 + 0xd5, 0xdc, 0x48, 0xf9, // IID958 + 0x62, 0xdc, 0x94, 0x10, 0x49, 0xc9, // IID959 + 0xd5, 0xc9, 0x49, 0xf6, // IID960 + 0x62, 0x44, 0xf4, 0x18, 0x4a, 0xd9, // IID961 + 0xd5, 0xc9, 0x4a, 0xf3, // IID962 + 0x62, 0xcc, 0x8c, 0x18, 0x4b, 0xd8, // IID963 + 0xd5, 0xdc, 0x4b, 0xc1, // IID964 + 0x62, 0xcc, 0xf4, 0x10, 0x4c, 0xde, // IID965 + 0xd5, 0xc9, 0x4c, 0xde, // IID966 + 0x62, 0x5c, 0xb4, 0x10, 0x4d, 0xdd, // IID967 + 0xd5, 0x9d, 0x4d, 0xe2, // IID968 + 0x62, 0xd4, 0xa4, 0x18, 0x4e, 0xda, // IID969 + 0xd5, 0x98, 0x4e, 0xd6, // IID970 + 0x62, 0x7c, 0x8c, 0x18, 0x4f, 0xff, // IID971 + 0xd5, 0x9d, 0x4f, 0xc0, // IID972 + 0x62, 0x04, 0xe4, 0x18, 0x40, 0xbc, 0xc2, 0x20, 0x9f, 0xc0, 0xce, // IID973 + 0xd5, 0xea, 0x40, 0xbc, 0x81, 0x9c, 0x1d, 0xf4, 0x17, // IID974 + 0x62, 0x7c, 0x84, 0x10, 0x41, 0x98, 0x42, 0x89, 0x01, 0x2c, // IID975 + 0xd5, 0xbc, 0x41, 0x9c, 0xe0, 0x55, 0x6a, 0x4b, 0x67, // IID976 + 0x62, 0x54, 0xb4, 0x18, 0x42, 0xac, 0x09, 0xdf, 0x11, 0x4a, 0x39, // IID977 + 0xd5, 0xec, 0x42, 0xb4, 0x72, 0x78, 0xd4, 0xc9, 0x93, // IID978 + 0x62, 0xdc, 0x94, 0x18, 0x43, 0x8c, 0xc8, 0x66, 0x0b, 0x50, 0x46, // IID979 + 0xd5, 0xfe, 0x43, 0x84, 0x4a, 0x7c, 0x3b, 0x28, 0x53, // IID980 + 0x62, 0x04, 0xc4, 0x10, 0x44, 0x8c, 0x0f, 0xe2, 0xfc, 0xfc, 0xa0, // IID981 + 0xd5, 0xfd, 0x44, 0x8c, 0x44, 0xec, 0x0a, 0x31, 0xac, // IID982 + 0x62, 0x0c, 0xe0, 0x18, 0x45, 0x8c, 0x88, 0x79, 0x53, 0x35, 0x99, // IID983 + 0xd5, 0xfb, 0x45, 0x84, 0xf3, 0x5d, 0x45, 0x7f, 0x79, // IID984 + 0x62, 0x6c, 0xb0, 0x10, 0x46, 0xb4, 0x52, 0xcd, 0xaa, 0x9d, 0x1c, // IID985 + 0xd5, 0xea, 0x46, 0xb4, 0x49, 0x57, 0x05, 0x34, 0xc2, // IID986 + 0x62, 0x4c, 0xbc, 0x10, 0x47, 0x91, 0xb5, 0x60, 0x70, 0x74, // IID987 + 0xd5, 0xbd, 0x47, 0x84, 0xe0, 0xf6, 0x85, 0xd2, 0x47, // IID988 + 0x62, 0x84, 0x9c, 0x18, 0x48, 0x84, 0x95, 0x14, 0xb2, 0xe5, 0x34, // IID989 + 0xd5, 0xa9, 0x48, 0x94, 0x1f, 0x4f, 0xc7, 0xae, 0xbf, // IID990 + 0x62, 0xa4, 0xec, 0x10, 0x49, 0xac, 0xab, 0x97, 0x91, 0xb1, 0x51, // IID991 + 0xd5, 0xef, 0x49, 0x84, 0xfb, 0x0a, 0x52, 0x01, 0x3e, // IID992 + 0x62, 0x04, 0x90, 0x10, 0x4a, 0x94, 0xca, 0x8e, 0xc7, 0x83, 0xa0, // IID993 + 0xd5, 0x9e, 0x4a, 0x9c, 0xd6, 0xad, 0xeb, 0x8c, 0x97, // IID994 + 0x62, 0x14, 0xd8, 0x10, 0x4b, 0xbc, 0x09, 0xaa, 0xed, 0x37, 0x4a, // IID995 + 0xd5, 0xed, 0x4b, 0xbc, 0x21, 0x86, 0x9f, 0x99, 0x4f, // IID996 + 0x62, 0x84, 0xe8, 0x10, 0x4c, 0xbc, 0x19, 0xe3, 0xbb, 0xef, 0xcb, // IID997 + 0xd5, 0xdb, 0x4c, 0x84, 0xd0, 0xee, 0x66, 0xed, 0x52, // IID998 + 0x62, 0xe4, 0xa4, 0x18, 0x4d, 0x91, 0x63, 0x91, 0xe0, 0x1d, // IID999 + 0xd5, 0xbd, 0x4d, 0xb4, 0x78, 0xda, 0xb4, 0xf3, 0x5d, // IID1000 + 0x62, 0x5c, 0x80, 0x18, 0x4e, 0xb4, 0x66, 0x76, 0xb9, 0x9a, 0x5c, // IID1001 + 0xd5, 0xfe, 0x4e, 0x94, 0x9a, 0xd7, 0x3c, 0x27, 0xff, // IID1002 + 0x62, 0x5c, 0x90, 0x10, 0x4f, 0x8c, 0xe6, 0x73, 0x30, 0x56, 0xc8, // IID1003 + 0xd5, 0xc9, 0x4f, 0xa4, 0x58, 0xef, 0x7d, 0xdc, 0x1b, // IID1004 #endif // _LP64 }; @@ -2196,19 +2364,19 @@ 15, // IID265 15, // IID266 11, // IID267 - 11, // IID268 + 9, // IID268 11, // IID269 11, // IID270 11, // IID271 - 11, // IID272 + 9, // IID272 11, // IID273 10, // IID274 11, // IID275 - 11, // IID276 + 9, // IID276 11, // IID277 11, // IID278 11, // IID279 - 11, // IID280 + 9, // IID280 10, // IID281 11, // IID282 10, // IID283 @@ -2216,645 +2384,729 @@ 11, // IID285 10, // IID286 11, // IID287 - 10, // IID288 + 8, // IID288 11, // IID289 11, // IID290 - 10, // IID291 - 10, // IID292 - 8, // IID293 - 7, // IID294 + 11, // IID291 + 9, // IID292 + 11, // IID293 + 11, // IID294 7, // IID295 - 10, // IID296 - 10, // IID297 + 7, // IID296 + 8, // IID297 10, // IID298 - 8, // IID299 + 10, // IID299 10, // IID300 - 10, // IID301 + 4, // IID301 7, // IID302 - 10, // IID303 -#endif // _LP64 - 10, // IID304 -#ifdef _LP64 - 10, // IID305 - 10, // IID306 + 5, // IID303 + 7, // IID304 + 7, // IID305 + 7, // IID306 10, // IID307 - 7, // IID308 + 10, // IID308 10, // IID309 - 10, // IID310 - 8, // IID311 - 7, // IID312 + 7, // IID310 + 7, // IID311 + 10, // IID312 7, // IID313 - 10, // IID314 - 6, // IID315 - 6, // IID316 - 4, // IID317 - 7, // IID318 + 7, // IID314 + 8, // IID315 + 7, // IID316 + 7, // IID317 #endif // _LP64 - 7, // IID319 + 10, // IID318 #ifdef _LP64 - 5, // IID320 - 7, // IID321 + 5, // IID319 + 7, // IID320 + 5, // IID321 7, // IID322 7, // IID323 - 7, // IID324 -#endif // _LP64 + 4, // IID324 7, // IID325 -#ifdef _LP64 - 4, // IID326 - 7, // IID327 + 7, // IID326 + 6, // IID327 7, // IID328 7, // IID329 - 7, // IID330 + 5, // IID330 7, // IID331 - 5, // IID332 + 7, // IID332 7, // IID333 7, // IID334 7, // IID335 - 7, // IID336 + 5, // IID336 7, // IID337 - 4, // IID338 + 7, // IID338 7, // IID339 - 7, // IID340 - 7, // IID341 - 7, // IID342 + 6, // IID340 + 6, // IID341 + 5, // IID342 7, // IID343 - 4, // IID344 + 7, // IID344 7, // IID345 7, // IID346 7, // IID347 - 7, // IID348 + 4, // IID348 7, // IID349 - 5, // IID350 + 7, // IID350 6, // IID351 - 6, // IID352 + 7, // IID352 7, // IID353 - 10, // IID354 - 10, // IID355 - 8, // IID356 - 10, // IID357 + 5, // IID354 + 7, // IID355 + 7, // IID356 + 7, // IID357 10, // IID358 10, // IID359 - 10, // IID360 + 8, // IID360 10, // IID361 -#endif // _LP64 - 6, // IID362 -#ifdef _LP64 - 10, // IID363 + 10, // IID362 + 7, // IID363 10, // IID364 10, // IID365 - 10, // IID366 - 10, // IID367 - 8, // IID368 - 10, // IID369 + 5, // IID366 + 7, // IID367 +#endif // _LP64 + 7, // IID368 +#ifdef _LP64 + 7, // IID369 10, // IID370 10, // IID371 - 10, // IID372 + 8, // IID372 10, // IID373 - 11, // IID374 - 11, // IID375 + 10, // IID374 + 10, // IID375 11, // IID376 - 11, // IID377 + 9, // IID377 11, // IID378 10, // IID379 11, // IID380 - 11, // IID381 + 9, // IID381 11, // IID382 11, // IID383 11, // IID384 - 11, // IID385 + 9, // IID385 11, // IID386 11, // IID387 - 6, // IID388 - 4, // IID389 - 6, // IID390 - 6, // IID391 - 6, // IID392 - 3, // IID393 - 6, // IID394 - 6, // IID395 - 6, // IID396 - 4, // IID397 - 6, // IID398 - 6, // IID399 - 6, // IID400 - 5, // IID401 - 6, // IID402 - 6, // IID403 - 6, // IID404 - 4, // IID405 - 6, // IID406 - 6, // IID407 + 10, // IID388 + 8, // IID389 + 11, // IID390 + 11, // IID391 + 11, // IID392 + 9, // IID393 + 10, // IID394 + 11, // IID395 + 11, // IID396 + 9, // IID397 + 11, // IID398 + 11, // IID399 + 11, // IID400 + 9, // IID401 + 11, // IID402 + 11, // IID403 + 11, // IID404 + 10, // IID405 + 10, // IID406 + 11, // IID407 6, // IID408 4, // IID409 - 6, // IID410 + 4, // IID410 6, // IID411 6, // IID412 - 4, // IID413 + 6, // IID413 6, // IID414 - 6, // IID415 - 6, // IID416 - 4, // IID417 + 4, // IID415 + 3, // IID416 + 6, // IID417 6, // IID418 6, // IID419 6, // IID420 4, // IID421 - 6, // IID422 + 4, // IID422 6, // IID423 - 7, // IID424 - 5, // IID425 - 7, // IID426 - 7, // IID427 - 7, // IID428 - 5, // IID429 - 7, // IID430 - 7, // IID431 + 6, // IID424 + 6, // IID425 + 6, // IID426 + 5, // IID427 + 4, // IID428 + 6, // IID429 + 6, // IID430 +#endif // _LP64 + 6, // IID431 +#ifdef _LP64 6, // IID432 4, // IID433 - 6, // IID434 - 4, // IID435 + 4, // IID434 + 6, // IID435 6, // IID436 - 4, // IID437 + 6, // IID437 6, // IID438 4, // IID439 6, // IID440 - 4, // IID441 + 6, // IID441 6, // IID442 4, // IID443 6, // IID444 - 4, // IID445 + 6, // IID445 6, // IID446 - 4, // IID447 + 3, // IID447 6, // IID448 - 4, // IID449 + 6, // IID449 6, // IID450 4, // IID451 4, // IID452 - 4, // IID453 + 6, // IID453 6, // IID454 - 4, // IID455 - 6, // IID456 - 4, // IID457 - 6, // IID458 - 4, // IID459 - 6, // IID460 - 4, // IID461 - 6, // IID462 - 4, // IID463 - 10, // IID464 - 11, // IID465 - 11, // IID466 - 11, // IID467 - 10, // IID468 - 11, // IID469 - 11, // IID470 - 11, // IID471 - 11, // IID472 - 11, // IID473 - 11, // IID474 - 11, // IID475 - 11, // IID476 - 11, // IID477 - 11, // IID478 - 11, // IID479 - 4, // IID480 + 6, // IID455 + 7, // IID456 + 5, // IID457 + 7, // IID458 + 7, // IID459 + 7, // IID460 + 5, // IID461 + 7, // IID462 + 7, // IID463 + 6, // IID464 + 4, // IID465 + 6, // IID466 + 4, // IID467 + 6, // IID468 + 4, // IID469 + 6, // IID470 + 4, // IID471 + 6, // IID472 + 4, // IID473 + 6, // IID474 + 4, // IID475 + 6, // IID476 + 4, // IID477 + 6, // IID478 + 4, // IID479 + 6, // IID480 4, // IID481 - 4, // IID482 - 5, // IID483 - 4, // IID484 + 6, // IID482 + 4, // IID483 + 6, // IID484 4, // IID485 - 5, // IID486 - 5, // IID487 - 4, // IID488 + 6, // IID486 + 4, // IID487 + 6, // IID488 4, // IID489 - 4, // IID490 - 3, // IID491 - 4, // IID492 + 6, // IID490 + 4, // IID491 + 6, // IID492 4, // IID493 - 4, // IID494 + 6, // IID494 4, // IID495 - 4, // IID496 - 4, // IID497 - 9, // IID498 + 11, // IID496 + 9, // IID497 + 11, // IID498 9, // IID499 - 9, // IID500 + 11, // IID500 9, // IID501 - 9, // IID502 - 9, // IID503 - 9, // IID504 + 11, // IID502 + 8, // IID503 + 11, // IID504 9, // IID505 - 12, // IID506 - 12, // IID507 + 11, // IID506 + 8, // IID507 11, // IID508 - 8, // IID509 - 9, // IID510 - 13, // IID511 - 10, // IID512 - 12, // IID513 - 10, // IID514 - 10, // IID515 - 13, // IID516 - 12, // IID517 - 9, // IID518 + 9, // IID509 + 10, // IID510 + 9, // IID511 + 11, // IID512 + 9, // IID513 + 9, // IID514 + 9, // IID515 + 11, // IID516 + 9, // IID517 + 11, // IID518 9, // IID519 - 9, // IID520 + 11, // IID520 9, // IID521 - 9, // IID522 - 7, // IID523 - 9, // IID524 + 10, // IID522 + 9, // IID523 + 10, // IID524 9, // IID525 - 9, // IID526 + 11, // IID526 9, // IID527 - 10, // IID528 - 9, // IID529 - 9, // IID530 - 7, // IID531 - 10, // IID532 - 9, // IID533 - 9, // IID534 + 4, // IID528 + 3, // IID529 + 4, // IID530 + 5, // IID531 + 3, // IID532 + 4, // IID533 + 5, // IID534 5, // IID535 - 5, // IID536 - 8, // IID537 - 8, // IID538 + 4, // IID536 + 3, // IID537 + 4, // IID538 4, // IID539 4, // IID540 - 5, // IID541 - 5, // IID542 + 4, // IID541 + 4, // IID542 4, // IID543 4, // IID544 - 7, // IID545 - 4, // IID546 - 3, // IID547 - 4, // IID548 + 4, // IID545 + 8, // IID546 + 9, // IID547 + 9, // IID548 8, // IID549 8, // IID550 - 10, // IID551 - 5, // IID552 - 8, // IID553 - 8, // IID554 - 7, // IID555 - 9, // IID556 - 8, // IID557 - 9, // IID558 - 9, // IID559 - 9, // IID560 - 9, // IID561 - 8, // IID562 - 9, // IID563 - 9, // IID564 - 9, // IID565 + 9, // IID551 + 9, // IID552 + 9, // IID553 + 13, // IID554 + 13, // IID555 + 11, // IID556 + 10, // IID557 + 10, // IID558 + 13, // IID559 + 10, // IID560 + 13, // IID561 + 10, // IID562 + 13, // IID563 + 11, // IID564 + 13, // IID565 9, // IID566 9, // IID567 9, // IID568 9, // IID569 9, // IID570 9, // IID571 - 4, // IID572 - 4, // IID573 - 4, // IID574 - 3, // IID575 - 3, // IID576 - 4, // IID577 - 4, // IID578 - 3, // IID579 - 4, // IID580 - 3, // IID581 - 4, // IID582 - 4, // IID583 - 4, // IID584 - 3, // IID585 - 3, // IID586 - 3, // IID587 + 9, // IID572 + 9, // IID573 + 8, // IID574 + 9, // IID575 + 10, // IID576 + 9, // IID577 + 9, // IID578 + 9, // IID579 + 10, // IID580 + 9, // IID581 + 9, // IID582 + 8, // IID583 + 5, // IID584 + 8, // IID585 + 7, // IID586 + 4, // IID587 3, // IID588 - 9, // IID589 - 9, // IID590 - 9, // IID591 - 9, // IID592 - 9, // IID593 - 9, // IID594 - 9, // IID595 - 9, // IID596 - 13, // IID597 + 5, // IID589 + 4, // IID590 + 4, // IID591 + 5, // IID592 + 7, // IID593 + 5, // IID594 + 5, // IID595 + 7, // IID596 + 7, // IID597 8, // IID598 - 5, // IID599 + 11, // IID599 5, // IID600 - 6, // IID601 - 6, // IID602 - 6, // IID603 - 6, // IID604 + 8, // IID601 + 8, // IID602 + 8, // IID603 + 9, // IID604 9, // IID605 9, // IID606 9, // IID607 9, // IID608 - 4, // IID609 - 4, // IID610 - 4, // IID611 - 4, // IID612 + 8, // IID609 + 9, // IID610 + 9, // IID611 + 9, // IID612 9, // IID613 - 6, // IID614 - 6, // IID615 - 6, // IID616 - 6, // IID617 - 6, // IID618 - 6, // IID619 - 6, // IID620 - 6, // IID621 - 11, // IID622 - 11, // IID623 - 6, // IID624 - 4, // IID625 - 6, // IID626 - 6, // IID627 - 6, // IID628 - 6, // IID629 - 6, // IID630 - 6, // IID631 - 6, // IID632 + 9, // IID614 + 9, // IID615 + 9, // IID616 + 8, // IID617 + 9, // IID618 + 9, // IID619 + 4, // IID620 + 3, // IID621 + 4, // IID622 + 3, // IID623 + 4, // IID624 + 3, // IID625 + 3, // IID626 + 4, // IID627 + 4, // IID628 + 3, // IID629 + 4, // IID630 + 4, // IID631 + 4, // IID632 4, // IID633 - 6, // IID634 - 6, // IID635 - 6, // IID636 - 4, // IID637 - 6, // IID638 - 6, // IID639 - 6, // IID640 - 6, // IID641 - 6, // IID642 - 4, // IID643 - 6, // IID644 - 6, // IID645 - 6, // IID646 - 4, // IID647 - 6, // IID648 + 3, // IID634 + 3, // IID635 + 3, // IID636 + 9, // IID637 + 8, // IID638 + 9, // IID639 + 8, // IID640 + 9, // IID641 + 8, // IID642 + 7, // IID643 + 9, // IID644 + 13, // IID645 + 8, // IID646 + 5, // IID647 + 5, // IID648 6, // IID649 6, // IID650 - 3, // IID651 + 6, // IID651 6, // IID652 - 6, // IID653 - 6, // IID654 - 3, // IID655 - 6, // IID656 - 6, // IID657 - 6, // IID658 - 3, // IID659 - 6, // IID660 - 6, // IID661 - 4, // IID662 - 4, // IID663 + 9, // IID653 + 9, // IID654 + 8, // IID655 + 9, // IID656 + 4, // IID657 + 4, // IID658 + 4, // IID659 + 4, // IID660 + 9, // IID661 + 6, // IID662 + 6, // IID663 6, // IID664 6, // IID665 6, // IID666 - 3, // IID667 + 6, // IID667 6, // IID668 6, // IID669 - 6, // IID670 - 4, // IID671 + 11, // IID670 + 11, // IID671 6, // IID672 - 6, // IID673 + 4, // IID673 6, // IID674 6, // IID675 6, // IID676 6, // IID677 - 10, // IID678 - 10, // IID679 - 11, // IID680 - 11, // IID681 - 11, // IID682 - 11, // IID683 - 11, // IID684 - 10, // IID685 - 10, // IID686 - 11, // IID687 - 11, // IID688 - 11, // IID689 - 11, // IID690 - 11, // IID691 - 11, // IID692 - 11, // IID693 - 11, // IID694 - 10, // IID695 - 11, // IID696 - 11, // IID697 - 10, // IID698 - 11, // IID699 - 11, // IID700 - 10, // IID701 - 11, // IID702 - 11, // IID703 - 11, // IID704 - 10, // IID705 - 11, // IID706 - 11, // IID707 - 11, // IID708 - 11, // IID709 - 11, // IID710 - 11, // IID711 - 11, // IID712 - 11, // IID713 - 10, // IID714 - 11, // IID715 - 11, // IID716 - 10, // IID717 - 15, // IID718 - 12, // IID719 - 12, // IID720 - 15, // IID721 - 15, // IID722 - 12, // IID723 - 12, // IID724 - 15, // IID725 - 12, // IID726 - 12, // IID727 - 12, // IID728 - 11, // IID729 - 12, // IID730 - 12, // IID731 - 14, // IID732 - 15, // IID733 - 15, // IID734 - 12, // IID735 - 7, // IID736 - 7, // IID737 - 8, // IID738 - 10, // IID739 - 10, // IID740 - 10, // IID741 - 10, // IID742 - 10, // IID743 - 8, // IID744 - 10, // IID745 - 10, // IID746 - 10, // IID747 - 10, // IID748 - 10, // IID749 - 10, // IID750 - 10, // IID751 - 10, // IID752 - 10, // IID753 - 10, // IID754 - 10, // IID755 - 8, // IID756 - 10, // IID757 - 10, // IID758 + 6, // IID678 + 6, // IID679 + 6, // IID680 + 4, // IID681 + 6, // IID682 + 6, // IID683 + 6, // IID684 + 4, // IID685 + 6, // IID686 + 6, // IID687 + 6, // IID688 + 6, // IID689 + 6, // IID690 + 4, // IID691 + 6, // IID692 + 6, // IID693 + 6, // IID694 + 3, // IID695 + 6, // IID696 + 6, // IID697 + 6, // IID698 + 4, // IID699 + 6, // IID700 + 6, // IID701 + 6, // IID702 + 4, // IID703 + 6, // IID704 + 6, // IID705 + 6, // IID706 + 3, // IID707 + 6, // IID708 + 6, // IID709 + 6, // IID710 + 4, // IID711 + 6, // IID712 + 6, // IID713 + 6, // IID714 + 3, // IID715 + 6, // IID716 + 6, // IID717 + 6, // IID718 + 3, // IID719 + 6, // IID720 + 6, // IID721 + 6, // IID722 + 6, // IID723 + 6, // IID724 + 6, // IID725 + 11, // IID726 + 11, // IID727 + 11, // IID728 + 10, // IID729 + 11, // IID730 + 11, // IID731 + 11, // IID732 + 10, // IID733 + 11, // IID734 + 11, // IID735 + 11, // IID736 + 11, // IID737 + 11, // IID738 + 11, // IID739 + 11, // IID740 + 11, // IID741 + 11, // IID742 + 11, // IID743 + 11, // IID744 + 11, // IID745 + 11, // IID746 + 8, // IID747 + 11, // IID748 + 11, // IID749 + 11, // IID750 + 9, // IID751 + 11, // IID752 + 11, // IID753 + 11, // IID754 + 9, // IID755 + 11, // IID756 + 11, // IID757 + 11, // IID758 10, // IID759 - 7, // IID760 - 7, // IID761 - 4, // IID762 - 7, // IID763 - 7, // IID764 - 4, // IID765 - 6, // IID766 - 6, // IID767 - 7, // IID768 - 7, // IID769 - 7, // IID770 - 5, // IID771 - 6, // IID772 - 6, // IID773 - 6, // IID774 - 7, // IID775 - 7, // IID776 - 5, // IID777 - 7, // IID778 - 7, // IID779 - 6, // IID780 - 7, // IID781 - 7, // IID782 - 4, // IID783 - 6, // IID784 - 6, // IID785 - 7, // IID786 - 7, // IID787 - 7, // IID788 - 4, // IID789 - 7, // IID790 - 7, // IID791 + 11, // IID760 + 11, // IID761 + 11, // IID762 + 9, // IID763 + 11, // IID764 + 11, // IID765 + 14, // IID766 + 15, // IID767 + 12, // IID768 + 12, // IID769 + 15, // IID770 + 15, // IID771 + 15, // IID772 + 15, // IID773 + 11, // IID774 + 12, // IID775 + 11, // IID776 + 12, // IID777 + 12, // IID778 + 12, // IID779 + 11, // IID780 + 15, // IID781 + 15, // IID782 + 12, // IID783 + 10, // IID784 + 10, // IID785 + 8, // IID786 + 10, // IID787 + 10, // IID788 + 7, // IID789 + 10, // IID790 + 10, // IID791 7, // IID792 - 7, // IID793 - 7, // IID794 - 4, // IID795 - 7, // IID796 - 7, // IID797 - 6, // IID798 - 10, // IID799 - 10, // IID800 - 5, // IID801 - 7, // IID802 - 7, // IID803 - 10, // IID804 + 10, // IID793 + 10, // IID794 + 10, // IID795 + 10, // IID796 + 10, // IID797 + 10, // IID798 + 7, // IID799 + 7, // IID800 + 10, // IID801 + 10, // IID802 + 10, // IID803 + 4, // IID804 10, // IID805 10, // IID806 - 8, // IID807 - 10, // IID808 - 10, // IID809 - 10, // IID810 - 7, // IID811 - 10, // IID812 - 8, // IID813 - 10, // IID814 - 10, // IID815 - 8, // IID816 - 10, // IID817 - 10, // IID818 - 8, // IID819 - 10, // IID820 - 10, // IID821 - 10, // IID822 - 11, // IID823 - 11, // IID824 - 10, // IID825 - 11, // IID826 - 11, // IID827 - 11, // IID828 - 11, // IID829 - 11, // IID830 - 10, // IID831 - 11, // IID832 - 11, // IID833 - 10, // IID834 - 6, // IID835 - 3, // IID836 - 6, // IID837 + 7, // IID807 + 7, // IID808 + 7, // IID809 + 4, // IID810 + 6, // IID811 + 6, // IID812 + 5, // IID813 + 7, // IID814 + 7, // IID815 + 7, // IID816 + 7, // IID817 + 7, // IID818 + 5, // IID819 + 7, // IID820 + 7, // IID821 + 7, // IID822 + 7, // IID823 + 7, // IID824 + 4, // IID825 + 6, // IID826 + 6, // IID827 + 7, // IID828 + 6, // IID829 + 6, // IID830 + 5, // IID831 + 7, // IID832 + 7, // IID833 + 7, // IID834 + 7, // IID835 + 7, // IID836 + 4, // IID837 6, // IID838 6, // IID839 - 6, // IID840 - 6, // IID841 - 6, // IID842 - 6, // IID843 - 4, // IID844 - 6, // IID845 - 6, // IID846 - 6, // IID847 - 4, // IID848 - 6, // IID849 - 6, // IID850 - 6, // IID851 - 3, // IID852 - 6, // IID853 - 6, // IID854 - 6, // IID855 - 3, // IID856 - 6, // IID857 - 6, // IID858 - 6, // IID859 - 4, // IID860 - 6, // IID861 - 6, // IID862 - 7, // IID863 - 5, // IID864 - 7, // IID865 - 7, // IID866 - 7, // IID867 - 5, // IID868 - 7, // IID869 - 7, // IID870 - 6, // IID871 - 4, // IID872 - 6, // IID873 - 4, // IID874 - 6, // IID875 - 4, // IID876 - 6, // IID877 - 4, // IID878 - 6, // IID879 - 4, // IID880 - 6, // IID881 - 4, // IID882 - 6, // IID883 - 4, // IID884 - 6, // IID885 - 4, // IID886 - 6, // IID887 - 4, // IID888 - 6, // IID889 - 4, // IID890 - 6, // IID891 - 4, // IID892 - 6, // IID893 - 4, // IID894 + 7, // IID840 + 7, // IID841 + 7, // IID842 + 4, // IID843 + 7, // IID844 + 7, // IID845 + 7, // IID846 + 7, // IID847 + 7, // IID848 + 7, // IID849 + 10, // IID850 + 10, // IID851 + 10, // IID852 + 10, // IID853 + 10, // IID854 + 7, // IID855 + 7, // IID856 + 7, // IID857 + 10, // IID858 + 10, // IID859 + 10, // IID860 + 7, // IID861 + 10, // IID862 + 10, // IID863 + 7, // IID864 + 10, // IID865 + 10, // IID866 + 8, // IID867 + 10, // IID868 + 10, // IID869 + 10, // IID870 + 11, // IID871 + 9, // IID872 + 11, // IID873 + 11, // IID874 + 11, // IID875 + 9, // IID876 + 10, // IID877 + 11, // IID878 + 11, // IID879 + 9, // IID880 + 11, // IID881 + 10, // IID882 + 11, // IID883 + 9, // IID884 + 11, // IID885 + 11, // IID886 + 11, // IID887 + 9, // IID888 + 11, // IID889 + 11, // IID890 + 10, // IID891 + 9, // IID892 + 10, // IID893 + 11, // IID894 6, // IID895 4, // IID896 - 6, // IID897 - 4, // IID898 + 3, // IID897 + 6, // IID898 6, // IID899 - 4, // IID900 + 6, // IID900 6, // IID901 - 4, // IID902 - 11, // IID903 - 11, // IID904 - 11, // IID905 - 10, // IID906 - 11, // IID907 - 9, // IID908 - 11, // IID909 - 11, // IID910 - 11, // IID911 - 10, // IID912 - 11, // IID913 - 11, // IID914 - 11, // IID915 - 11, // IID916 - 11, // IID917 - 11, // IID918 + 6, // IID902 + 6, // IID903 + 6, // IID904 + 6, // IID905 + 4, // IID906 + 4, // IID907 + 6, // IID908 + 6, // IID909 + 6, // IID910 + 6, // IID911 + 4, // IID912 + 4, // IID913 + 6, // IID914 + 6, // IID915 + 6, // IID916 + 6, // IID917 + 4, // IID918 + 4, // IID919 + 6, // IID920 + 6, // IID921 + 6, // IID922 + 6, // IID923 + 4, // IID924 + 6, // IID925 + 6, // IID926 + 4, // IID927 + 3, // IID928 + 4, // IID929 + 6, // IID930 + 6, // IID931 + 6, // IID932 + 7, // IID933 + 5, // IID934 + 7, // IID935 + 7, // IID936 + 5, // IID937 + 5, // IID938 + 7, // IID939 + 7, // IID940 + 6, // IID941 + 4, // IID942 + 6, // IID943 + 4, // IID944 + 6, // IID945 + 4, // IID946 + 6, // IID947 + 4, // IID948 + 6, // IID949 + 4, // IID950 + 6, // IID951 + 4, // IID952 + 6, // IID953 + 4, // IID954 + 6, // IID955 + 4, // IID956 + 6, // IID957 + 4, // IID958 + 6, // IID959 + 4, // IID960 + 6, // IID961 + 4, // IID962 + 6, // IID963 + 4, // IID964 + 6, // IID965 + 4, // IID966 + 6, // IID967 + 4, // IID968 + 6, // IID969 + 4, // IID970 + 6, // IID971 + 4, // IID972 + 11, // IID973 + 9, // IID974 + 10, // IID975 + 9, // IID976 + 11, // IID977 + 9, // IID978 + 11, // IID979 + 9, // IID980 + 11, // IID981 + 9, // IID982 + 11, // IID983 + 9, // IID984 + 11, // IID985 + 9, // IID986 + 10, // IID987 + 9, // IID988 + 11, // IID989 + 9, // IID990 + 11, // IID991 + 9, // IID992 + 11, // IID993 + 9, // IID994 + 11, // IID995 + 9, // IID996 + 11, // IID997 + 9, // IID998 + 10, // IID999 + 9, // IID1000 + 11, // IID1001 + 9, // IID1002 + 11, // IID1003 + 9, // IID1004 #endif // _LP64 }; @@ -3152,662 +3404,746 @@ "__ eaddl(r28, Address(r24, rcx, (Address::ScaleFactor)3, -0x6053edc2), r28, false);", // IID268 "__ eaddl(r17, Address(r18, r24, (Address::ScaleFactor)3, -0x1bf71f78), r29, true);", // IID269 "__ eaddl(rcx, Address(r15, r28, (Address::ScaleFactor)1, +0x15b8216), rcx, true);", // IID270 - "__ eorl(r30, Address(rbx, rdx, (Address::ScaleFactor)3, -0x463540b4), r28, false);", // IID271 - "__ eorl(r18, Address(r28, r10, (Address::ScaleFactor)3, +0x3523a73b), r18, false);", // IID272 - "__ eorl(r9, Address(r15, r15, (Address::ScaleFactor)1, -0x2a0bdd56), r21, true);", // IID273 - "__ eorl(r16, Address(r23, -0x165064ff), r16, true);", // IID274 - "__ eorb(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false);", // IID275 - "__ eorb(rdx, Address(rbx, r31, (Address::ScaleFactor)2, +0x2477b5bb), rdx, false);", // IID276 - "__ eorb(r16, Address(r11, rcx, (Address::ScaleFactor)1, -0x3175d1af), r24, true);", // IID277 - "__ eorb(rbx, Address(r11, r20, (Address::ScaleFactor)3, -0x22d67bd3), rbx, true);", // IID278 - "__ esubl(r26, Address(r27, r30, (Address::ScaleFactor)1, -0x3d9bce2e), rdx, false);", // IID279 - "__ esubl(r31, Address(r22, r29, (Address::ScaleFactor)1, +0x14218519), r31, false);", // IID280 - "__ esubl(r21, Address(r9, -0x1050127a), r13, true);", // IID281 - "__ esubl(r31, Address(r9, r8, (Address::ScaleFactor)0, -0xae18961), r31, true);", // IID282 - "__ exorl(r15, Address(r18, +0x5c2bbce5), r12, false);", // IID283 - "__ exorl(r27, Address(r25, r23, (Address::ScaleFactor)0, +0x5c6078b3), r27, false);", // IID284 - "__ exorl(r18, Address(r8, rdx, (Address::ScaleFactor)3, -0x9ed3881), r14, true);", // IID285 - "__ exorl(r9, Address(r15, +0x775acdad), r9, true);", // IID286 - "__ exorb(r21, Address(r18, r26, (Address::ScaleFactor)1, +0x2fe31fd5), r23, false);", // IID287 - "__ exorb(r10, Address(r27, +0xa3150de), r10, false);", // IID288 - "__ exorb(r18, Address(r22, r30, (Address::ScaleFactor)3, +0x1ad4e897), r24, true);", // IID289 - "__ exorb(r8, Address(r16, r20, (Address::ScaleFactor)0, +0x626eae82), r8, true);", // IID290 - "__ eaddl(r21, r15, 1048576, false);", // IID291 - "__ eaddl(rax, r18, 1048576, false);", // IID292 - "__ eaddl(r18, r18, 256, false);", // IID293 - "__ eaddl(r13, r19, 16, true);", // IID294 - "__ eaddl(rax, r23, 16, true);", // IID295 - "__ eaddl(r25, r25, 16777216, true);", // IID296 - "__ eandl(r29, r18, 1048576, false);", // IID297 - "__ eandl(rax, r14, 1048576, false);", // IID298 - "__ eandl(r19, r19, 65536, false);", // IID299 - "__ eandl(r27, r25, 1048576, true);", // IID300 - "__ eandl(rax, r20, 1048576, true);", // IID301 - "__ eandl(r28, r28, 16, true);", // IID302 - "__ eimull(r31, r22, 4096, false);", // IID303 + "__ eandl(r30, Address(rbx, rdx, (Address::ScaleFactor)3, -0x463540b4), r28, false);", // IID271 + "__ eandl(r18, Address(r28, r10, (Address::ScaleFactor)3, +0x3523a73b), r18, false);", // IID272 + "__ eandl(r9, Address(r15, r15, (Address::ScaleFactor)1, -0x2a0bdd56), r21, true);", // IID273 + "__ eandl(r16, Address(r23, -0x165064ff), r16, true);", // IID274 + "__ eorl(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false);", // IID275 + "__ eorl(rdx, Address(rbx, r31, (Address::ScaleFactor)2, +0x2477b5bb), rdx, false);", // IID276 + "__ eorl(r16, Address(r11, rcx, (Address::ScaleFactor)1, -0x3175d1af), r24, true);", // IID277 + "__ eorl(rbx, Address(r11, r20, (Address::ScaleFactor)3, -0x22d67bd3), rbx, true);", // IID278 + "__ eorb(r26, Address(r27, r30, (Address::ScaleFactor)1, -0x3d9bce2e), rdx, false);", // IID279 + "__ eorb(r31, Address(r22, r29, (Address::ScaleFactor)1, +0x14218519), r31, false);", // IID280 + "__ eorb(r21, Address(r9, -0x1050127a), r13, true);", // IID281 + "__ eorb(r31, Address(r9, r8, (Address::ScaleFactor)0, -0xae18961), r31, true);", // IID282 + "__ esubl(r15, Address(r18, +0x5c2bbce5), r12, false);", // IID283 + "__ esubl(r27, Address(r25, r23, (Address::ScaleFactor)0, +0x5c6078b3), r27, false);", // IID284 + "__ esubl(r18, Address(r8, rdx, (Address::ScaleFactor)3, -0x9ed3881), r14, true);", // IID285 + "__ esubl(r9, Address(r15, +0x775acdad), r9, true);", // IID286 + "__ exorl(r21, Address(r18, r26, (Address::ScaleFactor)1, +0x2fe31fd5), r23, false);", // IID287 + "__ exorl(r10, Address(r27, +0xa3150de), r10, false);", // IID288 + "__ exorl(r18, Address(r22, r30, (Address::ScaleFactor)3, +0x1ad4e897), r24, true);", // IID289 + "__ exorl(r8, Address(r16, r20, (Address::ScaleFactor)0, +0x626eae82), r8, true);", // IID290 + "__ exorb(r16, Address(r21, r15, (Address::ScaleFactor)0, -0x1403b60d), r18, false);", // IID291 + "__ exorb(r13, Address(r19, r23, (Address::ScaleFactor)2, +0x237ef1e1), r13, false);", // IID292 + "__ exorb(r29, Address(r18, r14, (Address::ScaleFactor)2, +0x5cc0095b), r14, true);", // IID293 + "__ exorb(r27, Address(r25, r20, (Address::ScaleFactor)3, +0x1cf7b958), r27, true);", // IID294 + "__ eaddl(r16, r24, 16, false);", // IID295 + "__ eaddl(rax, r24, 16, false);", // IID296 + "__ eaddl(r21, r21, 65536, false);", // IID297 + "__ eaddl(r24, r8, 1048576, true);", // IID298 + "__ eaddl(rax, r13, 1048576, true);", // IID299 + "__ eaddl(r29, r29, 16777216, true);", // IID300 + "__ eandl(r12, r12, 16, false);", // IID301 + "__ eandl(rax, r30, 16, false);", // IID302 + "__ eandl(r24, r24, 16, false);", // IID303 + "__ eandl(r8, r12, 1, true);", // IID304 + "__ eandl(rax, r13, 1, true);", // IID305 + "__ eandl(r25, r25, 16, true);", // IID306 + "__ eimull(r18, r23, 65536, false);", // IID307 + "__ eimull(rax, r9, 65536, false);", // IID308 + "__ eimull(r26, r26, 268435456, false);", // IID309 + "__ eimull(r25, r21, 1, true);", // IID310 + "__ eimull(rax, r24, 1, true);", // IID311 + "__ eimull(r24, r24, 16777216, true);", // IID312 + "__ eorl(r30, r26, 1, false);", // IID313 + "__ eorl(rax, r22, 1, false);", // IID314 + "__ eorl(r17, r17, 1048576, false);", // IID315 + "__ eorl(r24, r8, 1, true);", // IID316 + "__ eorl(rax, r27, 1, true);", // IID317 #endif // _LP64 - "__ eimull(rax, rbx, 4096, false);", // IID304 + "__ eorl(rdx, rdx, 268435456, true);", // IID318 #ifdef _LP64 - "__ eimull(r24, r24, 1048576, false);", // IID305 - "__ eimull(r21, r16, 65536, true);", // IID306 - "__ eimull(rax, r24, 65536, true);", // IID307 - "__ eimull(r13, r13, 16, true);", // IID308 - "__ eorl(r29, r8, 16777216, false);", // IID309 - "__ eorl(rax, r12, 16777216, false);", // IID310 - "__ eorl(r30, r30, 4096, false);", // IID311 - "__ eorl(r24, rdx, 16, true);", // IID312 - "__ eorl(rax, r8, 16, true);", // IID313 - "__ eorl(r13, r13, 4096, true);", // IID314 - "__ ercll(r25, r13, 1);", // IID315 - "__ ercll(rax, r18, 1);", // IID316 - "__ ercll(r9, r9, 16);", // IID317 - "__ eroll(r26, r25, 8, false);", // IID318 + "__ ercll(r22, r22, 8);", // IID319 + "__ ercll(rax, r23, 8);", // IID320 + "__ ercll(r19, r19, 4);", // IID321 + "__ eroll(r30, r24, 2, false);", // IID322 + "__ eroll(rax, r29, 2, false);", // IID323 + "__ eroll(r8, r8, 2, false);", // IID324 + "__ eroll(r18, r24, 16, true);", // IID325 + "__ eroll(rax, r13, 16, true);", // IID326 + "__ eroll(r24, r24, 1, true);", // IID327 + "__ erorl(r28, r17, 16, false);", // IID328 + "__ erorl(rax, r24, 16, false);", // IID329 + "__ erorl(r17, r17, 4, false);", // IID330 + "__ erorl(r24, rcx, 4, true);", // IID331 + "__ erorl(rax, r16, 4, true);", // IID332 + "__ erorl(r15, r15, 2, true);", // IID333 + "__ esall(r14, r27, 4, false);", // IID334 + "__ esall(rax, r23, 4, false);", // IID335 + "__ esall(r30, r30, 4, false);", // IID336 + "__ esall(r27, rdx, 2, true);", // IID337 + "__ esall(rax, r19, 2, true);", // IID338 + "__ esall(r20, r20, 2, true);", // IID339 + "__ esarl(r21, r23, 1, false);", // IID340 + "__ esarl(rax, r30, 1, false);", // IID341 + "__ esarl(r25, r25, 2, false);", // IID342 + "__ esarl(r24, r19, 4, true);", // IID343 + "__ esarl(rax, r14, 4, true);", // IID344 + "__ esarl(r26, r26, 16, true);", // IID345 + "__ eshll(r22, r13, 8, false);", // IID346 + "__ eshll(rax, r24, 8, false);", // IID347 + "__ eshll(r14, r14, 16, false);", // IID348 + "__ eshll(r28, r25, 8, true);", // IID349 + "__ eshll(rax, r10, 8, true);", // IID350 + "__ eshll(r20, r20, 1, true);", // IID351 + "__ eshrl(r12, rbx, 4, false);", // IID352 + "__ eshrl(rax, r23, 4, false);", // IID353 + "__ eshrl(r28, r28, 16, false);", // IID354 + "__ eshrl(r24, r30, 4, true);", // IID355 + "__ eshrl(rax, r31, 4, true);", // IID356 + "__ eshrl(r31, r31, 2, true);", // IID357 + "__ esubl(r20, r10, 256, false);", // IID358 + "__ esubl(rax, r13, 256, false);", // IID359 + "__ esubl(r25, r25, 256, false);", // IID360 + "__ esubl(r23, r12, 268435456, true);", // IID361 + "__ esubl(rax, r16, 268435456, true);", // IID362 + "__ esubl(r31, r31, 1, true);", // IID363 + "__ exorl(r9, r15, 16777216, false);", // IID364 + "__ exorl(rax, r13, 16777216, false);", // IID365 + "__ exorl(r28, r28, 16, false);", // IID366 + "__ exorl(r29, r22, 16, true);", // IID367 #endif // _LP64 - "__ eroll(rax, rdx, 8, false);", // IID319 + "__ exorl(rax, rbx, 16, true);", // IID368 #ifdef _LP64 - "__ eroll(r24, r24, 16, false);", // IID320 - "__ eroll(r24, rcx, 8, true);", // IID321 - "__ eroll(rax, r30, 8, true);", // IID322 - "__ eroll(r28, r28, 16, true);", // IID323 - "__ erorl(r17, r28, 4, false);", // IID324 + "__ exorl(r8, r8, 16, true);", // IID369 + "__ esubl_imm32(r16, r13, 4194304, false);", // IID370 + "__ esubl_imm32(rax, r12, 4194304, false);", // IID371 + "__ esubl_imm32(r17, r17, 67108864, false);", // IID372 + "__ esubl_imm32(r22, r26, 1073741824, true);", // IID373 + "__ esubl_imm32(rax, r10, 1073741824, true);", // IID374 + "__ esubl_imm32(r11, r11, 1073741824, true);", // IID375 + "__ eaddl(r19, r12, Address(r30, r8, (Address::ScaleFactor)0, +0x6a1a0a73), false);", // IID376 + "__ eaddl(r30, r30, Address(r18, r19, (Address::ScaleFactor)2, +0x25f990cf), false);", // IID377 + "__ eaddl(rcx, r25, Address(r19, r16, (Address::ScaleFactor)0, +0x482d5dbc), true);", // IID378 + "__ eaddl(r9, r9, Address(r11, +0x43d5ee01), true);", // IID379 + "__ eandl(rcx, r23, Address(r21, r15, (Address::ScaleFactor)2, +0x2825c2bc), false);", // IID380 + "__ eandl(r27, r27, Address(r13, r15, (Address::ScaleFactor)3, -0x1268b895), false);", // IID381 + "__ eandl(r9, r23, Address(r22, r30, (Address::ScaleFactor)0, -0x715acbb), true);", // IID382 + "__ eandl(rbx, rbx, Address(r28, r16, (Address::ScaleFactor)2, +0xb0223ee), true);", // IID383 + "__ eimull(r15, r29, Address(r15, r28, (Address::ScaleFactor)1, -0x1f297a69), false);", // IID384 + "__ eimull(r17, r17, Address(r23, rbx, (Address::ScaleFactor)1, +0xadc7545), false);", // IID385 + "__ eimull(r27, r9, Address(rdx, r22, (Address::ScaleFactor)2, -0x43d90f61), true);", // IID386 + "__ eimull(rbx, rbx, Address(r28, r22, (Address::ScaleFactor)3, -0x519d9a27), true);", // IID387 + "__ eorl(r17, rcx, Address(r14, +0x10642223), false);", // IID388 + "__ eorl(r26, r26, Address(r31, -0x7a9a83ba), false);", // IID389 + "__ eorl(r15, r22, Address(r12, r12, (Address::ScaleFactor)2, +0x743b6997), true);", // IID390 + "__ eorl(r8, r8, Address(rdx, r22, (Address::ScaleFactor)3, -0x588414dc), true);", // IID391 + "__ esubl(rcx, r28, Address(r30, r13, (Address::ScaleFactor)2, +0xe9310e5), false);", // IID392 + "__ esubl(rcx, rcx, Address(r30, r10, (Address::ScaleFactor)1, -0x1b076ed1), false);", // IID393 + "__ esubl(r9, r21, Address(r30, +0x2f79ffd3), true);", // IID394 + "__ esubl(r16, r16, Address(rdx, r14, (Address::ScaleFactor)2, +0x675d71c1), true);", // IID395 + "__ exorl(r27, r28, Address(rbx, r26, (Address::ScaleFactor)2, -0x78c20b81), false);", // IID396 + "__ exorl(r14, r14, Address(r31, r19, (Address::ScaleFactor)1, -0x4ff251cc), false);", // IID397 + "__ exorl(r20, r18, Address(r13, r16, (Address::ScaleFactor)2, -0x19efc6e2), true);", // IID398 + "__ exorl(r19, r19, Address(r13, r23, (Address::ScaleFactor)1, -0x2d1bd8aa), true);", // IID399 + "__ exorb(r29, r17, Address(rdx, r29, (Address::ScaleFactor)2, +0x66573e84), false);", // IID400 + "__ exorb(r22, r22, Address(r24, r25, (Address::ScaleFactor)3, +0x3a94a93f), false);", // IID401 + "__ exorb(r13, r29, Address(r15, r23, (Address::ScaleFactor)1, +0x76d43532), true);", // IID402 + "__ exorb(r15, r15, Address(r13, r9, (Address::ScaleFactor)0, -0x474e6d1a), true);", // IID403 + "__ exorw(r17, r16, Address(r23, rdx, (Address::ScaleFactor)0, +0x562a291), false);", // IID404 + "__ exorw(r29, r29, Address(r18, r28, (Address::ScaleFactor)3, -0x541967f2), false);", // IID405 + "__ exorw(r27, r11, Address(r10, +0xa911c5a), true);", // IID406 + "__ exorw(r31, r31, Address(r30, r19, (Address::ScaleFactor)2, -0xf6a3da), true);", // IID407 + "__ eaddl(r12, r13, r23, false);", // IID408 + "__ eaddl(r28, r28, r20, false);", // IID409 + "__ eaddl(r20, r24, r20, false);", // IID410 + "__ eaddl(r11, r10, r15, true);", // IID411 + "__ eaddl(r19, r19, r20, true);", // IID412 + "__ eaddl(r23, r15, r23, true);", // IID413 + "__ eandl(r26, r19, r24, false);", // IID414 + "__ eandl(r23, r23, r28, false);", // IID415 + "__ eandl(r11, r13, r11, false);", // IID416 + "__ eandl(r13, rdx, r31, true);", // IID417 + "__ eandl(r23, r23, r23, true);", // IID418 + "__ eandl(r9, r27, r9, true);", // IID419 + "__ eimull(r21, r20, r24, false);", // IID420 + "__ eimull(r21, r21, r29, false);", // IID421 + "__ eimull(rbx, r11, rbx, false);", // IID422 + "__ eimull(r21, rbx, rcx, true);", // IID423 + "__ eimull(r31, r31, r21, true);", // IID424 + "__ eimull(r15, r25, r15, true);", // IID425 + "__ eorw(r30, r23, r25, false);", // IID426 + "__ eorw(r18, r18, rcx, false);", // IID427 + "__ eorw(r10, rcx, r10, false);", // IID428 + "__ eorw(r31, r21, r26, true);", // IID429 + "__ eorw(r21, r21, r19, true);", // IID430 #endif // _LP64 - "__ erorl(rax, rdx, 4, false);", // IID325 + "__ eorw(rdx, rbx, rdx, true);", // IID431 #ifdef _LP64 - "__ erorl(r8, r8, 16, false);", // IID326 - "__ erorl(r19, rdx, 16, true);", // IID327 - "__ erorl(rax, r31, 16, true);", // IID328 - "__ erorl(r22, r22, 8, true);", // IID329 - "__ esall(r23, r25, 16, false);", // IID330 - "__ esall(rax, r14, 16, false);", // IID331 - "__ esall(r31, r31, 8, false);", // IID332 - "__ esall(r30, r24, 2, true);", // IID333 - "__ esall(rax, r29, 2, true);", // IID334 - "__ esall(r8, r8, 2, true);", // IID335 - "__ esarl(r18, r24, 16, false);", // IID336 - "__ esarl(rax, r13, 16, false);", // IID337 - "__ esarl(r24, r24, 1, false);", // IID338 - "__ esarl(r28, r17, 16, true);", // IID339 - "__ esarl(rax, r24, 16, true);", // IID340 - "__ esarl(r17, r17, 4, true);", // IID341 - "__ eshll(r24, rcx, 4, false);", // IID342 - "__ eshll(rax, r16, 4, false);", // IID343 - "__ eshll(r15, r15, 2, false);", // IID344 - "__ eshll(r14, r27, 4, true);", // IID345 - "__ eshll(rax, r23, 4, true);", // IID346 - "__ eshll(r30, r30, 4, true);", // IID347 - "__ eshrl(r27, rdx, 2, false);", // IID348 - "__ eshrl(rax, r19, 2, false);", // IID349 - "__ eshrl(r20, r20, 2, false);", // IID350 - "__ eshrl(r21, r23, 1, true);", // IID351 - "__ eshrl(rax, r30, 1, true);", // IID352 - "__ eshrl(r25, r25, 2, true);", // IID353 - "__ esubl(r24, r19, 1048576, false);", // IID354 - "__ esubl(rax, r14, 1048576, false);", // IID355 - "__ esubl(r22, r22, 268435456, false);", // IID356 - "__ esubl(r24, r24, 65536, true);", // IID357 - "__ esubl(rax, r14, 65536, true);", // IID358 - "__ esubl(r28, r28, 268435456, true);", // IID359 - "__ exorl(rbx, r20, 256, false);", // IID360 - "__ exorl(rax, r15, 256, false);", // IID361 -#endif // _LP64 - "__ exorl(rbx, rbx, 4096, false);", // IID362 -#ifdef _LP64 - "__ exorl(r24, r30, 65536, true);", // IID363 - "__ exorl(rax, r31, 65536, true);", // IID364 - "__ exorl(r31, r31, 4096, true);", // IID365 - "__ esubl_imm32(r20, r10, 1048576, false);", // IID366 - "__ esubl_imm32(rax, r13, 1048576, false);", // IID367 - "__ esubl_imm32(r25, r25, 1048576, false);", // IID368 - "__ esubl_imm32(r23, r12, 1073741824, true);", // IID369 - "__ esubl_imm32(rax, r16, 1073741824, true);", // IID370 - "__ esubl_imm32(r31, r31, 65536, true);", // IID371 - "__ eaddl(r17, r13, Address(r9, +0x7fef2f98), false);", // IID372 - "__ eaddl(r29, r8, Address(r22, -0x4df70aac), true);", // IID373 - "__ eandl(r13, r17, Address(r12, r15, (Address::ScaleFactor)3, +0x50a8a902), false);", // IID374 - "__ eandl(r22, r25, Address(r26, r10, (Address::ScaleFactor)2, +0x70ea2754), true);", // IID375 - "__ eimull(r19, r12, Address(r30, r8, (Address::ScaleFactor)0, +0x6a1a0a73), false);", // IID376 - "__ eimull(r30, r18, Address(r18, r19, (Address::ScaleFactor)2, -0x7fcd28c7), true);", // IID377 - "__ eorl(r16, r31, Address(r25, r11, (Address::ScaleFactor)3, +0x482d5dbc), false);", // IID378 - "__ eorl(r9, r27, Address(r11, +0x43d5ee01), true);", // IID379 - "__ esubl(rcx, r23, Address(r21, r15, (Address::ScaleFactor)2, +0x2825c2bc), false);", // IID380 - "__ esubl(r27, r22, Address(r13, r15, (Address::ScaleFactor)1, +0x771f0da7), true);", // IID381 - "__ exorl(r9, r30, Address(r9, r22, (Address::ScaleFactor)3, -0x4ad6c88e), false);", // IID382 - "__ exorl(r11, r16, Address(rbx, r28, (Address::ScaleFactor)2, +0xb0223ee), true);", // IID383 - "__ exorb(r15, r29, Address(r15, r28, (Address::ScaleFactor)1, -0x1f297a69), false);", // IID384 - "__ exorb(r17, r30, Address(r23, rbx, (Address::ScaleFactor)1, +0xadc7545), true);", // IID385 - "__ exorw(r27, r9, Address(rdx, r22, (Address::ScaleFactor)2, -0x43d90f61), false);", // IID386 - "__ exorw(rbx, r22, Address(r28, r22, (Address::ScaleFactor)0, -0x7d30a0b1), true);", // IID387 - "__ eaddl(r14, r24, rcx, false);", // IID388 - "__ eaddl(r8, r8, r17, false);", // IID389 - "__ eaddl(r26, r24, r12, true);", // IID390 - "__ eaddl(r24, r24, r23, true);", // IID391 - "__ eandl(r13, r26, r31, false);", // IID392 - "__ eandl(r11, r11, r8, false);", // IID393 - "__ eandl(rcx, r19, r15, true);", // IID394 - "__ eandl(r12, r12, r12, true);", // IID395 - "__ eimull(r22, r20, r19, false);", // IID396 - "__ eimull(r8, r8, rdx, false);", // IID397 - "__ eimull(r22, r27, r23, true);", // IID398 - "__ eimull(r9, r9, r18, true);", // IID399 - "__ eorw(rcx, r30, r13, false);", // IID400 - "__ eorw(r28, r28, r19, false);", // IID401 - "__ eorw(r12, r30, r27, true);", // IID402 - "__ eorw(r8, r8, r22, true);", // IID403 - "__ eorl(r16, rcx, r30, false);", // IID404 - "__ eorl(r10, r10, r25, false);", // IID405 - "__ eorl(r15, r17, r17, true);", // IID406 - "__ eorl(r9, r9, r30, true);", // IID407 - "__ eshldl(r20, r21, r8, false);", // IID408 - "__ eshldl(r26, r26, r14, false);", // IID409 - "__ eshldl(r16, rdx, r14, true);", // IID410 - "__ eshldl(r19, r19, r8, true);", // IID411 - "__ eshrdl(r27, rbx, r26, false);", // IID412 - "__ eshrdl(r28, r28, r19, false);", // IID413 - "__ eshrdl(rcx, r11, r14, true);", // IID414 - "__ eshrdl(r31, r31, r19, true);", // IID415 - "__ esubl(r26, r13, r25, false);", // IID416 - "__ esubl(r24, r24, r11, false);", // IID417 - "__ esubl(r18, r20, r13, true);", // IID418 - "__ esubl(r16, r16, r18, true);", // IID419 - "__ exorl(r19, r17, r8, false);", // IID420 - "__ exorl(r19, r19, r13, false);", // IID421 - "__ exorl(r23, r13, r15, true);", // IID422 - "__ exorl(r11, r11, r29, true);", // IID423 - "__ eshldl(r29, r17, r17, 1, false);", // IID424 - "__ eshldl(r22, r22, r24, 4, false);", // IID425 - "__ eshldl(r8, r28, r11, 16, true);", // IID426 - "__ eshldl(r15, r15, r23, 4, true);", // IID427 - "__ eshrdl(r29, r22, r16, 4, false);", // IID428 - "__ eshrdl(r13, r13, r9, 4, false);", // IID429 - "__ eshrdl(r15, r21, r12, 2, true);", // IID430 - "__ eshrdl(r17, r17, r23, 2, true);", // IID431 - "__ ecmovl (Assembler::Condition::overflow, rdx, r16, r29);", // IID432 - "__ ecmovl (Assembler::Condition::overflow, r10, r10, r21);", // IID433 - "__ ecmovl (Assembler::Condition::noOverflow, r17, r29, r18);", // IID434 - "__ ecmovl (Assembler::Condition::noOverflow, r28, r28, r24);", // IID435 - "__ ecmovl (Assembler::Condition::below, r10, r20, r27);", // IID436 - "__ ecmovl (Assembler::Condition::below, r10, r10, r14);", // IID437 - "__ ecmovl (Assembler::Condition::aboveEqual, r11, r27, rcx);", // IID438 - "__ ecmovl (Assembler::Condition::aboveEqual, r22, r22, r15);", // IID439 - "__ ecmovl (Assembler::Condition::zero, r31, r30, r19);", // IID440 - "__ ecmovl (Assembler::Condition::zero, r19, r19, r26);", // IID441 - "__ ecmovl (Assembler::Condition::notZero, r21, r14, r26);", // IID442 - "__ ecmovl (Assembler::Condition::notZero, r20, r20, r15);", // IID443 - "__ ecmovl (Assembler::Condition::belowEqual, r12, r13, r23);", // IID444 - "__ ecmovl (Assembler::Condition::belowEqual, r28, r28, r20);", // IID445 - "__ ecmovl (Assembler::Condition::above, r20, r24, r11);", // IID446 - "__ ecmovl (Assembler::Condition::above, r10, r10, r15);", // IID447 - "__ ecmovl (Assembler::Condition::negative, r19, r20, r23);", // IID448 - "__ ecmovl (Assembler::Condition::negative, r15, r15, r26);", // IID449 - "__ ecmovl (Assembler::Condition::positive, r19, r24, r23);", // IID450 - "__ ecmovl (Assembler::Condition::positive, r28, r28, r11);", // IID451 - "__ ecmovl (Assembler::Condition::parity, r13, r13, rdx);", // IID452 - "__ ecmovl (Assembler::Condition::parity, r31, r31, r23);", // IID453 - "__ ecmovl (Assembler::Condition::noParity, r23, r9, r27);", // IID454 - "__ ecmovl (Assembler::Condition::noParity, r21, r21, r20);", // IID455 - "__ ecmovl (Assembler::Condition::less, r24, r21, r29);", // IID456 - "__ ecmovl (Assembler::Condition::less, rbx, rbx, r11);", // IID457 - "__ ecmovl (Assembler::Condition::greaterEqual, r21, rbx, rcx);", // IID458 - "__ ecmovl (Assembler::Condition::greaterEqual, r31, r31, r21);", // IID459 - "__ ecmovl (Assembler::Condition::lessEqual, r15, r25, r30);", // IID460 - "__ ecmovl (Assembler::Condition::lessEqual, r23, r23, r25);", // IID461 - "__ ecmovl (Assembler::Condition::greater, r18, rcx, r10);", // IID462 - "__ ecmovl (Assembler::Condition::greater, rcx, rcx, r31);", // IID463 - "__ ecmovl (Assembler::Condition::overflow, r21, r19, Address(r26, -0x6e290873));", // IID464 - "__ ecmovl (Assembler::Condition::noOverflow, r24, r19, Address(r22, rcx, (Address::ScaleFactor)0, +0x11f85f9a));", // IID465 - "__ ecmovl (Assembler::Condition::below, r17, r24, Address(r20, +0x534d775e));", // IID466 - "__ ecmovl (Assembler::Condition::aboveEqual, r20, r18, Address(r20, -0x47c94ecd));", // IID467 - "__ ecmovl (Assembler::Condition::zero, r9, r13, Address(r23, -0x4b83c563));", // IID468 - "__ ecmovl (Assembler::Condition::notZero, r11, r25, Address(r24, r14, (Address::ScaleFactor)1, -0x446507af));", // IID469 - "__ ecmovl (Assembler::Condition::belowEqual, r14, r24, Address(r30, r13, (Address::ScaleFactor)2, +0xd0661d));", // IID470 - "__ ecmovl (Assembler::Condition::above, r13, r25, Address(r14, r27, (Address::ScaleFactor)3, +0x47e1403));", // IID471 - "__ ecmovl (Assembler::Condition::negative, r24, r19, Address(rcx, rdx, (Address::ScaleFactor)3, -0x644a5318));", // IID472 - "__ ecmovl (Assembler::Condition::positive, r26, r24, Address(r22, r22, (Address::ScaleFactor)0, +0x70352446));", // IID473 - "__ ecmovl (Assembler::Condition::parity, r19, r26, Address(r8, r30, (Address::ScaleFactor)2, +0x78a12f5c));", // IID474 - "__ ecmovl (Assembler::Condition::noParity, r29, r11, Address(r25, r20, (Address::ScaleFactor)0, +0x27a8303a));", // IID475 - "__ ecmovl (Assembler::Condition::less, r22, r24, Address(r27, r16, (Address::ScaleFactor)1, +0x2541a10));", // IID476 - "__ ecmovl (Assembler::Condition::greaterEqual, r31, r15, Address(r8, r16, (Address::ScaleFactor)3, +0x558e3251));", // IID477 - "__ ecmovl (Assembler::Condition::lessEqual, r27, r18, Address(r8, r10, (Address::ScaleFactor)0, -0x471987b7));", // IID478 - "__ ecmovl (Assembler::Condition::greater, r18, r16, Address(r18, r19, (Address::ScaleFactor)2, -0x120ae81e));", // IID479 - "__ adcq(rbx, r31);", // IID480 - "__ cmpq(r30, r31);", // IID481 - "__ imulq(r29, r28);", // IID482 - "__ popcntq(r25, r10);", // IID483 - "__ sbbq(r24, r20);", // IID484 - "__ subq(r16, rdx);", // IID485 - "__ tzcntq(r26, r28);", // IID486 - "__ lzcntq(r28, r9);", // IID487 - "__ addq(r20, r24);", // IID488 - "__ andq(r24, r29);", // IID489 - "__ orq(r23, r27);", // IID490 - "__ xorq(r15, r12);", // IID491 - "__ movq(r18, r19);", // IID492 - "__ bsfq(r31, rcx);", // IID493 - "__ bsrq(r9, r13);", // IID494 - "__ btq(r20, rcx);", // IID495 - "__ xchgq(r8, r21);", // IID496 - "__ testq(r24, r14);", // IID497 - "__ addq(Address(rcx, r23, (Address::ScaleFactor)2, +0x4ff06c4d), r29);", // IID498 - "__ andq(Address(r24, r10, (Address::ScaleFactor)1, -0x75d9a189), r26);", // IID499 - "__ cmpq(Address(rbx, rbx, (Address::ScaleFactor)0, +0x4033d59c), r17);", // IID500 - "__ orq(Address(r22, r12, (Address::ScaleFactor)3, -0x3893347d), r18);", // IID501 - "__ xorq(Address(r20, r23, (Address::ScaleFactor)3, +0x4b311560), r12);", // IID502 - "__ subq(Address(r10, r28, (Address::ScaleFactor)2, +0x5c3a2657), r29);", // IID503 - "__ movq(Address(r13, r25, (Address::ScaleFactor)3, +0x1a3d6f3f), r22);", // IID504 - "__ xaddq(Address(r17, r24, (Address::ScaleFactor)3, -0x35addbd8), r25);", // IID505 - "__ andq(Address(r25, +0x632184c3), 16777216);", // IID506 - "__ addq(Address(r13, r13, (Address::ScaleFactor)0, -0x3972eac6), 16777216);", // IID507 - "__ cmpq(Address(r9, -0x13b4c806), 4096);", // IID508 - "__ sarq(Address(r31, +0x4fa7f551), 1);", // IID509 - "__ salq(Address(r21, r31, (Address::ScaleFactor)2, +0x31aa8232), 1);", // IID510 - "__ sbbq(Address(r24, r31, (Address::ScaleFactor)2, -0x466538b7), 268435456);", // IID511 - "__ shrq(Address(r28, r22, (Address::ScaleFactor)0, -0x3efe85b1), 2);", // IID512 - "__ subq(Address(r16, -0x1389a3eb), 1048576);", // IID513 - "__ xorq(Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615), 16);", // IID514 - "__ orq(Address(r12, r28, (Address::ScaleFactor)1, -0x34c898e2), 1);", // IID515 - "__ movq(Address(rcx, r24, (Address::ScaleFactor)2, -0x1644eb08), 256);", // IID516 - "__ testq(Address(r29, -0x7d23890b), -65536);", // IID517 - "__ addq(r23, Address(rcx, r19, (Address::ScaleFactor)2, +0x70eac654));", // IID518 - "__ andq(rdx, Address(r24, r15, (Address::ScaleFactor)0, -0x204ddaa9));", // IID519 - "__ cmpq(rdx, Address(r23, r11, (Address::ScaleFactor)3, +0x32c930bd));", // IID520 - "__ lzcntq(r28, Address(rdx, -0x5433c28f));", // IID521 - "__ orq(r22, Address(r19, r14, (Address::ScaleFactor)1, -0x2cc67d38));", // IID522 - "__ adcq(r10, Address(r10, +0x3d7c59f));", // IID523 - "__ imulq(r10, Address(r8, r8, (Address::ScaleFactor)3, -0xe61862d));", // IID524 - "__ popcntq(r23, Address(r29, -0x777ed96d));", // IID525 - "__ sbbq(rcx, Address(rbx, r19, (Address::ScaleFactor)1, +0x53c601cb));", // IID526 - "__ subq(r14, Address(r17, rbx, (Address::ScaleFactor)0, -0x768bf073));", // IID527 - "__ tzcntq(r29, Address(r10, r19, (Address::ScaleFactor)1, +0x30c98d3c));", // IID528 - "__ xorq(r10, Address(r16, r27, (Address::ScaleFactor)0, -0x3d08d602));", // IID529 - "__ movq(r18, Address(r28, r28, (Address::ScaleFactor)3, -0x62fbac91));", // IID530 - "__ leaq(rbx, Address(rcx, +0x450602a5));", // IID531 - "__ cvttsd2siq(r12, Address(r30, r31, (Address::ScaleFactor)0, -0x6798a630));", // IID532 - "__ xchgq(r31, Address(r24, r10, (Address::ScaleFactor)1, -0x706712ed));", // IID533 - "__ testq(r14, Address(r13, r20, (Address::ScaleFactor)3, +0x171081f2));", // IID534 - "__ addq(r31, 16);", // IID535 - "__ andq(r25, 16);", // IID536 - "__ adcq(r23, 256);", // IID537 - "__ cmpq(r19, 268435456);", // IID538 - "__ rclq(r31, 1);", // IID539 - "__ rcrq(r17, 1);", // IID540 - "__ rolq(r25, 2);", // IID541 - "__ rorq(r17, 4);", // IID542 - "__ sarq(r28, 1);", // IID543 - "__ salq(r15, 4);", // IID544 - "__ sbbq(rbx, 65536);", // IID545 - "__ shlq(r21, 1);", // IID546 - "__ shrq(r10, 1);", // IID547 - "__ subq(r14, 16);", // IID548 - "__ xorq(r18, 268435456);", // IID549 - "__ movq(r23, 16);", // IID550 - "__ mov64(r12, 1099511627776);", // IID551 - "__ btq(r14, 4);", // IID552 - "__ testq(r24, -4096);", // IID553 - "__ orq_imm32(r19, 1048576);", // IID554 - "__ subq_imm32(rcx, 268435456);", // IID555 - "__ cmovq(Assembler::Condition::overflow, rdx, Address(r19, rbx, (Address::ScaleFactor)3, +0x211c8c4));", // IID556 - "__ cmovq(Assembler::Condition::noOverflow, rbx, Address(r21, +0x49267743));", // IID557 - "__ cmovq(Assembler::Condition::below, r21, Address(r8, r28, (Address::ScaleFactor)1, -0x4c8c2946));", // IID558 - "__ cmovq(Assembler::Condition::aboveEqual, r12, Address(r26, r20, (Address::ScaleFactor)0, -0x264df89c));", // IID559 - "__ cmovq(Assembler::Condition::zero, r17, Address(r28, r9, (Address::ScaleFactor)2, +0x3497196b));", // IID560 - "__ cmovq(Assembler::Condition::notZero, r13, Address(r15, r23, (Address::ScaleFactor)1, -0x27a30999));", // IID561 - "__ cmovq(Assembler::Condition::belowEqual, r22, Address(r22, +0xf39ab05));", // IID562 - "__ cmovq(Assembler::Condition::above, rcx, Address(r22, r26, (Address::ScaleFactor)3, -0x48c954c));", // IID563 - "__ cmovq(Assembler::Condition::negative, r25, Address(r19, r21, (Address::ScaleFactor)0, +0xe405b0b));", // IID564 - "__ cmovq(Assembler::Condition::positive, r12, Address(r19, r29, (Address::ScaleFactor)3, -0x7762044b));", // IID565 - "__ cmovq(Assembler::Condition::parity, rbx, Address(r30, r10, (Address::ScaleFactor)1, -0x19798323));", // IID566 - "__ cmovq(Assembler::Condition::noParity, r21, Address(r24, r31, (Address::ScaleFactor)0, -0x5731652b));", // IID567 - "__ cmovq(Assembler::Condition::less, r18, Address(r8, r10, (Address::ScaleFactor)1, -0x5613be89));", // IID568 - "__ cmovq(Assembler::Condition::greaterEqual, r28, Address(r21, r21, (Address::ScaleFactor)3, +0x65a0fdc4));", // IID569 - "__ cmovq(Assembler::Condition::lessEqual, r23, Address(r11, r18, (Address::ScaleFactor)0, -0x1d1af10c));", // IID570 - "__ cmovq(Assembler::Condition::greater, r22, Address(r18, r12, (Address::ScaleFactor)1, +0x1a5f1c38));", // IID571 - "__ call(r23);", // IID572 - "__ divq(r30);", // IID573 - "__ idivq(r19);", // IID574 - "__ imulq(r9);", // IID575 - "__ mulq(r13);", // IID576 - "__ negq(r16);", // IID577 - "__ notq(r29);", // IID578 - "__ rolq(rcx);", // IID579 - "__ rorq(r25);", // IID580 - "__ sarq(r8);", // IID581 - "__ salq(r27);", // IID582 - "__ shlq(r30);", // IID583 - "__ shrq(r23);", // IID584 - "__ incrementq(rbx);", // IID585 - "__ decrementq(r14);", // IID586 - "__ pushp(r21);", // IID587 - "__ popp(r21);", // IID588 - "__ call(Address(r20, r21, (Address::ScaleFactor)1, +0x56c6af2f));", // IID589 - "__ mulq(Address(r31, r19, (Address::ScaleFactor)3, -0x1b4eb23));", // IID590 - "__ negq(Address(r27, r27, (Address::ScaleFactor)0, -0x58dbfc1f));", // IID591 - "__ sarq(Address(rbx, r22, (Address::ScaleFactor)2, -0x606349d1));", // IID592 - "__ salq(Address(r26, r23, (Address::ScaleFactor)3, +0xb95a079));", // IID593 - "__ shrq(Address(r14, r26, (Address::ScaleFactor)0, +0x3544e09));", // IID594 - "__ incrementq(Address(r27, rdx, (Address::ScaleFactor)0, +0x120b3250));", // IID595 - "__ decrementq(Address(r9, r25, (Address::ScaleFactor)2, -0x34aaeccb));", // IID596 - "__ imulq(r20, Address(r16, r28, (Address::ScaleFactor)1, -0x59de05a5), 1048576);", // IID597 - "__ imulq(r17, r23, 256);", // IID598 - "__ shldq(r19, r11, 8);", // IID599 - "__ shrdq(r28, r10, 8);", // IID600 - "__ pop2(r29, r26);", // IID601 - "__ pop2p(r22, r10);", // IID602 - "__ push2(r25, r30);", // IID603 - "__ push2p(r28, r15);", // IID604 - "__ movzbq(r11, Address(r29, r19, (Address::ScaleFactor)2, -0x12368d34));", // IID605 - "__ movzwq(r14, Address(r8, r30, (Address::ScaleFactor)2, -0x4a9392de));", // IID606 - "__ movsbq(r28, Address(r23, r15, (Address::ScaleFactor)0, +0x6189cb54));", // IID607 - "__ movswq(r28, Address(rbx, r23, (Address::ScaleFactor)3, -0x2de86561));", // IID608 - "__ movzbq(r11, rcx);", // IID609 - "__ movzwq(r30, r15);", // IID610 - "__ movsbq(r14, rcx);", // IID611 - "__ movswq(r23, r9);", // IID612 - "__ cmpxchgq(r12, Address(r13, r10, (Address::ScaleFactor)1, -0x7c62c3a));", // IID613 - "__ eidivq(rcx, false);", // IID614 - "__ eidivq(r15, true);", // IID615 - "__ edivq(r23, false);", // IID616 - "__ edivq(r24, true);", // IID617 - "__ eimulq(r27, false);", // IID618 - "__ eimulq(r30, true);", // IID619 - "__ emulq(r12, false);", // IID620 - "__ emulq(rcx, true);", // IID621 - "__ emulq(Address(r13, r9, (Address::ScaleFactor)3, -0x226aab94), false);", // IID622 - "__ emulq(Address(r13, r24, (Address::ScaleFactor)3, -0x286c7605), true);", // IID623 - "__ eimulq(r21, r30, false);", // IID624 - "__ eimulq(r17, r17, false);", // IID625 - "__ eimulq(r29, r12, true);", // IID626 - "__ eimulq(r30, r30, true);", // IID627 - "__ elzcntq(r24, r15, false);", // IID628 - "__ elzcntq(r25, r25, false);", // IID629 - "__ elzcntq(r25, r21, true);", // IID630 - "__ elzcntq(r22, r22, true);", // IID631 - "__ enegq(r17, r30, false);", // IID632 - "__ enegq(r17, r17, false);", // IID633 - "__ enegq(r31, r17, true);", // IID634 - "__ enegq(r29, r29, true);", // IID635 - "__ enotq(r10, r9);", // IID636 - "__ enotq(r24, r24);", // IID637 - "__ epopcntq(r28, r15, false);", // IID638 - "__ epopcntq(r10, r10, false);", // IID639 - "__ epopcntq(r27, r30, true);", // IID640 - "__ epopcntq(r28, r28, true);", // IID641 - "__ erolq(r28, r14, false);", // IID642 - "__ erolq(r23, r23, false);", // IID643 - "__ erolq(r23, r24, true);", // IID644 - "__ erolq(r21, r21, true);", // IID645 - "__ erorq(r31, r22, false);", // IID646 - "__ erorq(r28, r28, false);", // IID647 - "__ erorq(r17, r10, true);", // IID648 - "__ erorq(r9, r9, true);", // IID649 - "__ esalq(r29, r30, false);", // IID650 - "__ esalq(r11, r11, false);", // IID651 - "__ esalq(r26, r11, true);", // IID652 - "__ esalq(r16, r16, true);", // IID653 - "__ esarq(rbx, r15, false);", // IID654 - "__ esarq(r14, r14, false);", // IID655 - "__ esarq(r25, r16, true);", // IID656 - "__ esarq(r8, r8, true);", // IID657 - "__ edecq(r11, r13, false);", // IID658 - "__ edecq(rcx, rcx, false);", // IID659 - "__ edecq(r21, r18, true);", // IID660 - "__ edecq(r28, r28, true);", // IID661 - "__ eincq(r16, r16, false);", // IID662 - "__ eincq(r29, r29, false);", // IID663 - "__ eincq(r18, r9, true);", // IID664 - "__ eincq(r19, r19, true);", // IID665 - "__ eshlq(r19, r18, false);", // IID666 - "__ eshlq(r8, r8, false);", // IID667 - "__ eshlq(r12, r15, true);", // IID668 - "__ eshlq(r29, r29, true);", // IID669 - "__ eshrq(r28, r24, false);", // IID670 - "__ eshrq(r19, r19, false);", // IID671 - "__ eshrq(r8, r28, true);", // IID672 - "__ eshrq(r17, r17, true);", // IID673 - "__ etzcntq(r28, r16, false);", // IID674 - "__ etzcntq(r14, r14, false);", // IID675 - "__ etzcntq(r12, r31, true);", // IID676 - "__ etzcntq(r14, r14, true);", // IID677 - "__ eimulq(r31, Address(r13, -0x69c4b352), false);", // IID678 - "__ eimulq(r17, Address(r18, -0x60ab1105), true);", // IID679 - "__ elzcntq(r27, Address(r14, r25, (Address::ScaleFactor)2, +0x2798bf83), false);", // IID680 - "__ elzcntq(r23, Address(r10, r11, (Address::ScaleFactor)0, -0x378e635d), true);", // IID681 - "__ enegq(rcx, Address(r19, r9, (Address::ScaleFactor)3, -0x6847d440), false);", // IID682 - "__ enegq(rcx, Address(rbx, rcx, (Address::ScaleFactor)0, +0x6f92d38d), true);", // IID683 - "__ epopcntq(r20, Address(r12, -0x2a8b27d6), false);", // IID684 - "__ epopcntq(r31, Address(r30, +0x4603f6d0), true);", // IID685 - "__ esalq(rbx, Address(r24, +0x567d06f9), false);", // IID686 - "__ esalq(r12, Address(r24, r28, (Address::ScaleFactor)0, -0x1c4c584e), true);", // IID687 - "__ esarq(r12, Address(r23, r24, (Address::ScaleFactor)2, -0x3157bcba), false);", // IID688 - "__ esarq(r8, Address(r14, r24, (Address::ScaleFactor)2, -0x714290a5), true);", // IID689 - "__ edecq(r23, Address(r8, r15, (Address::ScaleFactor)1, -0x5ae272dd), false);", // IID690 - "__ edecq(r13, Address(r29, r9, (Address::ScaleFactor)3, -0x5b5174a9), true);", // IID691 - "__ eincq(r11, Address(r21, r31, (Address::ScaleFactor)3, -0x2176b4dc), false);", // IID692 - "__ eincq(r13, Address(rcx, r16, (Address::ScaleFactor)0, -0x36b448c9), true);", // IID693 - "__ eshrq(r26, Address(r25, rcx, (Address::ScaleFactor)2, -0x5f894993), false);", // IID694 - "__ eshrq(r25, Address(r9, +0x51798d21), true);", // IID695 - "__ etzcntq(r28, Address(r13, r26, (Address::ScaleFactor)2, +0x207196f6), false);", // IID696 - "__ etzcntq(rbx, Address(r19, r13, (Address::ScaleFactor)0, -0x24d937d5), true);", // IID697 - "__ eaddq(r17, Address(r30, +0x3935ccff), r31, false);", // IID698 - "__ eaddq(r14, Address(r27, r10, (Address::ScaleFactor)2, -0x34ad9bab), r14, false);", // IID699 - "__ eaddq(r18, Address(r20, r23, (Address::ScaleFactor)0, +0x5ad3ed4b), r30, true);", // IID700 - "__ eaddq(r20, Address(rdx, -0x322a99e5), r20, true);", // IID701 - "__ eandq(r31, Address(rbx, r27, (Address::ScaleFactor)3, +0x4ce247d2), r17, false);", // IID702 - "__ eandq(r30, Address(r18, r19, (Address::ScaleFactor)1, -0x4ee3d14), r30, false);", // IID703 - "__ eandq(r28, Address(r11, rbx, (Address::ScaleFactor)3, -0x28994bbf), r24, true);", // IID704 - "__ eandq(r30, Address(r22, +0x7d21c24), r30, true);", // IID705 - "__ eorq(r26, Address(r15, r19, (Address::ScaleFactor)3, +0x58c21792), r20, false);", // IID706 - "__ eorq(r13, Address(r10, r27, (Address::ScaleFactor)2, -0x2c70d333), r13, false);", // IID707 - "__ eorq(rbx, Address(r12, rbx, (Address::ScaleFactor)0, -0x1fb0f1bc), r26, true);", // IID708 - "__ eorq(r31, Address(r27, r31, (Address::ScaleFactor)1, +0x28d1756), r31, true);", // IID709 - "__ esubq(r24, Address(r28, r23, (Address::ScaleFactor)1, +0x6980f610), r27, false);", // IID710 - "__ esubq(r15, Address(r11, r30, (Address::ScaleFactor)3, -0x49777e7), r15, false);", // IID711 - "__ esubq(r17, Address(r25, r13, (Address::ScaleFactor)2, +0x31619e46), r31, true);", // IID712 - "__ esubq(r18, Address(r11, r10, (Address::ScaleFactor)2, +0x1922861a), r18, true);", // IID713 - "__ exorq(rbx, Address(r11, -0x4716d420), r21, false);", // IID714 - "__ exorq(r8, Address(rdx, r9, (Address::ScaleFactor)2, -0x4cfe39c), r8, false);", // IID715 - "__ exorq(r16, Address(r14, r27, (Address::ScaleFactor)0, +0x7c6654d9), r25, true);", // IID716 - "__ exorq(r29, Address(r15, -0x5efab479), r29, true);", // IID717 - "__ eaddq(r19, Address(r13, r22, (Address::ScaleFactor)2, +0x68b64559), 16777216, false);", // IID718 - "__ eaddq(r16, Address(r13, r31, (Address::ScaleFactor)3, -0x65143af5), 1, true);", // IID719 - "__ eandq(r31, Address(r24, r13, (Address::ScaleFactor)1, -0x25b16a0e), 1, false);", // IID720 - "__ eandq(r11, Address(r28, -0xf6d4b26), 65536, true);", // IID721 - "__ eimulq(rcx, Address(r18, r10, (Address::ScaleFactor)0, +0x46ec6da1), 16777216, false);", // IID722 - "__ eimulq(r15, Address(r9, r10, (Address::ScaleFactor)3, -0x7fc36af3), 16, true);", // IID723 - "__ eorq(r17, Address(r27, r30, (Address::ScaleFactor)0, +0x1b4cda2c), 1, false);", // IID724 - "__ eorq(rdx, Address(r25, r14, (Address::ScaleFactor)2, -0x59aa6b85), 4096, true);", // IID725 - "__ esalq(r17, Address(r26, r21, (Address::ScaleFactor)1, -0x6ab1f15f), 8, false);", // IID726 - "__ esalq(r12, Address(r22, r17, (Address::ScaleFactor)0, -0x43ac14ab), 2, true);", // IID727 - "__ esarq(r29, Address(r18, r16, (Address::ScaleFactor)0, -0x59dc0c61), 4, false);", // IID728 - "__ esarq(r16, Address(r11, -0x7bdd314), 4, true);", // IID729 - "__ eshrq(r26, Address(r23, r27, (Address::ScaleFactor)3, -0x55b92314), 16, false);", // IID730 - "__ eshrq(r23, Address(r16, r29, (Address::ScaleFactor)1, +0x71311a1d), 2, true);", // IID731 - "__ esubq(r25, Address(r9, -0x9532bac), 1048576, false);", // IID732 - "__ esubq(r17, Address(r8, r23, (Address::ScaleFactor)0, +0x55d06ca2), 1048576, true);", // IID733 - "__ exorq(r29, Address(r9, r24, (Address::ScaleFactor)0, -0x2c141c1), 1048576, false);", // IID734 - "__ exorq(r28, Address(r22, r19, (Address::ScaleFactor)1, -0x2d9d9abd), 16, true);", // IID735 - "__ eaddq(r22, r14, 16, false);", // IID736 - "__ eaddq(rax, r12, 16, false);", // IID737 - "__ eaddq(r24, r24, 65536, false);", // IID738 - "__ eaddq(r21, rbx, 65536, true);", // IID739 - "__ eaddq(rax, rbx, 65536, true);", // IID740 - "__ eaddq(r24, r24, 65536, true);", // IID741 - "__ eandq(r21, r27, 16777216, false);", // IID742 - "__ eandq(rax, r27, 16777216, false);", // IID743 - "__ eandq(r24, r24, 65536, false);", // IID744 - "__ eandq(r13, r31, 1048576, true);", // IID745 - "__ eandq(rax, r21, 1048576, true);", // IID746 - "__ eandq(r30, r30, 1048576, true);", // IID747 - "__ eimulq(r8, r13, 268435456, false);", // IID748 - "__ eimulq(rax, r31, 268435456, false);", // IID749 - "__ eimulq(r13, r13, 65536, false);", // IID750 - "__ eimulq(r14, r29, 1048576, true);", // IID751 - "__ eimulq(rax, r22, 1048576, true);", // IID752 - "__ eimulq(r8, r8, 268435456, true);", // IID753 - "__ eorq(r30, r15, 4096, false);", // IID754 - "__ eorq(rax, r28, 4096, false);", // IID755 - "__ eorq(r26, r26, 1048576, false);", // IID756 - "__ eorq(r16, r12, 268435456, true);", // IID757 - "__ eorq(rax, r9, 268435456, true);", // IID758 - "__ eorq(r23, r23, 256, true);", // IID759 - "__ erclq(r15, r9, 16);", // IID760 - "__ erclq(rax, r8, 16);", // IID761 - "__ erclq(r25, r25, 1);", // IID762 - "__ erolq(r9, r17, 16, false);", // IID763 - "__ erolq(rax, r20, 16, false);", // IID764 - "__ erolq(r27, r27, 1, false);", // IID765 - "__ erolq(r20, r31, 1, true);", // IID766 - "__ erolq(rax, r18, 1, true);", // IID767 - "__ erolq(r28, r28, 16, true);", // IID768 - "__ erorq(r26, r18, 16, false);", // IID769 - "__ erorq(rax, r24, 16, false);", // IID770 - "__ erorq(r22, r22, 16, false);", // IID771 - "__ erorq(r27, r29, 1, true);", // IID772 - "__ erorq(rax, r18, 1, true);", // IID773 - "__ erorq(r21, r21, 1, true);", // IID774 - "__ esalq(r12, rcx, 2, false);", // IID775 - "__ esalq(rax, r24, 2, false);", // IID776 - "__ esalq(r22, r22, 8, false);", // IID777 - "__ esalq(r17, r23, 8, true);", // IID778 - "__ esalq(rax, r27, 8, true);", // IID779 - "__ esalq(r23, r23, 1, true);", // IID780 - "__ esarq(r8, r25, 16, false);", // IID781 - "__ esarq(rax, r23, 16, false);", // IID782 - "__ esarq(r9, r9, 4, false);", // IID783 - "__ esarq(r22, r13, 1, true);", // IID784 - "__ esarq(rax, r11, 1, true);", // IID785 - "__ esarq(r12, r12, 2, true);", // IID786 - "__ eshlq(rcx, r30, 8, false);", // IID787 - "__ eshlq(rax, r19, 8, false);", // IID788 - "__ eshlq(r13, r13, 2, false);", // IID789 - "__ eshlq(r18, r11, 8, true);", // IID790 - "__ eshlq(rax, r9, 8, true);", // IID791 - "__ eshlq(rcx, rcx, 16, true);", // IID792 - "__ eshrq(r10, r22, 4, false);", // IID793 - "__ eshrq(rax, r9, 4, false);", // IID794 - "__ eshrq(r12, r12, 2, false);", // IID795 - "__ eshrq(r26, r31, 8, true);", // IID796 - "__ eshrq(rax, r12, 8, true);", // IID797 - "__ eshrq(r28, r28, 1, true);", // IID798 - "__ esubq(r15, r30, 65536, false);", // IID799 - "__ esubq(rax, rcx, 65536, false);", // IID800 - "__ esubq(r26, r26, 16, false);", // IID801 - "__ esubq(r12, r14, 1, true);", // IID802 - "__ esubq(rax, r21, 1, true);", // IID803 - "__ esubq(r20, r20, 1048576, true);", // IID804 - "__ exorq(r11, rbx, 16777216, false);", // IID805 - "__ exorq(rax, r23, 16777216, false);", // IID806 - "__ exorq(r31, r31, 268435456, false);", // IID807 - "__ exorq(r29, r28, 4096, true);", // IID808 - "__ exorq(rax, r19, 4096, true);", // IID809 - "__ exorq(rdx, rdx, 268435456, true);", // IID810 - "__ eorq_imm32(rdx, rdx, 1048576, false);", // IID811 - "__ eorq_imm32(rax, r22, 1048576, false);", // IID812 - "__ eorq_imm32(r29, r29, 1048576, false);", // IID813 - "__ eorq_imm32(r17, rcx, 4194304, false);", // IID814 - "__ eorq_imm32(rax, r25, 4194304, false);", // IID815 - "__ eorq_imm32(r27, r27, 1073741824, false);", // IID816 - "__ esubq_imm32(r16, r19, 4194304, false);", // IID817 - "__ esubq_imm32(rax, r31, 4194304, false);", // IID818 - "__ esubq_imm32(r26, r26, 262144, false);", // IID819 - "__ esubq_imm32(r17, r22, 1073741824, true);", // IID820 - "__ esubq_imm32(rax, r18, 1073741824, true);", // IID821 - "__ esubq_imm32(r23, r23, 268435456, true);", // IID822 - "__ eaddq(r13, r30, Address(r24, r19, (Address::ScaleFactor)1, +0x56ea3a3b), false);", // IID823 - "__ eaddq(r29, r15, Address(r26, r27, (Address::ScaleFactor)3, -0x4b113958), true);", // IID824 - "__ eandq(r12, r30, Address(r31, -0x46103c74), false);", // IID825 - "__ eandq(r27, r10, Address(r22, r25, (Address::ScaleFactor)1, +0x6a1ebee5), true);", // IID826 - "__ eorq(r30, r26, Address(r11, r18, (Address::ScaleFactor)2, -0x2b9fff29), false);", // IID827 - "__ eorq(r9, r12, Address(r18, r17, (Address::ScaleFactor)0, +0xb4859f6), true);", // IID828 - "__ eimulq(rdx, r17, Address(r24, rdx, (Address::ScaleFactor)2, +0x3d284cd8), false);", // IID829 - "__ eimulq(r29, r26, Address(r30, r12, (Address::ScaleFactor)1, +0x6e813124), true);", // IID830 - "__ esubq(rbx, r13, Address(r22, -0x702a289e), false);", // IID831 - "__ esubq(r23, r29, Address(r25, rdx, (Address::ScaleFactor)0, -0x6252a7ed), true);", // IID832 - "__ exorq(r8, r18, Address(r19, r14, (Address::ScaleFactor)2, -0xebfa697), false);", // IID833 - "__ exorq(r10, r28, Address(r26, +0x168381ca), true);", // IID834 - "__ eaddq(rcx, r18, r8, false);", // IID835 - "__ eaddq(rcx, rcx, r14, false);", // IID836 - "__ eaddq(r23, r10, r16, true);", // IID837 - "__ eaddq(r11, r11, r24, true);", // IID838 - "__ eadcxq(r9, r18, rdx);", // IID839 - "__ eadcxq(r8, r8, r15);", // IID840 - "__ eadoxq(r15, r22, r26);", // IID841 - "__ eadoxq(r11, r11, rdx);", // IID842 - "__ eandq(r19, rdx, r22, false);", // IID843 - "__ eandq(r29, r29, r17, false);", // IID844 - "__ eandq(r23, r27, r15, true);", // IID845 - "__ eandq(r9, r9, r13, true);", // IID846 - "__ eimulq(r18, r15, r16, false);", // IID847 - "__ eimulq(rcx, rcx, r17, false);", // IID848 - "__ eimulq(r23, r12, r20, true);", // IID849 - "__ eimulq(r10, r10, r9, true);", // IID850 - "__ eorq(rdx, r19, r14, false);", // IID851 - "__ eorq(rcx, rcx, r13, false);", // IID852 - "__ eorq(r9, r25, r29, true);", // IID853 - "__ eorq(rdx, rdx, r25, true);", // IID854 - "__ esubq(r23, r8, r16, false);", // IID855 - "__ esubq(r13, r13, r13, false);", // IID856 - "__ esubq(r19, r12, r15, true);", // IID857 - "__ esubq(r9, r9, rdx, true);", // IID858 - "__ exorq(r13, r16, r31, false);", // IID859 - "__ exorq(r17, r17, r30, false);", // IID860 - "__ exorq(r19, r30, r20, true);", // IID861 - "__ exorq(r31, r31, r13, true);", // IID862 - "__ eshldq(r22, r10, r13, 4, false);", // IID863 - "__ eshldq(r24, r24, r21, 16, false);", // IID864 - "__ eshldq(r20, r13, r27, 16, true);", // IID865 - "__ eshldq(r31, r31, r19, 2, true);", // IID866 - "__ eshrdq(r30, r20, r11, 8, false);", // IID867 - "__ eshrdq(rdx, rdx, r15, 1, false);", // IID868 - "__ eshrdq(r28, r30, r14, 2, true);", // IID869 - "__ eshrdq(r20, r20, r16, 1, true);", // IID870 - "__ ecmovq (Assembler::Condition::overflow, r21, r17, r28);", // IID871 - "__ ecmovq (Assembler::Condition::overflow, r15, r15, r30);", // IID872 - "__ ecmovq (Assembler::Condition::noOverflow, rcx, r15, r15);", // IID873 - "__ ecmovq (Assembler::Condition::noOverflow, rcx, rcx, r13);", // IID874 - "__ ecmovq (Assembler::Condition::below, rdx, r26, r26);", // IID875 - "__ ecmovq (Assembler::Condition::below, r28, r28, r15);", // IID876 - "__ ecmovq (Assembler::Condition::aboveEqual, r8, rdx, rcx);", // IID877 - "__ ecmovq (Assembler::Condition::aboveEqual, rcx, rcx, rcx);", // IID878 - "__ ecmovq (Assembler::Condition::zero, r10, r13, r9);", // IID879 - "__ ecmovq (Assembler::Condition::zero, r14, r14, r27);", // IID880 - "__ ecmovq (Assembler::Condition::notZero, r11, r23, r9);", // IID881 - "__ ecmovq (Assembler::Condition::notZero, r11, r11, rdx);", // IID882 - "__ ecmovq (Assembler::Condition::belowEqual, r31, r14, r25);", // IID883 - "__ ecmovq (Assembler::Condition::belowEqual, r20, r20, r12);", // IID884 - "__ ecmovq (Assembler::Condition::above, rdx, r10, r28);", // IID885 - "__ ecmovq (Assembler::Condition::above, r8, r8, r17);", // IID886 - "__ ecmovq (Assembler::Condition::negative, rcx, r30, r23);", // IID887 - "__ ecmovq (Assembler::Condition::negative, r26, r26, r18);", // IID888 - "__ ecmovq (Assembler::Condition::positive, rdx, rbx, r18);", // IID889 - "__ ecmovq (Assembler::Condition::positive, r21, r21, r13);", // IID890 - "__ ecmovq (Assembler::Condition::parity, r27, r28, r27);", // IID891 - "__ ecmovq (Assembler::Condition::parity, r11, r11, r30);", // IID892 - "__ ecmovq (Assembler::Condition::noParity, rcx, r21, r18);", // IID893 - "__ ecmovq (Assembler::Condition::noParity, rcx, rcx, r29);", // IID894 - "__ ecmovq (Assembler::Condition::less, rdx, r21, r12);", // IID895 - "__ ecmovq (Assembler::Condition::less, rdx, rdx, r26);", // IID896 - "__ ecmovq (Assembler::Condition::greaterEqual, r17, rbx, r22);", // IID897 - "__ ecmovq (Assembler::Condition::greaterEqual, rdx, rdx, r11);", // IID898 - "__ ecmovq (Assembler::Condition::lessEqual, rdx, r14, r8);", // IID899 - "__ ecmovq (Assembler::Condition::lessEqual, r14, r14, r8);", // IID900 - "__ ecmovq (Assembler::Condition::greater, r25, r29, r21);", // IID901 - "__ ecmovq (Assembler::Condition::greater, r26, r26, r30);", // IID902 - "__ ecmovq (Assembler::Condition::overflow, r24, r21, Address(r13, r11, (Address::ScaleFactor)1, +0x439c521e));", // IID903 - "__ ecmovq (Assembler::Condition::noOverflow, r11, r18, Address(r29, r16, (Address::ScaleFactor)0, +0x632127f));", // IID904 - "__ ecmovq (Assembler::Condition::below, r16, r8, Address(r8, r26, (Address::ScaleFactor)1, +0x10633def));", // IID905 - "__ ecmovq (Assembler::Condition::aboveEqual, r13, r14, Address(r18, -0x54f69e38));", // IID906 - "__ ecmovq (Assembler::Condition::zero, r12, r8, Address(r31, r26, (Address::ScaleFactor)1, -0x7a1e447a));", // IID907 - "__ ecmovq (Assembler::Condition::notZero, r29, r29, Address(r19, r11, (Address::ScaleFactor)2, -0x35d82dd2));", // IID908 - "__ ecmovq (Assembler::Condition::belowEqual, rcx, r18, Address(r25, r28, (Address::ScaleFactor)0, +0x30be64a0));", // IID909 - "__ ecmovq (Assembler::Condition::above, r28, r12, Address(r10, r16, (Address::ScaleFactor)1, -0x22b8fefa));", // IID910 - "__ ecmovq (Assembler::Condition::negative, r11, r8, Address(rbx, r11, (Address::ScaleFactor)3, +0x25cc9e96));", // IID911 - "__ ecmovq (Assembler::Condition::positive, r12, r27, Address(r11, -0xc2d70fe));", // IID912 - "__ ecmovq (Assembler::Condition::parity, r8, r26, Address(r19, rbx, (Address::ScaleFactor)1, -0x486db7ea));", // IID913 - "__ ecmovq (Assembler::Condition::noParity, r30, r10, Address(r14, r18, (Address::ScaleFactor)3, +0x14884884));", // IID914 - "__ ecmovq (Assembler::Condition::less, r27, r8, Address(r29, r14, (Address::ScaleFactor)2, +0x92b7a8));", // IID915 - "__ ecmovq (Assembler::Condition::greaterEqual, r14, r28, Address(r19, rdx, (Address::ScaleFactor)0, +0x9c2d45));", // IID916 - "__ ecmovq (Assembler::Condition::lessEqual, r25, r8, Address(rcx, r18, (Address::ScaleFactor)2, +0x6655c86b));", // IID917 - "__ ecmovq (Assembler::Condition::greater, r19, r21, Address(r10, r25, (Address::ScaleFactor)0, -0x1005430b));", // IID918 + "__ eorl(rcx, r24, r22, false);", // IID432 + "__ eorl(rcx, rcx, r19, false);", // IID433 + "__ eorl(r27, r27, r27, false);", // IID434 + "__ eorl(r31, r9, r13, true);", // IID435 + "__ eorl(r31, r31, r23, true);", // IID436 + "__ eorl(r19, r17, r19, true);", // IID437 + "__ eshldl(r20, r16, r24, false);", // IID438 + "__ eshldl(rdx, rdx, r12, false);", // IID439 + "__ eshldl(r29, r9, r31, true);", // IID440 + "__ eshldl(r17, r17, r20, true);", // IID441 + "__ eshrdl(r20, r15, r18, false);", // IID442 + "__ eshrdl(rcx, rcx, r12, false);", // IID443 + "__ eshrdl(r14, r9, r23, true);", // IID444 + "__ eshrdl(r19, r19, r13, true);", // IID445 + "__ esubl(r30, r27, r27, false);", // IID446 + "__ esubl(rdx, rdx, r11, false);", // IID447 + "__ esubl(r15, r11, r24, true);", // IID448 + "__ esubl(r14, r14, r25, true);", // IID449 + "__ exorl(r31, r16, r12, false);", // IID450 + "__ exorl(r20, r20, r14, false);", // IID451 + "__ exorl(r30, r13, r30, false);", // IID452 + "__ exorl(r24, r17, r17, true);", // IID453 + "__ exorl(r26, r26, r21, true);", // IID454 + "__ exorl(r11, r13, r11, true);", // IID455 + "__ eshldl(r27, r25, r21, 4, false);", // IID456 + "__ eshldl(r22, r22, r10, 4, false);", // IID457 + "__ eshldl(r21, r15, r24, 16, true);", // IID458 + "__ eshldl(rdx, rdx, r19, 1, true);", // IID459 + "__ eshrdl(r23, r13, r8, 16, false);", // IID460 + "__ eshrdl(r26, r26, r22, 1, false);", // IID461 + "__ eshrdl(r24, r9, r30, 16, true);", // IID462 + "__ eshrdl(r19, r19, r8, 4, true);", // IID463 + "__ ecmovl (Assembler::Condition::overflow, r30, r26, r17);", // IID464 + "__ ecmovl (Assembler::Condition::overflow, r14, r14, r26);", // IID465 + "__ ecmovl (Assembler::Condition::noOverflow, r24, r19, r29);", // IID466 + "__ ecmovl (Assembler::Condition::noOverflow, r25, r25, r20);", // IID467 + "__ ecmovl (Assembler::Condition::below, r11, r10, r14);", // IID468 + "__ ecmovl (Assembler::Condition::below, r30, r30, r25);", // IID469 + "__ ecmovl (Assembler::Condition::aboveEqual, r13, r22, r27);", // IID470 + "__ ecmovl (Assembler::Condition::aboveEqual, r16, r16, r24);", // IID471 + "__ ecmovl (Assembler::Condition::zero, r28, r13, r30);", // IID472 + "__ ecmovl (Assembler::Condition::zero, r30, r30, r24);", // IID473 + "__ ecmovl (Assembler::Condition::notZero, r21, r20, r31);", // IID474 + "__ ecmovl (Assembler::Condition::notZero, r8, r8, r16);", // IID475 + "__ ecmovl (Assembler::Condition::belowEqual, r15, r26, r22);", // IID476 + "__ ecmovl (Assembler::Condition::belowEqual, r31, r31, rdx);", // IID477 + "__ ecmovl (Assembler::Condition::above, r27, r8, r10);", // IID478 + "__ ecmovl (Assembler::Condition::above, r18, r18, r11);", // IID479 + "__ ecmovl (Assembler::Condition::negative, r27, rbx, r21);", // IID480 + "__ ecmovl (Assembler::Condition::negative, r12, r12, r31);", // IID481 + "__ ecmovl (Assembler::Condition::positive, r12, rdx, r18);", // IID482 + "__ ecmovl (Assembler::Condition::positive, r18, r18, r19);", // IID483 + "__ ecmovl (Assembler::Condition::parity, r16, r20, r23);", // IID484 + "__ ecmovl (Assembler::Condition::parity, r18, r18, r16);", // IID485 + "__ ecmovl (Assembler::Condition::noParity, rbx, r31, r30);", // IID486 + "__ ecmovl (Assembler::Condition::noParity, r31, r31, r29);", // IID487 + "__ ecmovl (Assembler::Condition::less, r28, r25, r10);", // IID488 + "__ ecmovl (Assembler::Condition::less, r24, r24, r20);", // IID489 + "__ ecmovl (Assembler::Condition::greaterEqual, r16, rdx, r26);", // IID490 + "__ ecmovl (Assembler::Condition::greaterEqual, r28, r28, r28);", // IID491 + "__ ecmovl (Assembler::Condition::lessEqual, r9, r20, r24);", // IID492 + "__ ecmovl (Assembler::Condition::lessEqual, r24, r24, r29);", // IID493 + "__ ecmovl (Assembler::Condition::greater, r23, r27, r15);", // IID494 + "__ ecmovl (Assembler::Condition::greater, r12, r12, r18);", // IID495 + "__ ecmovl (Assembler::Condition::overflow, r19, r9, Address(r31, rcx, (Address::ScaleFactor)1, -0x2be98bd));", // IID496 + "__ ecmovl (Assembler::Condition::overflow, r8, r8, Address(r21, r24, (Address::ScaleFactor)1, +0x41e6a0cb));", // IID497 + "__ ecmovl (Assembler::Condition::noOverflow, r23, r15, Address(r19, r30, (Address::ScaleFactor)3, -0x55adfe2d));", // IID498 + "__ ecmovl (Assembler::Condition::noOverflow, rdx, rdx, Address(r27, rdx, (Address::ScaleFactor)0, -0x1aa12735));", // IID499 + "__ ecmovl (Assembler::Condition::below, rbx, r29, Address(r31, r12, (Address::ScaleFactor)0, +0xbd42246));", // IID500 + "__ ecmovl (Assembler::Condition::below, r21, r21, Address(r19, r21, (Address::ScaleFactor)1, -0x41518818));", // IID501 + "__ ecmovl (Assembler::Condition::aboveEqual, r23, r29, Address(r22, r9, (Address::ScaleFactor)2, -0x35addbd8));", // IID502 + "__ ecmovl (Assembler::Condition::aboveEqual, r18, r18, Address(r25, +0x632184c3));", // IID503 + "__ ecmovl (Assembler::Condition::zero, r29, r13, Address(r18, r13, (Address::ScaleFactor)0, -0x3972eac6));", // IID504 + "__ ecmovl (Assembler::Condition::zero, r29, r29, Address(r12, r9, (Address::ScaleFactor)3, -0x668cdfd2));", // IID505 + "__ ecmovl (Assembler::Condition::notZero, r25, r18, Address(r9, r22, (Address::ScaleFactor)2, +0x7f6ac91f));", // IID506 + "__ ecmovl (Assembler::Condition::notZero, r28, r28, Address(r30, +0x562e6594));", // IID507 + "__ ecmovl (Assembler::Condition::belowEqual, r27, r24, Address(r15, r20, (Address::ScaleFactor)2, -0x466538b7));", // IID508 + "__ ecmovl (Assembler::Condition::belowEqual, r25, r25, Address(r26, r11, (Address::ScaleFactor)3, -0x593812a9));", // IID509 + "__ ecmovl (Assembler::Condition::above, rcx, r20, Address(r16, -0x1389a3eb));", // IID510 + "__ ecmovl (Assembler::Condition::above, rbx, rbx, Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615));", // IID511 + "__ ecmovl (Assembler::Condition::negative, rdx, r14, Address(r12, r28, (Address::ScaleFactor)1, -0x51725a91));", // IID512 + "__ ecmovl (Assembler::Condition::negative, r24, r24, Address(r17, r18, (Address::ScaleFactor)1, -0x1725c4e4));", // IID513 + "__ ecmovl (Assembler::Condition::positive, rcx, rcx, Address(r15, r23, (Address::ScaleFactor)2, -0x6bd22ccf));", // IID514 + "__ ecmovl (Assembler::Condition::positive, r24, r24, Address(r15, r10, (Address::ScaleFactor)1, -0x7ffb3d09));", // IID515 + "__ ecmovl (Assembler::Condition::parity, r23, rcx, Address(r11, r23, (Address::ScaleFactor)0, +0x3738c585));", // IID516 + "__ ecmovl (Assembler::Condition::parity, r24, r24, Address(r30, r10, (Address::ScaleFactor)0, +0xfcc15a8));", // IID517 + "__ ecmovl (Assembler::Condition::noParity, r14, r26, Address(r14, r21, (Address::ScaleFactor)1, -0x4430ce9f));", // IID518 + "__ ecmovl (Assembler::Condition::noParity, r10, r10, Address(r28, +0x3d7c59f));", // IID519 + "__ ecmovl (Assembler::Condition::less, r10, r21, Address(r8, r8, (Address::ScaleFactor)3, +0x4a6584b4));", // IID520 + "__ ecmovl (Assembler::Condition::less, r26, r26, Address(r19, r20, (Address::ScaleFactor)3, +0x47c660ef));", // IID521 + "__ ecmovl (Assembler::Condition::greaterEqual, r26, r10, Address(rcx, +0x61977a97));", // IID522 + "__ ecmovl (Assembler::Condition::greaterEqual, r30, r30, Address(r15, r19, (Address::ScaleFactor)3, +0x53c601cb));", // IID523 + "__ ecmovl (Assembler::Condition::lessEqual, r14, r9, Address(r17, -0x566ceee2));", // IID524 + "__ ecmovl (Assembler::Condition::lessEqual, r15, r15, Address(r27, r20, (Address::ScaleFactor)0, +0x76164792));", // IID525 + "__ ecmovl (Assembler::Condition::greater, r27, r14, Address(r9, r13, (Address::ScaleFactor)2, +0xf5752d7));", // IID526 + "__ ecmovl (Assembler::Condition::greater, r12, r12, Address(rbx, rcx, (Address::ScaleFactor)3, -0x5501b4c6));", // IID527 + "__ adcq(r30, r31);", // IID528 + "__ cmpq(r12, rdx);", // IID529 + "__ imulq(r21, r24);", // IID530 + "__ popcntq(r9, r25);", // IID531 + "__ sbbq(r8, r12);", // IID532 + "__ subq(r31, r24);", // IID533 + "__ tzcntq(r10, r16);", // IID534 + "__ lzcntq(r20, r21);", // IID535 + "__ addq(rdx, r17);", // IID536 + "__ andq(r14, r13);", // IID537 + "__ orq(r20, r24);", // IID538 + "__ xorq(r21, r22);", // IID539 + "__ movq(r12, r27);", // IID540 + "__ bsfq(r23, rdx);", // IID541 + "__ bsrq(r31, r28);", // IID542 + "__ btq(r8, r25);", // IID543 + "__ xchgq(r21, rbx);", // IID544 + "__ testq(r23, r23);", // IID545 + "__ addq(Address(r19, -0x180d3ea1), r10);", // IID546 + "__ andq(Address(r11, r17, (Address::ScaleFactor)1, -0x78976be8), r25);", // IID547 + "__ cmpq(Address(rbx, r28, (Address::ScaleFactor)3, +0x35f72102), r13);", // IID548 + "__ orq(Address(r8, -0x34465011), r21);", // IID549 + "__ xorq(Address(r19, -0x404b22dd), r18);", // IID550 + "__ subq(Address(r23, r27, (Address::ScaleFactor)3, -0x428d2646), r14);", // IID551 + "__ movq(Address(r9, rcx, (Address::ScaleFactor)2, -0x72611661), r28);", // IID552 + "__ xaddq(Address(r24, r21, (Address::ScaleFactor)2, +0x3a6be990), rbx);", // IID553 + "__ andq(Address(r22, r10, (Address::ScaleFactor)0, +0x7ef8bdd), 1048576);", // IID554 + "__ addq(Address(r13, r28, (Address::ScaleFactor)0, -0x754789b1), 65536);", // IID555 + "__ cmpq(Address(r10, -0xbd2a8da), 268435456);", // IID556 + "__ sarq(Address(r23, r14, (Address::ScaleFactor)1, +0x6a16d9f5), 4);", // IID557 + "__ salq(Address(rcx, r21, (Address::ScaleFactor)1, +0x5f66ac1e), 8);", // IID558 + "__ sbbq(Address(rcx, r22, (Address::ScaleFactor)3, -0x48c954c), 268435456);", // IID559 + "__ shrq(Address(r21, r30, (Address::ScaleFactor)0, +0xe405b0b), 8);", // IID560 + "__ subq(Address(r19, r29, (Address::ScaleFactor)3, -0x7762044b), 4096);", // IID561 + "__ xorq(Address(r30, r10, (Address::ScaleFactor)1, -0x19798323), 16);", // IID562 + "__ orq(Address(rdx, r24, (Address::ScaleFactor)3, +0x18d9b316), 4096);", // IID563 + "__ movq(Address(rbx, -0x3058074d), 256);", // IID564 + "__ testq(Address(r28, r21, (Address::ScaleFactor)3, +0x65a0fdc4), -268435456);", // IID565 + "__ addq(r23, Address(r11, r18, (Address::ScaleFactor)0, -0x1d1af10c));", // IID566 + "__ andq(r22, Address(r18, r12, (Address::ScaleFactor)1, +0x1a5f1c38));", // IID567 + "__ cmpq(r23, Address(r30, r19, (Address::ScaleFactor)0, -0x3e912f7f));", // IID568 + "__ lzcntq(r29, Address(rcx, +0x12e3fbe4));", // IID569 + "__ orq(r14, Address(r21, r21, (Address::ScaleFactor)2, +0xd73042));", // IID570 + "__ adcq(r31, Address(r17, r31, (Address::ScaleFactor)2, +0xabde912));", // IID571 + "__ imulq(r20, Address(r13, r27, (Address::ScaleFactor)0, -0x58dbfc1f));", // IID572 + "__ popcntq(rbx, Address(r22, -0x72c66c23));", // IID573 + "__ sbbq(r26, Address(r9, +0x334aba09));", // IID574 + "__ subq(r9, Address(r9, r30, (Address::ScaleFactor)3, -0x219a6102));", // IID575 + "__ tzcntq(r25, Address(r20, -0x2131bab1));", // IID576 + "__ xorq(r16, Address(r28, r16, (Address::ScaleFactor)1, +0x48c483b9));", // IID577 + "__ movq(r30, Address(r9, r16, (Address::ScaleFactor)0, -0x88ce84f));", // IID578 + "__ leaq(r11, Address(r30, r29, (Address::ScaleFactor)2, +0x3eeb8fd0));", // IID579 + "__ cvttsd2siq(r26, Address(r29, r10, (Address::ScaleFactor)3, +0x3ef4822e));", // IID580 + "__ xchgq(r29, Address(r19, r20, (Address::ScaleFactor)2, -0x3f0f3db9));", // IID581 + "__ testq(r8, Address(r30, r20, (Address::ScaleFactor)0, +0x15b56a17));", // IID582 + "__ addq(r26, 4096);", // IID583 + "__ andq(r20, 16);", // IID584 + "__ adcq(r23, 1048576);", // IID585 + "__ cmpq(r12, 4096);", // IID586 + "__ rclq(rcx, 4);", // IID587 + "__ rcrq(r14, 1);", // IID588 + "__ rolq(r23, 2);", // IID589 + "__ rorq(r12, 4);", // IID590 + "__ sarq(r10, 4);", // IID591 + "__ salq(r20, 4);", // IID592 + "__ sbbq(rcx, 1048576);", // IID593 + "__ shlq(r23, 16);", // IID594 + "__ shrq(r27, 2);", // IID595 + "__ subq(rcx, 65536);", // IID596 + "__ xorq(r9, 1048576);", // IID597 + "__ movq(r16, 65536);", // IID598 + "__ mov64(r24, 4503599627370496);", // IID599 + "__ btq(r18, 64);", // IID600 + "__ testq(r29, -4096);", // IID601 + "__ orq_imm32(r30, 67108864);", // IID602 + "__ subq_imm32(r25, 268435456);", // IID603 + "__ cmovq(Assembler::Condition::overflow, r30, Address(r17, r31, (Address::ScaleFactor)2, +0x47ff92f0));", // IID604 + "__ cmovq(Assembler::Condition::noOverflow, r9, Address(r24, r28, (Address::ScaleFactor)1, +0x384904c0));", // IID605 + "__ cmovq(Assembler::Condition::below, r23, Address(r23, r24, (Address::ScaleFactor)3, -0x197f1266));", // IID606 + "__ cmovq(Assembler::Condition::aboveEqual, r9, Address(r29, r30, (Address::ScaleFactor)0, +0x2b5d49c8));", // IID607 + "__ cmovq(Assembler::Condition::zero, r16, Address(rbx, r15, (Address::ScaleFactor)1, +0x22379381));", // IID608 + "__ cmovq(Assembler::Condition::notZero, r8, Address(r11, +0x49d67a0));", // IID609 + "__ cmovq(Assembler::Condition::belowEqual, r28, Address(r16, r16, (Address::ScaleFactor)2, -0x5e941da9));", // IID610 + "__ cmovq(Assembler::Condition::above, r19, Address(r18, r8, (Address::ScaleFactor)0, -0xa5e55ec));", // IID611 + "__ cmovq(Assembler::Condition::negative, r28, Address(r17, r28, (Address::ScaleFactor)1, -0x3264220c));", // IID612 + "__ cmovq(Assembler::Condition::positive, r31, Address(r14, r31, (Address::ScaleFactor)1, +0x5001bc5a));", // IID613 + "__ cmovq(Assembler::Condition::parity, rbx, Address(r18, r17, (Address::ScaleFactor)2, -0x286f2379));", // IID614 + "__ cmovq(Assembler::Condition::noParity, r17, Address(r20, -0x5549f838));", // IID615 + "__ cmovq(Assembler::Condition::less, r30, Address(r9, r28, (Address::ScaleFactor)1, -0x25b00cf3));", // IID616 + "__ cmovq(Assembler::Condition::greaterEqual, r19, Address(r9, -0x2aabf22c));", // IID617 + "__ cmovq(Assembler::Condition::lessEqual, rbx, Address(rcx, r12, (Address::ScaleFactor)1, -0x432d68cc));", // IID618 + "__ cmovq(Assembler::Condition::greater, rbx, Address(r15, r17, (Address::ScaleFactor)3, -0x2b97565e));", // IID619 + "__ call(r24);", // IID620 + "__ divq(r9);", // IID621 + "__ idivq(r28);", // IID622 + "__ imulq(rdx);", // IID623 + "__ mulq(r31);", // IID624 + "__ negq(r12);", // IID625 + "__ notq(r12);", // IID626 + "__ rolq(r24);", // IID627 + "__ rorq(r28);", // IID628 + "__ sarq(r11);", // IID629 + "__ salq(r27);", // IID630 + "__ shlq(r23);", // IID631 + "__ shrq(r17);", // IID632 + "__ incrementq(r16);", // IID633 + "__ decrementq(r12);", // IID634 + "__ pushp(r23);", // IID635 + "__ popp(r24);", // IID636 + "__ call(Address(r18, r14, (Address::ScaleFactor)0, -0x66639d32));", // IID637 + "__ mulq(Address(r24, -0x660a2421));", // IID638 + "__ negq(Address(r14, r18, (Address::ScaleFactor)0, +0x40f3936e));", // IID639 + "__ sarq(Address(r10, r13, (Address::ScaleFactor)0, +0x7d04cb72));", // IID640 + "__ salq(Address(r18, r11, (Address::ScaleFactor)3, -0x2176b4dc));", // IID641 + "__ shrq(Address(r13, rcx, (Address::ScaleFactor)1, +0x7996aa80));", // IID642 + "__ incrementq(Address(r14, +0x67c2d02a));", // IID643 + "__ decrementq(Address(r22, r26, (Address::ScaleFactor)0, +0x224f62c0));", // IID644 + "__ imulq(rdx, Address(r31, rbx, (Address::ScaleFactor)1, +0x2b00bb10), 16777216);", // IID645 + "__ imulq(r21, r31, 4096);", // IID646 + "__ shldq(rbx, r19, 1);", // IID647 + "__ shrdq(r11, r23, 4);", // IID648 + "__ pop2(r16, r30);", // IID649 + "__ pop2p(r17, rbx);", // IID650 + "__ push2(r20, r30);", // IID651 + "__ push2p(r8, r31);", // IID652 + "__ movzbq(r28, Address(r8, r14, (Address::ScaleFactor)0, +0x469ae67a));", // IID653 + "__ movzwq(r14, Address(r8, r18, (Address::ScaleFactor)2, -0x48699e02));", // IID654 + "__ movsbq(r21, Address(rbx, -0x64dae06b));", // IID655 + "__ movswq(r19, Address(r31, rbx, (Address::ScaleFactor)2, +0x60318819));", // IID656 + "__ movzbq(r30, r13);", // IID657 + "__ movzwq(r30, r18);", // IID658 + "__ movsbq(r19, r15);", // IID659 + "__ movswq(r20, r16);", // IID660 + "__ cmpxchgq(r28, Address(r11, rbx, (Address::ScaleFactor)3, +0xfc3479d));", // IID661 + "__ eidivq(r20, false);", // IID662 + "__ eidivq(r30, true);", // IID663 + "__ edivq(r22, false);", // IID664 + "__ edivq(r11, true);", // IID665 + "__ eimulq(rcx, false);", // IID666 + "__ eimulq(r28, true);", // IID667 + "__ emulq(r21, false);", // IID668 + "__ emulq(r13, true);", // IID669 + "__ emulq(Address(r26, r15, (Address::ScaleFactor)2, +0x70a1ce6e), false);", // IID670 + "__ emulq(Address(r24, r19, (Address::ScaleFactor)1, -0x1670855c), true);", // IID671 + "__ eimulq(r10, r27, false);", // IID672 + "__ eimulq(r17, r17, false);", // IID673 + "__ eimulq(rdx, r22, true);", // IID674 + "__ eimulq(rbx, rbx, true);", // IID675 + "__ elzcntq(r28, r15, false);", // IID676 + "__ elzcntq(r15, r15, false);", // IID677 + "__ elzcntq(rbx, r12, true);", // IID678 + "__ elzcntq(rbx, rbx, true);", // IID679 + "__ enegq(r26, r11, false);", // IID680 + "__ enegq(r17, r17, false);", // IID681 + "__ enegq(rdx, r31, true);", // IID682 + "__ enegq(r27, r27, true);", // IID683 + "__ enotq(r31, r15);", // IID684 + "__ enotq(r21, r21);", // IID685 + "__ epopcntq(rbx, r24, false);", // IID686 + "__ epopcntq(r28, r28, false);", // IID687 + "__ epopcntq(r23, r27, true);", // IID688 + "__ epopcntq(r13, r13, true);", // IID689 + "__ erolq(r25, r28, false);", // IID690 + "__ erolq(r31, r31, false);", // IID691 + "__ erolq(r25, r23, true);", // IID692 + "__ erolq(rcx, rcx, true);", // IID693 + "__ erorq(r22, r14, false);", // IID694 + "__ erorq(r15, r15, false);", // IID695 + "__ erorq(r11, r30, true);", // IID696 + "__ erorq(r24, r24, true);", // IID697 + "__ esalq(r10, r20, false);", // IID698 + "__ esalq(r19, r19, false);", // IID699 + "__ esalq(r17, r25, true);", // IID700 + "__ esalq(r13, r13, true);", // IID701 + "__ esarq(r31, r30, false);", // IID702 + "__ esarq(r18, r18, false);", // IID703 + "__ esarq(r25, r25, true);", // IID704 + "__ esarq(r28, r28, true);", // IID705 + "__ edecq(r22, r27, false);", // IID706 + "__ edecq(r12, r12, false);", // IID707 + "__ edecq(r18, r11, true);", // IID708 + "__ edecq(r10, r10, true);", // IID709 + "__ eincq(r20, r24, false);", // IID710 + "__ eincq(r18, r18, false);", // IID711 + "__ eincq(rbx, r11, true);", // IID712 + "__ eincq(r26, r26, true);", // IID713 + "__ eshlq(r21, r8, false);", // IID714 + "__ eshlq(rbx, rbx, false);", // IID715 + "__ eshlq(r22, r21, true);", // IID716 + "__ eshlq(r27, r27, true);", // IID717 + "__ eshrq(r12, r16, false);", // IID718 + "__ eshrq(r8, r8, false);", // IID719 + "__ eshrq(rdx, r9, true);", // IID720 + "__ eshrq(r20, r20, true);", // IID721 + "__ etzcntq(r31, r21, false);", // IID722 + "__ etzcntq(r20, r20, false);", // IID723 + "__ etzcntq(rcx, r16, true);", // IID724 + "__ etzcntq(r14, r14, true);", // IID725 + "__ eimulq(r27, Address(r25, r9, (Address::ScaleFactor)1, +0x445a2393), false);", // IID726 + "__ eimulq(r23, Address(rcx, r9, (Address::ScaleFactor)1, -0x1480ef0c), true);", // IID727 + "__ elzcntq(r13, Address(r22, r17, (Address::ScaleFactor)1, -0x750c1996), false);", // IID728 + "__ elzcntq(r13, Address(r31, -0x342b6259), true);", // IID729 + "__ enegq(r31, Address(r24, r13, (Address::ScaleFactor)1, -0x25b16a0e), false);", // IID730 + "__ enegq(r13, Address(r11, r28, (Address::ScaleFactor)3, +0x5c0013ab), true);", // IID731 + "__ epopcntq(rdx, Address(r18, rcx, (Address::ScaleFactor)2, -0x6113eaaf), false);", // IID732 + "__ epopcntq(r9, Address(r10, -0x5ca7d588), true);", // IID733 + "__ esalq(r17, Address(r27, r30, (Address::ScaleFactor)0, +0x1b4cda2c), false);", // IID734 + "__ esalq(r25, Address(r12, rdx, (Address::ScaleFactor)1, +0x62823bce), true);", // IID735 + "__ esarq(r9, Address(r10, r18, (Address::ScaleFactor)2, -0x264a7a48), false);", // IID736 + "__ esarq(rbx, Address(r14, r27, (Address::ScaleFactor)0, +0x20291e00), true);", // IID737 + "__ edecq(r12, Address(r15, r14, (Address::ScaleFactor)2, -0x20f7dabb), false);", // IID738 + "__ edecq(r9, Address(r10, r25, (Address::ScaleFactor)1, +0x21411d84), true);", // IID739 + "__ eincq(r20, Address(rbx, r25, (Address::ScaleFactor)3, +0x2f0329e), false);", // IID740 + "__ eincq(r10, Address(r12, r31, (Address::ScaleFactor)0, -0x37505c8c), true);", // IID741 + "__ eshrq(r24, Address(r23, r14, (Address::ScaleFactor)3, -0x71e75ab0), false);", // IID742 + "__ eshrq(r25, Address(r19, r10, (Address::ScaleFactor)1, +0x507b0a88), true);", // IID743 + "__ etzcntq(r31, Address(rbx, r16, (Address::ScaleFactor)0, +0x19d5192a), false);", // IID744 + "__ etzcntq(r9, Address(r22, r28, (Address::ScaleFactor)2, +0x211007cd), true);", // IID745 + "__ eaddq(r16, Address(r21, rbx, (Address::ScaleFactor)3, -0x823fa1e), r28, false);", // IID746 + "__ eaddq(r15, Address(rdx, r8, (Address::ScaleFactor)3, -0x34b9a058), r15, false);", // IID747 + "__ eaddq(r24, Address(r14, r24, (Address::ScaleFactor)3, +0x6cdc59d2), r13, true);", // IID748 + "__ eaddq(rbx, Address(r27, r14, (Address::ScaleFactor)3, +0x36c5e8de), rbx, true);", // IID749 + "__ eandq(r21, Address(r27, r27, (Address::ScaleFactor)1, -0x2c023b13), r27, false);", // IID750 + "__ eandq(r31, Address(r21, r15, (Address::ScaleFactor)2, +0x6ef2c74a), r31, false);", // IID751 + "__ eandq(r13, Address(r31, r25, (Address::ScaleFactor)1, +0x734fe9ab), r27, true);", // IID752 + "__ eandq(r15, Address(r14, r29, (Address::ScaleFactor)3, -0x6e68556), r15, true);", // IID753 + "__ eorq(r12, Address(r30, r15, (Address::ScaleFactor)3, +0x3ba33f9e), r28, false);", // IID754 + "__ eorq(r16, Address(r12, r9, (Address::ScaleFactor)0, -0x28e03b33), r16, false);", // IID755 + "__ eorq(r8, Address(r8, r25, (Address::ScaleFactor)3, -0x1e42bd95), r27, true);", // IID756 + "__ eorq(rcx, Address(r27, rbx, (Address::ScaleFactor)2, +0x7be4bcad), rcx, true);", // IID757 + "__ esubq(r24, Address(r23, r22, (Address::ScaleFactor)2, +0x6f8827d7), rdx, false);", // IID758 + "__ esubq(r21, Address(r10, -0x635b8c8), r21, false);", // IID759 + "__ esubq(r23, Address(r27, r26, (Address::ScaleFactor)3, +0x922bcc0), rbx, true);", // IID760 + "__ esubq(r25, Address(r23, r15, (Address::ScaleFactor)0, -0x38f494ac), r25, true);", // IID761 + "__ exorq(r11, Address(r12, r19, (Address::ScaleFactor)2, -0x5b71ec17), rcx, false);", // IID762 + "__ exorq(r28, Address(r19, r18, (Address::ScaleFactor)0, +0x716b9b7e), r28, false);", // IID763 + "__ exorq(r21, Address(rcx, r29, (Address::ScaleFactor)0, -0x5af0441e), r16, true);", // IID764 + "__ exorq(r12, Address(r20, r26, (Address::ScaleFactor)0, +0xe0b7fb1), r12, true);", // IID765 + "__ eaddq(r30, Address(rcx, +0x2d3b7b4f), 1048576, false);", // IID766 + "__ eaddq(r14, Address(r21, r15, (Address::ScaleFactor)2, -0x1222aee8), 4096, true);", // IID767 + "__ eandq(r23, Address(r20, r31, (Address::ScaleFactor)0, -0x96e4d6a), 16, false);", // IID768 + "__ eandq(r10, Address(rdx, rdx, (Address::ScaleFactor)3, +0x3875f17c), 1, true);", // IID769 + "__ eimulq(r17, Address(rcx, r25, (Address::ScaleFactor)2, +0x32c71076), 4096, false);", // IID770 + "__ eimulq(r19, Address(r31, rbx, (Address::ScaleFactor)2, +0x7bada60d), 1048576, true);", // IID771 + "__ eorq(r25, Address(r18, r23, (Address::ScaleFactor)1, +0x48147444), 16777216, false);", // IID772 + "__ eorq(r29, Address(r26, r27, (Address::ScaleFactor)1, -0x4b113958), 1048576, true);", // IID773 + "__ esalq(r31, Address(r18, -0x46103c74), 2, false);", // IID774 + "__ esalq(r25, Address(r10, r15, (Address::ScaleFactor)0, +0x48925da4), 16, true);", // IID775 + "__ esarq(r26, Address(r18, -0x5ea1c542), 8, false);", // IID776 + "__ esarq(r12, Address(r10, r22, (Address::ScaleFactor)2, +0x5d958264), 8, true);", // IID777 + "__ eshrq(rdx, Address(r17, r20, (Address::ScaleFactor)2, +0x295add23), 16, false);", // IID778 + "__ eshrq(rbx, Address(r22, r28, (Address::ScaleFactor)1, +0x782929cb), 2, true);", // IID779 + "__ esubq(r19, Address(r23, -0x49811d72), 1, false);", // IID780 + "__ esubq(r8, Address(r19, r14, (Address::ScaleFactor)2, -0x1b2bae9a), 1048576, true);", // IID781 + "__ exorq(r19, Address(rcx, r10, (Address::ScaleFactor)0, +0x45a66ee9), 1048576, false);", // IID782 + "__ exorq(r28, Address(r9, r29, (Address::ScaleFactor)0, -0x28a19314), 16, true);", // IID783 + "__ eaddq(r8, rcx, 16777216, false);", // IID784 + "__ eaddq(rax, r14, 16777216, false);", // IID785 + "__ eaddq(r16, r16, 256, false);", // IID786 + "__ eaddq(r24, r9, 4096, true);", // IID787 + "__ eaddq(rax, r18, 4096, true);", // IID788 + "__ eaddq(r8, r8, 1, true);", // IID789 + "__ eandq(r15, r22, 1048576, false);", // IID790 + "__ eandq(rax, r26, 1048576, false);", // IID791 + "__ eandq(rdx, rdx, 4096, false);", // IID792 + "__ eandq(rdx, r22, 268435456, true);", // IID793 + "__ eandq(rax, r29, 268435456, true);", // IID794 + "__ eandq(r23, r23, 16777216, true);", // IID795 + "__ eimulq(r9, r13, 1048576, false);", // IID796 + "__ eimulq(rax, r18, 1048576, false);", // IID797 + "__ eimulq(r16, r16, 1048576, false);", // IID798 + "__ eimulq(r17, r23, 1, true);", // IID799 + "__ eimulq(rax, r12, 1, true);", // IID800 + "__ eimulq(r10, r10, 268435456, true);", // IID801 + "__ eorq(rdx, r19, 256, false);", // IID802 + "__ eorq(rax, r14, 256, false);", // IID803 + "__ eorq(r13, r13, 1, false);", // IID804 + "__ eorq(r25, r29, 256, true);", // IID805 + "__ eorq(rax, rdx, 256, true);", // IID806 + "__ eorq(r16, r16, 16, true);", // IID807 + "__ erclq(r13, r19, 4);", // IID808 + "__ erclq(rax, r12, 4);", // IID809 + "__ erclq(r9, r9, 4);", // IID810 + "__ erolq(r13, r16, 1, false);", // IID811 + "__ erolq(rax, r31, 1, false);", // IID812 + "__ erolq(r30, r30, 8, false);", // IID813 + "__ erolq(r30, r20, 8, true);", // IID814 + "__ erolq(rax, r31, 8, true);", // IID815 + "__ erolq(r31, r31, 4, true);", // IID816 + "__ erorq(r22, r10, 4, false);", // IID817 + "__ erorq(rax, r13, 4, false);", // IID818 + "__ erorq(r24, r24, 16, false);", // IID819 + "__ erorq(r29, r22, 16, true);", // IID820 + "__ erorq(rax, r20, 16, true);", // IID821 + "__ erorq(r27, r27, 4, true);", // IID822 + "__ esalq(r31, r19, 2, false);", // IID823 + "__ esalq(rax, r20, 2, false);", // IID824 + "__ esalq(r11, r11, 8, false);", // IID825 + "__ esalq(rdx, r15, 1, true);", // IID826 + "__ esalq(rax, r10, 1, true);", // IID827 + "__ esalq(r29, r29, 4, true);", // IID828 + "__ esarq(r20, r16, 1, false);", // IID829 + "__ esarq(rax, r21, 1, false);", // IID830 + "__ esarq(r28, r28, 8, false);", // IID831 + "__ esarq(r30, rcx, 4, true);", // IID832 + "__ esarq(rax, r15, 4, true);", // IID833 + "__ esarq(rcx, rcx, 4, true);", // IID834 + "__ eshlq(rdx, r26, 4, false);", // IID835 + "__ eshlq(rax, r26, 4, false);", // IID836 + "__ eshlq(r8, r8, 4, false);", // IID837 + "__ eshlq(rcx, rcx, 1, true);", // IID838 + "__ eshlq(rax, rcx, 1, true);", // IID839 + "__ eshlq(r13, r13, 2, true);", // IID840 + "__ eshrq(r14, r27, 2, false);", // IID841 + "__ eshrq(rax, r11, 2, false);", // IID842 + "__ eshrq(r9, r9, 16, false);", // IID843 + "__ eshrq(rdx, r31, 2, true);", // IID844 + "__ eshrq(rax, r14, 2, true);", // IID845 + "__ eshrq(r12, r12, 8, true);", // IID846 + "__ esubq(r10, r28, 1, false);", // IID847 + "__ esubq(rax, r8, 1, false);", // IID848 + "__ esubq(rcx, rcx, 16777216, false);", // IID849 + "__ esubq(rdx, rbx, 16777216, true);", // IID850 + "__ esubq(rax, r18, 16777216, true);", // IID851 + "__ esubq(r27, r27, 65536, true);", // IID852 + "__ exorq(r30, rcx, 4096, false);", // IID853 + "__ exorq(rax, r21, 4096, false);", // IID854 + "__ exorq(rcx, rcx, 16777216, false);", // IID855 + "__ exorq(r21, r12, 1, true);", // IID856 + "__ exorq(rax, rdx, 1, true);", // IID857 + "__ exorq(rbx, rbx, 16777216, true);", // IID858 + "__ eorq_imm32(r11, rdx, 65536, false);", // IID859 + "__ eorq_imm32(rax, r14, 65536, false);", // IID860 + "__ eorq_imm32(r14, r14, 262144, false);", // IID861 + "__ eorq_imm32(r25, r29, 262144, false);", // IID862 + "__ eorq_imm32(rax, r21, 262144, false);", // IID863 + "__ eorq_imm32(r11, r11, 16777216, false);", // IID864 + "__ esubq_imm32(r29, r19, 67108864, false);", // IID865 + "__ esubq_imm32(rax, r11, 67108864, false);", // IID866 + "__ esubq_imm32(r18, r18, 67108864, false);", // IID867 + "__ esubq_imm32(r28, r23, 4194304, true);", // IID868 + "__ esubq_imm32(rax, r21, 4194304, true);", // IID869 + "__ esubq_imm32(r16, r16, 16777216, true);", // IID870 + "__ eaddq(r8, r25, Address(r26, r8, (Address::ScaleFactor)1, +0x10633def), false);", // IID871 + "__ eaddq(r13, r13, Address(r18, r16, (Address::ScaleFactor)1, -0x74204508), false);", // IID872 + "__ eaddq(r17, r26, Address(r12, +0x23a80abf), true);", // IID873 + "__ eaddq(r9, r9, Address(r29, r19, (Address::ScaleFactor)0, -0x29e9e52), true);", // IID874 + "__ eandq(r9, r28, Address(rcx, r25, (Address::ScaleFactor)2, +0x4261ffaa), false);", // IID875 + "__ eandq(r27, r27, Address(rdx, r28, (Address::ScaleFactor)0, -0x26bdc9c1), false);", // IID876 + "__ eandq(r14, r11, Address(r16, +0x63ba0ddf), true);", // IID877 + "__ eandq(r8, r8, Address(r22, r25, (Address::ScaleFactor)1, -0x43b6ab44), true);", // IID878 + "__ eorq(r19, rcx, Address(r27, rcx, (Address::ScaleFactor)2, -0x7f687fc6), false);", // IID879 + "__ eorq(r19, r19, Address(rbx, r26, (Address::ScaleFactor)1, -0x486db7ea), false);", // IID880 + "__ eorq(r30, r10, Address(r14, r18, (Address::ScaleFactor)3, +0x14884884), true);", // IID881 + "__ eorq(r27, r27, Address(r29, +0x20337180), true);", // IID882 + "__ eimulq(rcx, r21, Address(r21, rbx, (Address::ScaleFactor)0, -0x3303888e), false);", // IID883 + "__ eimulq(rdx, rdx, Address(r28, r9, (Address::ScaleFactor)3, -0x7ad8f741), false);", // IID884 + "__ eimulq(r8, r29, Address(r17, r12, (Address::ScaleFactor)0, +0x6e85396a), true);", // IID885 + "__ eimulq(r16, r16, Address(r19, r10, (Address::ScaleFactor)3, -0x49599300), true);", // IID886 + "__ esubq(r20, r17, Address(r13, r22, (Address::ScaleFactor)0, +0x1d219a4f), false);", // IID887 + "__ esubq(r25, r25, Address(r21, r21, (Address::ScaleFactor)3, -0x6868a8c7), false);", // IID888 + "__ esubq(r20, r24, Address(rbx, r20, (Address::ScaleFactor)2, +0x32c59da6), true);", // IID889 + "__ esubq(r8, r8, Address(r12, r17, (Address::ScaleFactor)0, -0x26be2dcf), true);", // IID890 + "__ exorq(rdx, r19, Address(r9, +0x7d903b91), false);", // IID891 + "__ exorq(r28, r28, Address(r29, r27, (Address::ScaleFactor)2, +0x53091f6f), false);", // IID892 + "__ exorq(r17, r16, Address(r27, +0x7c6e9207), true);", // IID893 + "__ exorq(r15, r15, Address(r13, r24, (Address::ScaleFactor)3, -0x75c87960), true);", // IID894 + "__ eaddq(r16, rbx, r18, false);", // IID895 + "__ eaddq(r24, r24, r18, false);", // IID896 + "__ eaddq(r9, r15, r9, false);", // IID897 + "__ eaddq(r19, r26, r13, true);", // IID898 + "__ eaddq(r28, r28, r22, true);", // IID899 + "__ eaddq(r22, r11, r22, true);", // IID900 + "__ eadcxq(rcx, r12, r13);", // IID901 + "__ eadcxq(r30, r30, r12);", // IID902 + "__ eadoxq(r28, r14, r18);", // IID903 + "__ eadoxq(r30, r30, r19);", // IID904 + "__ eandq(r20, r14, r14, false);", // IID905 + "__ eandq(r17, r17, r23, false);", // IID906 + "__ eandq(r17, r14, r17, false);", // IID907 + "__ eandq(r19, r20, r15, true);", // IID908 + "__ eandq(rbx, rbx, r13, true);", // IID909 + "__ eandq(r22, r30, r22, true);", // IID910 + "__ eimulq(r17, r24, rcx, false);", // IID911 + "__ eimulq(r21, r21, r8, false);", // IID912 + "__ eimulq(r29, r21, r29, false);", // IID913 + "__ eimulq(r27, r13, r23, true);", // IID914 + "__ eimulq(r26, r26, r8, true);", // IID915 + "__ eimulq(r22, r13, r22, true);", // IID916 + "__ eorq(r11, rdx, r29, false);", // IID917 + "__ eorq(rdx, rdx, r31, false);", // IID918 + "__ eorq(r10, r29, r10, false);", // IID919 + "__ eorq(r27, r28, rcx, true);", // IID920 + "__ eorq(r25, r25, r9, true);", // IID921 + "__ eorq(rcx, r8, rcx, true);", // IID922 + "__ esubq(rcx, r10, r16, false);", // IID923 + "__ esubq(r17, r17, rcx, false);", // IID924 + "__ esubq(r13, r21, r24, true);", // IID925 + "__ esubq(r31, r31, r28, true);", // IID926 + "__ exorq(r23, r28, r23, false);", // IID927 + "__ exorq(r10, r10, r11, false);", // IID928 + "__ exorq(r19, r18, r19, false);", // IID929 + "__ exorq(r31, r9, rdx, true);", // IID930 + "__ exorq(r13, r13, r9, true);", // IID931 + "__ exorq(rcx, r10, rcx, true);", // IID932 + "__ eshldq(r12, r24, r22, 8, false);", // IID933 + "__ eshldq(r25, r25, r25, 8, false);", // IID934 + "__ eshldq(r21, r20, r15, 8, true);", // IID935 + "__ eshldq(r21, r21, r10, 8, true);", // IID936 + "__ eshrdq(r18, r18, r8, 2, false);", // IID937 + "__ eshrdq(r26, r26, r29, 8, false);", // IID938 + "__ eshrdq(r29, r26, r19, 2, true);", // IID939 + "__ eshrdq(r12, r12, rcx, 4, true);", // IID940 + "__ ecmovq (Assembler::Condition::overflow, r21, r22, r23);", // IID941 + "__ ecmovq (Assembler::Condition::overflow, r9, r9, r13);", // IID942 + "__ ecmovq (Assembler::Condition::noOverflow, rcx, r23, r24);", // IID943 + "__ ecmovq (Assembler::Condition::noOverflow, r28, r28, rdx);", // IID944 + "__ ecmovq (Assembler::Condition::below, r14, r31, r23);", // IID945 + "__ ecmovq (Assembler::Condition::below, r30, r30, r23);", // IID946 + "__ ecmovq (Assembler::Condition::aboveEqual, r10, r29, r22);", // IID947 + "__ ecmovq (Assembler::Condition::aboveEqual, rbx, rbx, r26);", // IID948 + "__ ecmovq (Assembler::Condition::zero, r23, r21, r13);", // IID949 + "__ ecmovq (Assembler::Condition::zero, r10, r10, r20);", // IID950 + "__ ecmovq (Assembler::Condition::notZero, rbx, r9, r29);", // IID951 + "__ ecmovq (Assembler::Condition::notZero, r16, r16, r30);", // IID952 + "__ ecmovq (Assembler::Condition::belowEqual, r13, rcx, r29);", // IID953 + "__ ecmovq (Assembler::Condition::belowEqual, r31, r31, r13);", // IID954 + "__ ecmovq (Assembler::Condition::above, r27, r9, r30);", // IID955 + "__ ecmovq (Assembler::Condition::above, r26, r26, r20);", // IID956 + "__ ecmovq (Assembler::Condition::negative, r8, r12, r22);", // IID957 + "__ ecmovq (Assembler::Condition::negative, r31, r31, r17);", // IID958 + "__ ecmovq (Assembler::Condition::positive, r29, rcx, r25);", // IID959 + "__ ecmovq (Assembler::Condition::positive, r22, r22, r14);", // IID960 + "__ ecmovq (Assembler::Condition::parity, rcx, r27, r9);", // IID961 + "__ ecmovq (Assembler::Condition::parity, r22, r22, r11);", // IID962 + "__ ecmovq (Assembler::Condition::noParity, r14, r19, r24);", // IID963 + "__ ecmovq (Assembler::Condition::noParity, r24, r24, r17);", // IID964 + "__ ecmovq (Assembler::Condition::less, r17, r19, r30);", // IID965 + "__ ecmovq (Assembler::Condition::less, r19, r19, r14);", // IID966 + "__ ecmovq (Assembler::Condition::greaterEqual, r25, r11, r29);", // IID967 + "__ ecmovq (Assembler::Condition::greaterEqual, r12, r12, r26);", // IID968 + "__ ecmovq (Assembler::Condition::lessEqual, r11, rbx, r10);", // IID969 + "__ ecmovq (Assembler::Condition::lessEqual, rdx, rdx, r22);", // IID970 + "__ ecmovq (Assembler::Condition::greater, r14, r15, r23);", // IID971 + "__ ecmovq (Assembler::Condition::greater, r8, r8, r24);", // IID972 + "__ ecmovq (Assembler::Condition::overflow, rbx, r31, Address(r10, r8, (Address::ScaleFactor)3, -0x313f60e0));", // IID973 + "__ ecmovq (Assembler::Condition::overflow, r23, r23, Address(rcx, r24, (Address::ScaleFactor)2, +0x17f41d9c));", // IID974 + "__ ecmovq (Assembler::Condition::noOverflow, r31, r11, Address(r16, +0x2c018942));", // IID975 + "__ ecmovq (Assembler::Condition::noOverflow, r11, r11, Address(r16, r20, (Address::ScaleFactor)3, +0x674b6a55));", // IID976 + "__ ecmovq (Assembler::Condition::below, r9, r13, Address(r9, rcx, (Address::ScaleFactor)0, +0x394a11df));", // IID977 + "__ ecmovq (Assembler::Condition::below, r30, r30, Address(rdx, r22, (Address::ScaleFactor)1, -0x6c362b88));", // IID978 + "__ ecmovq (Assembler::Condition::aboveEqual, r13, rcx, Address(r24, rcx, (Address::ScaleFactor)3, +0x46500b66));", // IID979 + "__ ecmovq (Assembler::Condition::aboveEqual, r24, r24, Address(r18, r25, (Address::ScaleFactor)1, +0x53283b7c));", // IID980 + "__ ecmovq (Assembler::Condition::zero, r23, r25, Address(r15, r9, (Address::ScaleFactor)0, -0x5f03031e));", // IID981 + "__ ecmovq (Assembler::Condition::zero, r25, r25, Address(r28, r16, (Address::ScaleFactor)1, -0x53cef514));", // IID982 + "__ ecmovq (Assembler::Condition::notZero, rbx, r25, Address(r24, r25, (Address::ScaleFactor)2, -0x66caac87));", // IID983 + "__ ecmovq (Assembler::Condition::notZero, r16, r16, Address(r27, r30, (Address::ScaleFactor)3, +0x797f455d));", // IID984 + "__ ecmovq (Assembler::Condition::belowEqual, r25, r30, Address(r18, r18, (Address::ScaleFactor)1, +0x1c9daacd));", // IID985 + "__ ecmovq (Assembler::Condition::belowEqual, r22, r22, Address(rcx, r25, (Address::ScaleFactor)1, -0x3dcbfaa9));", // IID986 + "__ ecmovq (Assembler::Condition::above, r24, r26, Address(r25, +0x747060b5));", // IID987 + "__ ecmovq (Assembler::Condition::above, r8, r8, Address(r24, r20, (Address::ScaleFactor)3, +0x47d285f6));", // IID988 + "__ ecmovq (Assembler::Condition::negative, r12, r16, Address(r13, r10, (Address::ScaleFactor)2, +0x34e5b214));", // IID989 + "__ ecmovq (Assembler::Condition::negative, rdx, rdx, Address(r15, r19, (Address::ScaleFactor)0, -0x405138b1));", // IID990 + "__ ecmovq (Assembler::Condition::positive, r18, r21, Address(rbx, r13, (Address::ScaleFactor)2, +0x51b19197));", // IID991 + "__ ecmovq (Assembler::Condition::positive, r24, r24, Address(r11, r31, (Address::ScaleFactor)3, +0x3e01520a));", // IID992 + "__ ecmovq (Assembler::Condition::parity, r29, r26, Address(r10, r25, (Address::ScaleFactor)3, -0x5f7c3872));", // IID993 + "__ ecmovq (Assembler::Condition::parity, r11, r11, Address(r22, r10, (Address::ScaleFactor)3, -0x68731453));", // IID994 + "__ ecmovq (Assembler::Condition::noParity, r20, r15, Address(r9, r25, (Address::ScaleFactor)0, +0x4a37edaa));", // IID995 + "__ ecmovq (Assembler::Condition::noParity, r31, r31, Address(r9, r20, (Address::ScaleFactor)0, +0x4f999f86));", // IID996 + "__ ecmovq (Assembler::Condition::less, r18, r23, Address(r9, r27, (Address::ScaleFactor)0, -0x3410441d));", // IID997 + "__ ecmovq (Assembler::Condition::less, r16, r16, Address(r24, r10, (Address::ScaleFactor)3, +0x52ed66ee));", // IID998 + "__ ecmovq (Assembler::Condition::greaterEqual, r11, r18, Address(rcx, +0x1de09163));", // IID999 + "__ ecmovq (Assembler::Condition::greaterEqual, r14, r14, Address(r24, r23, (Address::ScaleFactor)1, +0x5df3b4da));", // IID1000 + "__ ecmovq (Assembler::Condition::lessEqual, r15, r14, Address(r30, r20, (Address::ScaleFactor)1, +0x5c9ab976));", // IID1001 + "__ ecmovq (Assembler::Condition::lessEqual, r26, r26, Address(r18, r27, (Address::ScaleFactor)2, -0xd8c329));", // IID1002 + "__ ecmovq (Assembler::Condition::greater, r29, r9, Address(r30, r20, (Address::ScaleFactor)3, -0x37a9cf8d));", // IID1003 + "__ ecmovq (Assembler::Condition::greater, r20, r20, Address(r8, rbx, (Address::ScaleFactor)1, +0x1bdc7def));", // IID1004 #endif // _LP64 }; // END Generated code -- do not edit diff --git a/test/hotspot/gtest/x86/x86-asmtest.py b/test/hotspot/gtest/x86/x86-asmtest.py index 7081c64e604..714b7aaea40 100644 --- a/test/hotspot/gtest/x86/x86-asmtest.py +++ b/test/hotspot/gtest/x86/x86-asmtest.py @@ -92,6 +92,8 @@ registers_mapping = { 'r31': {64: 'r31', 32: 'r31d', 16: 'r31w', 8: 'r31b'}, } +commutative_instrs = ['imul', 'add', 'and', 'xor', 'or'] + class Operand(object): def generate(self): return self @@ -400,6 +402,15 @@ class RegMemRegNddInstruction(NFInstruction): self.mem = Address().generate(mem_base, mem_idx, width) self.reg2 = Register().generate(reg2, width) self.generate_operands(self.reg1, self.mem, self.reg2) + self.demote = True + + def astr(self): + if self.demote: + ops = [op.cstr() for op in self.operands] + # imul does not support RegMemReg + if self._aname in commutative_instrs[1:] and ops[0] == ops[2] and (not self.no_flag): + return f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[:2]]) + return super().astr() class RegRegImmNddInstruction(NFInstruction): def __init__(self, name, aname, width, no_flag, reg1, reg2, imm): @@ -448,6 +459,9 @@ class RegRegRegNddInstruction(NFInstruction): ops = [op.cstr() for op in self.operands] if ops[0] == ops[1] and (not self.no_flag): return hdr + f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[1:]]) + if self._aname in commutative_instrs and ops[0] == ops[2] and (not self.no_flag): + return hdr + f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[:2]]) + return hdr + super().astr() class RegRegRegImmNddInstruction(NFInstruction): @@ -574,6 +588,18 @@ def generate(RegOp, ops, print_lp64_flag=True, full_set=False): lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2, test_reg3) instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, reg3=test_reg3) print_instruction(instr, lp64_flag, print_lp64_flag) + + demote = True if TEST_DEMOTION else False + commute = True if op[1] in commutative_instrs else False + if RegOp in [RegRegRegNddInstruction] and demote and commute : + for i in range(len(test_regs) if full_set else 1): + test_reg1 = test_regs[i] if full_set else random.choice(test_regs) + test_reg2 = test_regs[(i + 2) % len(test_regs)] if full_set else random.choice(test_regs) + test_reg3 = test_reg1 + + lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2, test_reg3) + instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, reg3=test_reg3) + print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [MemRegInstruction, RegMemInstruction, MoveRegMemInstruction, CmpxchgInstruction, CondRegMemInstruction, RegMemNddInstruction]: if full_set: @@ -699,7 +725,7 @@ def generate(RegOp, ops, print_lp64_flag=True, full_set=False): print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [RegMemRegNddInstruction, RegRegMemNddInstruction, CondRegRegMemInstruction]: - demote_options = [False] if TEST_DEMOTION and RegOp not in [RegMemRegNddInstruction] else [False, True] + demote_options = [False, True] for demote in demote_options: for i in range(len(test_regs) if full_set else 1): test_reg1 = test_regs[i] if full_set else random.choice(test_regs) @@ -1023,6 +1049,8 @@ instruction_set = { RegMemRegNddInstruction: [ ('eaddl', 'add', 32, False), ('eaddl', 'add', 32, True), + ('eandl', 'and', 32, False), + ('eandl', 'and', 32, True), ('eorl', 'or', 32, False), ('eorl', 'or', 32, True), ('eorb', 'or', 8, False), From e883dec6be8cb2fc44e45a6b4677cca2f4df58ef Mon Sep 17 00:00:00 2001 From: Srinivas Vamsi Parasa Date: Tue, 16 Sep 2025 18:14:07 +0000 Subject: [PATCH 106/120] 8367694: Fix jtreg test failure when Intel APX is enabled for KNL platforms Reviewed-by: sviswanathan, epeter --- src/hotspot/cpu/x86/assembler_x86.cpp | 24 ++++++++++++------------ src/hotspot/cpu/x86/vm_version_x86.cpp | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 49d40447f9f..3f1140c937b 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -13780,7 +13780,7 @@ void Assembler::pdepq(Register dst, Register src1, Address src2) { void Assembler::sarxl(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes, true); emit_int16((unsigned char)0xF7, (0xC0 | encode)); } @@ -13788,7 +13788,7 @@ void Assembler::sarxl(Register dst, Register src1, Register src2) { void Assembler::sarxl(Register dst, Address src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); vex_prefix(src1, src2->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes); emit_int8((unsigned char)0xF7); @@ -13797,7 +13797,7 @@ void Assembler::sarxl(Register dst, Address src1, Register src2) { void Assembler::sarxq(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes, true); emit_int16((unsigned char)0xF7, (0xC0 | encode)); } @@ -13805,7 +13805,7 @@ void Assembler::sarxq(Register dst, Register src1, Register src2) { void Assembler::sarxq(Register dst, Address src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); vex_prefix(src1, src2->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes); emit_int8((unsigned char)0xF7); @@ -13814,7 +13814,7 @@ void Assembler::sarxq(Register dst, Address src1, Register src2) { void Assembler::shlxl(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes, true); emit_int16((unsigned char)0xF7, (0xC0 | encode)); } @@ -13822,7 +13822,7 @@ void Assembler::shlxl(Register dst, Register src1, Register src2) { void Assembler::shlxl(Register dst, Address src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); vex_prefix(src1, src2->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8((unsigned char)0xF7); @@ -13831,7 +13831,7 @@ void Assembler::shlxl(Register dst, Address src1, Register src2) { void Assembler::shlxq(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes, true); emit_int16((unsigned char)0xF7, (0xC0 | encode)); } @@ -13839,7 +13839,7 @@ void Assembler::shlxq(Register dst, Register src1, Register src2) { void Assembler::shlxq(Register dst, Address src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); vex_prefix(src1, src2->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8((unsigned char)0xF7); @@ -13848,7 +13848,7 @@ void Assembler::shlxq(Register dst, Address src1, Register src2) { void Assembler::shrxl(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes, true); emit_int16((unsigned char)0xF7, (0xC0 | encode)); } @@ -13856,7 +13856,7 @@ void Assembler::shrxl(Register dst, Register src1, Register src2) { void Assembler::shrxl(Register dst, Address src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); vex_prefix(src1, src2->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes); emit_int8((unsigned char)0xF7); @@ -13865,7 +13865,7 @@ void Assembler::shrxl(Register dst, Address src1, Register src2) { void Assembler::shrxq(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes, true); emit_int16((unsigned char)0xF7, (0xC0 | encode)); } @@ -13873,7 +13873,7 @@ void Assembler::shrxq(Register dst, Register src1, Register src2) { void Assembler::shrxq(Register dst, Address src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); vex_prefix(src1, src2->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes); emit_int8((unsigned char)0xF7); diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 094ab370190..f380f2ad271 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -1016,16 +1016,6 @@ void VM_Version::get_processor_features() { _features.clear_feature(CPU_AVX10_2); } - // Currently APX support is only enabled for targets supporting AVX512VL feature. - bool apx_supported = os_supports_apx_egprs() && supports_apx_f() && supports_avx512vl(); - if (UseAPX && !apx_supported) { - warning("UseAPX is not supported on this CPU, setting it to false"); - FLAG_SET_DEFAULT(UseAPX, false); - } - - if (!UseAPX) { - _features.clear_feature(CPU_APX_F); - } if (UseAVX < 2) { _features.clear_feature(CPU_AVX2); @@ -1049,6 +1039,7 @@ void VM_Version::get_processor_features() { _features.clear_feature(CPU_VZEROUPPER); _features.clear_feature(CPU_AVX512BW); _features.clear_feature(CPU_AVX512VL); + _features.clear_feature(CPU_APX_F); _features.clear_feature(CPU_AVX512DQ); _features.clear_feature(CPU_AVX512_VNNI); _features.clear_feature(CPU_AVX512_VAES); @@ -1068,6 +1059,17 @@ void VM_Version::get_processor_features() { } } + // Currently APX support is only enabled for targets supporting AVX512VL feature. + bool apx_supported = os_supports_apx_egprs() && supports_apx_f() && supports_avx512vl(); + if (UseAPX && !apx_supported) { + warning("UseAPX is not supported on this CPU, setting it to false"); + FLAG_SET_DEFAULT(UseAPX, false); + } + + if (!UseAPX) { + _features.clear_feature(CPU_APX_F); + } + if (FLAG_IS_DEFAULT(IntelJccErratumMitigation)) { _has_intel_jcc_erratum = compute_has_intel_jcc_erratum(); FLAG_SET_ERGO(IntelJccErratumMitigation, _has_intel_jcc_erratum); From b75e35cb94d17a742d88f23dfd1b016c26a5e63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20H=C3=BCbner?= Date: Tue, 16 Sep 2025 19:17:53 +0000 Subject: [PATCH 107/120] 8365858: FilteredJavaFieldStream is unnecessary Reviewed-by: liach, jsjolen, coleenp, amenkov --- src/hotspot/share/classfile/javaClasses.cpp | 20 ++-- src/hotspot/share/classfile/javaClasses.hpp | 9 +- .../share/classfile/javaClassesImpl.hpp | 3 +- src/hotspot/share/prims/jvmtiEnv.cpp | 6 +- src/hotspot/share/prims/jvmtiTagMap.cpp | 18 ++- src/hotspot/share/runtime/reflectionUtils.cpp | 38 ------ src/hotspot/share/runtime/reflectionUtils.hpp | 109 ------------------ .../jdk/internal/reflect/ConstantPool.java | 7 -- .../ci/runtime/test/TestResolvedJavaType.java | 3 - 9 files changed, 28 insertions(+), 185 deletions(-) delete mode 100644 src/hotspot/share/runtime/reflectionUtils.cpp delete mode 100644 src/hotspot/share/runtime/reflectionUtils.hpp diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index da093936ce5..60a63892518 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -79,7 +79,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/javaThread.hpp" #include "runtime/jniHandles.inline.hpp" -#include "runtime/reflectionUtils.hpp" +#include "runtime/reflection.hpp" #include "runtime/safepoint.hpp" #include "runtime/safepointVerifiers.hpp" #include "runtime/threadSMR.hpp" @@ -3741,20 +3741,17 @@ oop java_lang_reflect_RecordComponent::create(InstanceKlass* holder, RecordCompo return element(); } -int reflect_ConstantPool::_oop_offset; - -#define CONSTANTPOOL_FIELDS_DO(macro) \ - macro(_oop_offset, k, "constantPoolOop", object_signature, false) +int reflect_ConstantPool::_vmholder_offset; void reflect_ConstantPool::compute_offsets() { InstanceKlass* k = vmClasses::reflect_ConstantPool_klass(); - // The field is called ConstantPool* in the sun.reflect.ConstantPool class. - CONSTANTPOOL_FIELDS_DO(FIELD_COMPUTE_OFFSET); + // The field is injected and called Object vmholder in the jdk.internal.reflect.ConstantPool class. + CONSTANTPOOL_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } #if INCLUDE_CDS void reflect_ConstantPool::serialize_offsets(SerializeClosure* f) { - CONSTANTPOOL_FIELDS_DO(FIELD_SERIALIZE_OFFSET); + CONSTANTPOOL_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET); } #endif @@ -3907,13 +3904,15 @@ Handle reflect_ConstantPool::create(TRAPS) { void reflect_ConstantPool::set_cp(oop reflect, ConstantPool* value) { + assert(_vmholder_offset != 0, "Uninitialized vmholder"); oop mirror = value->pool_holder()->java_mirror(); // Save the mirror to get back the constant pool. - reflect->obj_field_put(_oop_offset, mirror); + reflect->obj_field_put(_vmholder_offset, mirror); } ConstantPool* reflect_ConstantPool::get_cp(oop reflect) { - oop mirror = reflect->obj_field(_oop_offset); + assert(_vmholder_offset != 0, "Uninitialized vmholder"); + oop mirror = reflect->obj_field(_vmholder_offset); InstanceKlass* ik = java_lang_Class::as_InstanceKlass(mirror); // Get the constant pool back from the klass. Since class redefinition @@ -5554,5 +5553,4 @@ int InjectedField::compute_offset() { void javaClasses_init() { JavaClasses::compute_offsets(); JavaClasses::check_offsets(); - FilteredFieldsMap::initialize(); // must be done after computing offsets. } diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 6f82ca10fd6..b137f1a8035 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -936,12 +936,16 @@ class java_lang_Module { friend class JavaClasses; }; +#define CONSTANTPOOL_INJECTED_FIELDS(macro) \ + macro(reflect_ConstantPool, vmholder, object_signature, false) + // Interface to jdk.internal.reflect.ConstantPool objects class reflect_ConstantPool { private: // Note that to reduce dependencies on the JDK we compute these - // offsets at run-time. - static int _oop_offset; + // offsets at run-time. This field is the oop offset for the + // actual constant pool, previously called constantPoolOop. + static int _vmholder_offset; static void compute_offsets(); @@ -953,7 +957,6 @@ class reflect_ConstantPool { // Accessors static void set_cp(oop reflect, ConstantPool* value); - static int oop_offset() { CHECK_INIT(_oop_offset); } static ConstantPool* get_cp(oop reflect); diff --git a/src/hotspot/share/classfile/javaClassesImpl.hpp b/src/hotspot/share/classfile/javaClassesImpl.hpp index b450a4e3cc4..5f88f708523 100644 --- a/src/hotspot/share/classfile/javaClassesImpl.hpp +++ b/src/hotspot/share/classfile/javaClassesImpl.hpp @@ -42,7 +42,8 @@ THREAD_INJECTED_FIELDS(macro) \ VTHREAD_INJECTED_FIELDS(macro) \ INTERNALERROR_INJECTED_FIELDS(macro) \ - STACKCHUNK_INJECTED_FIELDS(macro) + STACKCHUNK_INJECTED_FIELDS(macro) \ + CONSTANTPOOL_INJECTED_FIELDS(macro) #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ klass::_##name##_offset = JavaClasses::compute_injected_offset(InjectedFieldID::klass##_##name##_enum); diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 3eb507ba5e3..5642cd9ff8f 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -38,6 +38,7 @@ #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/fieldStreams.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayOop.inline.hpp" @@ -68,7 +69,6 @@ #include "runtime/objectMonitor.inline.hpp" #include "runtime/os.hpp" #include "runtime/osThread.hpp" -#include "runtime/reflectionUtils.hpp" #include "runtime/signature.hpp" #include "runtime/threadHeapSampler.hpp" #include "runtime/threads.hpp" @@ -2841,9 +2841,9 @@ JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ InstanceKlass* ik = InstanceKlass::cast(k); - FilteredJavaFieldStream flds(ik); + JavaFieldStream flds(ik); - int result_count = flds.field_count(); + int result_count = ik->java_fields_count(); // Allocate the result and fill it in. jfieldID* result_list = (jfieldID*)jvmtiMalloc(result_count * sizeof(jfieldID)); diff --git a/src/hotspot/share/prims/jvmtiTagMap.cpp b/src/hotspot/share/prims/jvmtiTagMap.cpp index 4febb4f3125..a69c7cb7142 100644 --- a/src/hotspot/share/prims/jvmtiTagMap.cpp +++ b/src/hotspot/share/prims/jvmtiTagMap.cpp @@ -36,6 +36,7 @@ #include "oops/access.inline.hpp" #include "oops/arrayOop.hpp" #include "oops/constantPool.inline.hpp" +#include "oops/fieldStreams.inline.hpp" #include "oops/instanceMirrorKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayKlass.hpp" @@ -58,7 +59,6 @@ #include "runtime/jniHandles.inline.hpp" #include "runtime/mutex.hpp" #include "runtime/mutexLocker.hpp" -#include "runtime/reflectionUtils.hpp" #include "runtime/safepoint.hpp" #include "runtime/threadSMR.hpp" #include "runtime/timerTrace.hpp" @@ -429,8 +429,8 @@ int ClassFieldMap::interfaces_field_count(InstanceKlass* ik) { const Array* interfaces = ik->transitive_interfaces(); int count = 0; for (int i = 0; i < interfaces->length(); i++) { - FilteredJavaFieldStream fld(interfaces->at(i)); - count += fld.field_count(); + count += interfaces->at(i)->java_fields_count(); + } return count; } @@ -452,11 +452,10 @@ ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) { // Need to calculate start index of this class fields: number of fields in all interfaces and superclasses. int index = interfaces_field_count(ik); for (InstanceKlass* super_klass = ik->super(); super_klass != nullptr; super_klass = super_klass->super()) { - FilteredJavaFieldStream super_fld(super_klass); - index += super_fld.field_count(); + index += super_klass->java_fields_count(); } - for (FilteredJavaFieldStream fld(ik); !fld.done(); fld.next(), index++) { + for (JavaFieldStream fld(ik); !fld.done(); fld.next(), index++) { // ignore instance fields if (!fld.access_flags().is_static()) { continue; @@ -479,13 +478,12 @@ ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) { // fields of the superclasses are reported first, so need to know total field number to calculate field indices int total_field_number = interfaces_field_count(ik); for (InstanceKlass* klass = ik; klass != nullptr; klass = klass->super()) { - FilteredJavaFieldStream fld(klass); - total_field_number += fld.field_count(); + total_field_number += klass->java_fields_count(); } for (InstanceKlass* klass = ik; klass != nullptr; klass = klass->super()) { - FilteredJavaFieldStream fld(klass); - int start_index = total_field_number - fld.field_count(); + JavaFieldStream fld(klass); + int start_index = total_field_number - klass->java_fields_count(); for (int index = 0; !fld.done(); fld.next(), index++) { // ignore static fields if (fld.access_flags().is_static()) { diff --git a/src/hotspot/share/runtime/reflectionUtils.cpp b/src/hotspot/share/runtime/reflectionUtils.cpp deleted file mode 100644 index ba1e167f1d6..00000000000 --- a/src/hotspot/share/runtime/reflectionUtils.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "classfile/javaClasses.hpp" -#include "classfile/vmClasses.hpp" -#include "oops/instanceKlass.inline.hpp" -#include "runtime/reflectionUtils.hpp" - - -GrowableArray *FilteredFieldsMap::_filtered_fields = - new (mtServiceability) GrowableArray(3, mtServiceability); - - -void FilteredFieldsMap::initialize() { - int offset = reflect_ConstantPool::oop_offset(); - _filtered_fields->append(new FilteredField(vmClasses::reflect_ConstantPool_klass(), offset)); -} diff --git a/src/hotspot/share/runtime/reflectionUtils.hpp b/src/hotspot/share/runtime/reflectionUtils.hpp deleted file mode 100644 index 5753f46055e..00000000000 --- a/src/hotspot/share/runtime/reflectionUtils.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 1999, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_RUNTIME_REFLECTIONUTILS_HPP -#define SHARE_RUNTIME_REFLECTIONUTILS_HPP - -#include "memory/allStatic.hpp" -#include "oops/fieldStreams.inline.hpp" -#include "oops/instanceKlass.hpp" -#include "oops/oopsHierarchy.hpp" -#include "runtime/reflection.hpp" -#include "utilities/globalDefinitions.hpp" -#include "utilities/growableArray.hpp" - -class FilteredField : public CHeapObj { - private: - Klass* _klass; - int _field_offset; - - public: - FilteredField(Klass* klass, int field_offset) { - _klass = klass; - _field_offset = field_offset; - } - Klass* klass() { return _klass; } - int field_offset() { return _field_offset; } -}; - -class FilteredFieldsMap : AllStatic { - private: - static GrowableArray *_filtered_fields; - public: - static void initialize(); - static bool is_filtered_field(Klass* klass, int field_offset) { - for (int i=0; i < _filtered_fields->length(); i++) { - if (klass == _filtered_fields->at(i)->klass() && - field_offset == _filtered_fields->at(i)->field_offset()) { - return true; - } - } - return false; - } - static int filtered_fields_count(Klass* klass, bool local_only) { - int nflds = 0; - for (int i=0; i < _filtered_fields->length(); i++) { - if (local_only && klass == _filtered_fields->at(i)->klass()) { - nflds++; - } else if (klass->is_subtype_of(_filtered_fields->at(i)->klass())) { - nflds++; - } - } - return nflds; - } -}; - -// Iterate over Java fields filtering fields like reflection does. -class FilteredJavaFieldStream : public JavaFieldStream { -private: - InstanceKlass* _klass; - int _filtered_fields_count; - bool has_filtered_field() const { return (_filtered_fields_count > 0); } - void skip_filtered_fields() { - if (has_filtered_field()) { - while (!done() && FilteredFieldsMap::is_filtered_field((Klass*)_klass, offset())) { - JavaFieldStream::next(); - } - } - } - -public: - FilteredJavaFieldStream(InstanceKlass* klass) - : JavaFieldStream(klass), - _klass(klass), - _filtered_fields_count(FilteredFieldsMap::filtered_fields_count(klass, true)) - { - // skip filtered fields at the beginning - skip_filtered_fields(); - } - int field_count() const { - return _klass->java_fields_count() - _filtered_fields_count; - } - void next() { - JavaFieldStream::next(); - skip_filtered_fields(); - } -}; - -#endif // SHARE_RUNTIME_REFLECTIONUTILS_HPP diff --git a/src/java.base/share/classes/jdk/internal/reflect/ConstantPool.java b/src/java.base/share/classes/jdk/internal/reflect/ConstantPool.java index d56ecff5e36..be241a1eca5 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/ConstantPool.java +++ b/src/java.base/share/classes/jdk/internal/reflect/ConstantPool.java @@ -106,13 +106,6 @@ public class ConstantPool { // Internals only below this point // - static { - Reflection.registerFieldsToFilter(ConstantPool.class, Set.of("constantPoolOop")); - } - - // HotSpot-internal constant pool object (set by the VM, name known to the VM) - private Object constantPoolOop; - private native int getSize0 (); private native Class getClassAt0 (int index); private native Class getClassAtIfLoaded0 (int index); diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 6501d082075..2ea54f2b4ef 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -949,9 +949,6 @@ public class TestResolvedJavaType extends TypeUniverse { * Replicates the semantics of jdk.internal.reflect.Reflection#fieldFilterMap. */ private static boolean isHiddenFromReflection(ResolvedJavaField f) { - if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) { - return true; - } if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Class.class))) { String name = f.getName(); return name.equals("classLoader") || From e1071797a4f0ab1a6af29824a777a7800d729b0e Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 16 Sep 2025 21:51:47 +0000 Subject: [PATCH 108/120] 8367017: Remove legacy checks from WrappedToolkitTest and convert from bash Reviewed-by: prr --- .../WrappedToolkitTest/TestWrapped.java | 71 +++--- .../WrappedToolkitTest/WrappedToolkitTest.sh | 221 ------------------ 2 files changed, 34 insertions(+), 258 deletions(-) delete mode 100644 test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh diff --git a/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/TestWrapped.java b/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/TestWrapped.java index e2ded58e7f2..4b4041dbcfd 100644 --- a/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/TestWrapped.java +++ b/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/TestWrapped.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 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,55 +22,52 @@ */ /* - * test + * @test * @bug 6282388 - * @summary Tests that AWT use correct toolkit to be wrapped into HeadlessToolkit - * @author artem.ananiev@sun.com: area=awt.headless - * @run shell WrappedToolkitTest.sh + * @summary Tests that AWT uses correct toolkit wrapped into HeadlessToolkit + * @modules java.desktop/sun.awt:open + * @library /test/lib + * @run main/othervm -Djava.awt.headless=true TestWrapped */ -import java.awt.*; +import java.awt.Toolkit; +import java.lang.Class; +import java.lang.reflect.Field; -import java.lang.reflect.*; +import jdk.test.lib.Platform; -import sun.awt.*; +public final class TestWrapped { -public class TestWrapped -{ - public static void main(String[] args) - { - try - { - if (args.length != 1) { - System.err.println("No correct toolkit class name is specified, test is not run"); - System.exit(0); + private static final String HEADLESS_TOOLKIT = "sun.awt.HeadlessToolkit"; + private static final String MACOSX_TOOLKIT = "sun.lwawt.macosx.LWCToolkit"; + private static final String UNIX_TOOLKIT = "sun.awt.X11.XToolkit"; + private static final String WINDOWS_TOOLKIT = "sun.awt.windows.WToolkit"; + + public static void main(String[] args) throws Exception { + String expectedToolkitClassName; + if (Platform.isWindows()) { + expectedToolkitClassName = WINDOWS_TOOLKIT; + } else if (Platform.isOSX()) { + expectedToolkitClassName = MACOSX_TOOLKIT; + } else { + expectedToolkitClassName = UNIX_TOOLKIT; } - String correctToolkitClassName = args[0]; Toolkit tk = Toolkit.getDefaultToolkit(); - Class tkClass = tk.getClass(); - if (!tkClass.getName().equals("sun.awt.HeadlessToolkit")) - { - System.err.println(tkClass.getName()); - System.err.println("Error: default toolkit is not an instance of HeadlessToolkit"); - System.exit(-1); + Class tkClass = tk.getClass(); + if (!tkClass.getName().equals(HEADLESS_TOOLKIT)) { + System.err.println("Expected: " + HEADLESS_TOOLKIT); + System.err.println("Actual: " + tkClass.getName()); + throw new RuntimeException("Wrong default toolkit"); } Field f = tkClass.getDeclaredField("tk"); f.setAccessible(true); - Class wrappedClass = f.get(tk).getClass(); - if (!wrappedClass.getName().equals(correctToolkitClassName)) { - System.err.println(wrappedClass.getName()); - System.err.println("Error: wrapped toolkit is not an instance of " + correctToolkitClassName); - System.exit(-1); + Class wrappedClass = f.get(tk).getClass(); + if (!wrappedClass.getName().equals(expectedToolkitClassName)) { + System.err.println("Expected: " + expectedToolkitClassName); + System.err.println("Actual: " + wrappedClass.getName()); + throw new RuntimeException("Wrong wrapped toolkit"); } - } - catch (Exception z) - { - z.printStackTrace(System.err); - System.exit(-1); - } - - System.exit(0); } } diff --git a/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh b/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh deleted file mode 100644 index ac0cf58942c..00000000000 --- a/test/jdk/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh +++ /dev/null @@ -1,221 +0,0 @@ -#!/bin/ksh -p - -# -# Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# @test -# @bug 6282388 8030640 -# @summary Tests that AWT use correct toolkit to be wrapped into HeadlessToolkit -# @author artem.ananiev@sun.com: area=awt.headless -# compile TestWrapped.java -# @run shell WrappedToolkitTest.sh - -# Beginning of subroutines: -status=1 - -#Call this from anywhere to fail the test with an error message -# usage: fail "reason why the test failed" -fail() - { echo "The test failed :-(" - echo "$*" 1>&2 - echo "exit status was $status" - exit $status - } #end of fail() - -#Call this from anywhere to pass the test with a message -# usage: pass "reason why the test passed if applicable" -pass() - { echo "The test passed!!!" - echo "$*" 1>&2 - exit 0 - } #end of pass() - -# end of subroutines - - -# The beginning of the script proper - -# Checking for proper OS -OS=`uname -s` -case "$OS" in - AIX | CYGWIN* | Darwin | Linux ) - FILESEP="/" - ;; - - Windows* ) - FILESEP="\\" - ;; - - # catch all other OSs - * ) - echo "Unrecognized system! $OS" - fail "Unrecognized system! $OS" - ;; -esac - -# check that some executable or other file you need is available, abort if not -# note that the name of the executable is in the fail string as well. -# this is how to check for presence of the compiler, etc. -#RESOURCE=`whence SomeProgramOrFileNeeded` -#if [ "${RESOURCE}" = "" ] ; -# then fail "Need SomeProgramOrFileNeeded to perform the test" ; -#fi - -# Want this test to run standalone as well as in the harness, so do the -# following to copy the test's directory into the harness's scratch directory -# and set all appropriate variables: - -if [ -z "${TESTJAVA}" ] ; then - # TESTJAVA is not set, so the test is running stand-alone. - # TESTJAVA holds the path to the root directory of the build of the JDK - # to be tested. That is, any java files run explicitly in this shell - # should use TESTJAVA in the path to the java interpreter. - # So, we'll set this to the JDK spec'd on the command line. If none - # is given on the command line, tell the user that and use a cheesy - # default. - # THIS IS THE JDK BEING TESTED. - if [ -n "$1" ] ; - then TESTJAVA=$1 - else fail "no JDK specified on command line!" - fi - TESTSRC=. - TESTCLASSES=. - STANDALONE=1; -fi -echo "JDK under test is: $TESTJAVA" - -#if in test harness, then copy the entire directory that the test is in over -# to the scratch directory. This catches any support files needed by the test. -if [ -z "${STANDALONE}" ] ; - then cp ${TESTSRC}/* . -fi -case "$OS" in - Windows* | CYGWIN* ) - ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \ - --add-exports java.desktop/sun.awt=ALL-UNNAMED \ - --add-exports java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ - *.java - status=$? - if [ ! $status -eq "0" ]; then - fail "Compilation failed"; - fi - ;; - - AIX | Linux ) - ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \ - --add-exports java.desktop/sun.awt=ALL-UNNAMED \ - --add-exports java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ - *.java - status=$? - if [ ! $status -eq "0" ]; then - fail "Compilation failed"; - fi - ;; - - Darwin) - ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \ - --add-exports java.desktop/sun.awt=ALL-UNNAMED \ - --add-exports java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ - *.java - status=$? - if [ ! $status -eq "0" ]; then - fail "Compilation failed"; - fi - ;; - -esac - -#Just before executing anything, make sure it has executable permission! -chmod 777 ./* - -############### YOUR TEST CODE HERE!!!!!!! ############# - -case "$OS" in - Windows* | CYGWIN* ) - ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - --add-opens java.desktop/sun.awt=ALL-UNNAMED \ - --add-opens java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ - TestWrapped sun.awt.windows.WToolkit - status=$? - if [ ! $status -eq "0" ]; then - fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit"; - fi - ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - --add-opens java.desktop/sun.awt=ALL-UNNAMED \ - --add-opens java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \ - -Dawt.toolkit=sun.awt.windows.WToolkit \ - TestWrapped sun.awt.windows.WToolkit - status=$? - if [ ! $status -eq "0" ]; then - fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit"; - fi - ;; - - AIX | Linux ) - ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - --add-opens java.desktop/sun.awt=ALL-UNNAMED \ - --add-opens java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ - -Dawt.toolkit=sun.awt.X11.XToolkit \ - TestWrapped sun.awt.X11.XToolkit - status=$? - if [ ! $status -eq "0" ]; then - fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit"; - fi - AWT_TOOLKIT=XToolkit ${TESTJAVA}/bin/java ${TESTVMOPTS} \ - --add-opens java.desktop/sun.awt=ALL-UNNAMED \ - --add-opens java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \ - -Djava.awt.headless=true \ - TestWrapped sun.awt.X11.XToolkit - status=$? - if [ ! $status -eq "0" ]; then - fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit"; - fi - ;; - - Darwin) - ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - --add-opens java.desktop/sun.awt=ALL-UNNAMED \ - --add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ - TestWrapped sun.lwawt.macosx.LWCToolkit - status=$? - if [ ! $status -eq "0" ]; then - fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit"; - fi - ${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \ - --add-opens java.desktop/sun.awt=ALL-UNNAMED \ - --add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \ - -Dawt.toolkit=sun.lwawt.macosx.LWCToolkit \ - TestWrapped sun.lwawt.macosx.LWCToolkit - status=$? - if [ ! $status -eq "0" ]; then - fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit"; - fi - ;; - -esac - -pass "All the tests are PASSED"; - -#For additional examples of how to write platform independent KSH scripts, -# see the jtreg file itself. It is a KSH script for both Solaris and Win32 From c2c44a061a6ba392b4e93eca2c85bd96ab7dcffe Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 17 Sep 2025 05:51:51 +0000 Subject: [PATCH 109/120] 8367724: Remove Trailing Return Types from undecided list Reviewed-by: stefank, phubner --- doc/hotspot-style.html | 2 -- doc/hotspot-style.md | 3 --- 2 files changed, 5 deletions(-) diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index 7be6867b3ca..f1c25dab7f4 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -1859,8 +1859,6 @@ difference.

        Additional Undecided Features

          -
        • Trailing return type syntax for functions (n2541)

        • Member initializers and aggregates (n3653)

        • Rvalue references and move semantics

        • diff --git a/doc/hotspot-style.md b/doc/hotspot-style.md index facdf68462f..e49f49ec1c9 100644 --- a/doc/hotspot-style.md +++ b/doc/hotspot-style.md @@ -1853,9 +1853,6 @@ See Object Lifetime: C++17 6.8/8, C++20 6.7.3/8 ### Additional Undecided Features -* Trailing return type syntax for functions -([n2541](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm)) - * Member initializers and aggregates ([n3653](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html)) From 45cc515f451accfd1a0a36d17ccb38d428a5d035 Mon Sep 17 00:00:00 2001 From: erifan Date: Wed, 17 Sep 2025 07:32:19 +0000 Subject: [PATCH 110/120] 8354242: VectorAPI: combine vector not operation with compare Reviewed-by: epeter, jbhateja, xgong --- src/hotspot/share/opto/node.cpp | 3 + src/hotspot/share/opto/subnode.hpp | 4 +- src/hotspot/share/opto/vectornode.cpp | 98 ++ src/hotspot/share/opto/vectornode.hpp | 2 + .../compiler/lib/ir_framework/IRNode.java | 10 + .../vectorapi/VectorMaskCompareNotTest.java | 1299 +++++++++++++++++ .../vector/MaskCompareNotBenchmark.java | 220 +++ 7 files changed, 1635 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java create mode 100644 test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp index 5ecc038954d..f5f7a4231f2 100644 --- a/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp @@ -1216,6 +1216,9 @@ bool Node::has_special_unique_user() const { } else if ((is_IfFalse() || is_IfTrue()) && n->is_If()) { // See IfNode::fold_compares return true; + } else if (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) { + // Condition for XorVMask(VectorMaskCmp(x,y,cond), MaskAll(true)) ==> VectorMaskCmp(x,y,ncond) + return true; } else { return false; } diff --git a/src/hotspot/share/opto/subnode.hpp b/src/hotspot/share/opto/subnode.hpp index 57a501ecbc3..5acf31b45c4 100644 --- a/src/hotspot/share/opto/subnode.hpp +++ b/src/hotspot/share/opto/subnode.hpp @@ -328,7 +328,9 @@ struct BoolTest { // a simple char array where each element is the ASCII version of a 'mask' // enum from above. mask commute( ) const { return mask("032147658"[_test]-'0'); } - mask negate( ) const { return mask(_test^4); } + mask negate( ) const { return negate_mask(_test); } + // Return the negative mask for the given mask, for both signed and unsigned comparison. + static mask negate_mask(mask btm) { return mask(btm ^ 4); } bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); } bool is_less( ) const { return _test == BoolTest::lt || _test == BoolTest::le; } bool is_greater( ) const { return _test == BoolTest::gt || _test == BoolTest::ge; } diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 2153a12c402..ae9ef552df4 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -2268,6 +2268,99 @@ Node* OrVNode::Identity(PhaseGVN* phase) { return redundant_logical_identity(this); } +// Returns whether (XorV (VectorMaskCmp) -1) can be optimized by negating the +// comparison operation. +bool VectorMaskCmpNode::predicate_can_be_negated() { + switch (_predicate) { + case BoolTest::eq: + case BoolTest::ne: + // eq and ne also apply to floating-point special values like NaN and infinities. + return true; + case BoolTest::le: + case BoolTest::ge: + case BoolTest::lt: + case BoolTest::gt: + case BoolTest::ule: + case BoolTest::uge: + case BoolTest::ult: + case BoolTest::ugt: { + BasicType bt = vect_type()->element_basic_type(); + // For float and double, we don't know if either comparison operand is a + // NaN, NaN {le|ge|lt|gt} anything is false, resulting in inconsistent + // results before and after negation. + return is_integral_type(bt); + } + default: + return false; + } +} + +// This function transforms the following patterns: +// +// For integer types: +// (XorV (VectorMaskCmp src1 src2 cond) (Replicate -1)) +// => (VectorMaskCmp src1 src2 ncond) +// (XorVMask (VectorMaskCmp src1 src2 cond) (MaskAll m1)) +// => (VectorMaskCmp src1 src2 ncond) +// (XorV (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (Replicate -1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// (XorVMask (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (MaskAll m1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// cond can be eq, ne, le, ge, lt, gt, ule, uge, ult and ugt. +// ncond is the negative comparison of cond. +// +// For float and double types: +// (XorV (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (Replicate -1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// (XorVMask (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (MaskAll m1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// cond can be eq or ne. +Node* XorVNode::Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape) { + Node* in1 = in(1); + Node* in2 = in(2); + // Transformations for predicated vectors are not supported for now. + if (is_predicated_vector() || + in1->is_predicated_vector() || + in2->is_predicated_vector()) { + return nullptr; + } + + // XorV/XorVMask is commutative, swap VectorMaskCmp/VectorMaskCast to in1. + if (VectorNode::is_all_ones_vector(in1)) { + swap(in1, in2); + } + + bool with_vector_mask_cast = false; + // Required conditions: + // 1. VectorMaskCast and VectorMaskCmp should only have a single use, + // otherwise the optimization may be unprofitable. + // 2. The predicate of VectorMaskCmp should be negatable. + // 3. The second input should be an all true vector mask. + if (in1->Opcode() == Op_VectorMaskCast) { + if (in1->outcnt() != 1) { + return nullptr; + } + with_vector_mask_cast = true; + in1 = in1->in(1); + } + if (in1->Opcode() != Op_VectorMaskCmp || + in1->outcnt() != 1 || + !in1->as_VectorMaskCmp()->predicate_can_be_negated() || + !VectorNode::is_all_ones_vector(in2)) { + return nullptr; + } + + BoolTest::mask neg_cond = BoolTest::negate_mask((in1->as_VectorMaskCmp())->get_predicate()); + ConINode* predicate_node = phase->intcon(neg_cond); + const TypeVect* vt = in1->as_Vector()->vect_type(); + Node* res = new VectorMaskCmpNode(neg_cond, in1->in(1), in1->in(2), predicate_node, vt); + if (with_vector_mask_cast) { + // We optimized out a VectorMaskCast, regenerate one to ensure type correctness. + res = new VectorMaskCastNode(phase->transform(res), vect_type()); + } + return res; +} + Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) { // (XorV src src) => (Replicate zero) // (XorVMask src src) => (MaskAll zero) @@ -2281,6 +2374,11 @@ Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* zero = phase->transform(phase->zerocon(bt)); return VectorNode::scalar2vector(zero, length(), bt, bottom_type()->isa_vectmask() != nullptr); } + + Node* res = Ideal_XorV_VectorMaskCmp(phase, can_reshape); + if (res != nullptr) { + return res; + } return VectorNode::Ideal(phase, can_reshape); } diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 463680d0a52..53778b61d0e 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1013,6 +1013,7 @@ class XorVNode : public VectorNode { XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); + Node* Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape); }; //------------------------------XorReductionVNode-------------------------------------- @@ -1676,6 +1677,7 @@ class VectorMaskCmpNode : public VectorNode { virtual bool cmp( const Node &n ) const { return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; } + bool predicate_can_be_negated(); BoolTest::mask get_predicate() { return _predicate; } #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 52fc9a05f98..bb69e5bfe80 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -2295,6 +2295,11 @@ public class IRNode { vectorNode(VECTOR_MASK_CMP_D, "VectorMaskCmp", TYPE_DOUBLE); } + public static final String VECTOR_MASK_CMP = PREFIX + "VECTOR_MASK_CMP" + POSTFIX; + static { + beforeMatchingNameRegex(VECTOR_MASK_CMP, "VectorMaskCmp"); + } + public static final String VECTOR_CAST_B2S = VECTOR_PREFIX + "VECTOR_CAST_B2S" + POSTFIX; static { vectorNode(VECTOR_CAST_B2S, "VectorCastB2X", TYPE_SHORT); @@ -2705,6 +2710,11 @@ public class IRNode { vectorNode(XOR_VL, "XorV", TYPE_LONG); } + public static final String XOR_V = PREFIX + "XOR_V" + POSTFIX; + static { + beforeMatchingNameRegex(XOR_V, "XorV"); + } + public static final String XOR_V_MASK = PREFIX + "XOR_V_MASK" + POSTFIX; static { beforeMatchingNameRegex(XOR_V_MASK, "XorVMask"); diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java new file mode 100644 index 00000000000..851113ea4de --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java @@ -0,0 +1,1299 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import compiler.lib.generators.*; +import compiler.lib.ir_framework.*; +import jdk.incubator.vector.*; +import jdk.test.lib.Asserts; + +/* + * @test + * @bug 8354242 + * @key randomness + * @library /test/lib / + * @summary test combining vector not operation with compare + * @modules jdk.incubator.vector + * + * @run driver compiler.vectorapi.VectorMaskCompareNotTest + */ + +public class VectorMaskCompareNotTest { + private static int LENGTH = 128; + + private static final VectorSpecies B_SPECIES = VectorSpecies.ofLargestShape(byte.class); + private static final VectorSpecies S_SPECIES = VectorSpecies.ofLargestShape(short.class); + private static final VectorSpecies I_SPECIES = VectorSpecies.ofLargestShape(int.class); + private static final VectorSpecies L_SPECIES = VectorSpecies.ofLargestShape(long.class); + private static final VectorSpecies F_SPECIES = VectorSpecies.ofLargestShape(float.class); + private static final VectorSpecies D_SPECIES = VectorSpecies.ofLargestShape(double.class); + + // Vector species for vector mask cast operation between int and long types, + // they must have the same number of elements. + // For other types, use a vector species of the specified width. + private static final VectorSpecies L_SPECIES_FOR_CAST = VectorSpecies.ofLargestShape(long.class); + private static final VectorSpecies I_SPECIES_FOR_CAST = VectorSpecies.of(int.class, VectorShape.forBitSize(L_SPECIES_FOR_CAST.vectorBitSize() / 2)); + + private static final Generators RD = Generators.G; + + private static byte[] ba; + private static byte[] bb; + private static short[] sa; + private static short[] sb; + private static int[] ia; + private static int[] ib; + private static int[] ic; + private static long[] la; + private static long[] lb; + private static float[] fa; + private static float[] fb; + private static float[] fnan; + private static float[] fpinf; + private static float[] fninf; + private static double[] da; + private static double[] db; + private static double[] dnan; + private static double[] dpinf; + private static double[] dninf; + private static boolean[] mr; + + static { + ba = new byte[LENGTH]; + bb = new byte[LENGTH]; + sa = new short[LENGTH]; + sb = new short[LENGTH]; + ia = new int[LENGTH]; + ib = new int[LENGTH]; + ic = new int[LENGTH]; + la = new long[LENGTH]; + lb = new long[LENGTH]; + fa = new float[LENGTH]; + fb = new float[LENGTH]; + fnan = new float[LENGTH]; + fpinf = new float[LENGTH]; + fninf = new float[LENGTH]; + da = new double[LENGTH]; + db = new double[LENGTH]; + dnan = new double[LENGTH]; + dpinf = new double[LENGTH]; + dninf = new double[LENGTH]; + mr = new boolean[LENGTH]; + + Generator iGen = RD.ints(); + Generator lGen = RD.longs(); + // Use uniform generators for floating point numbers not to generate NaN values. + Generator fGen = RD.uniformFloats(Float.MIN_VALUE, Float.MAX_VALUE); + Generator dGen = RD.uniformDoubles(Double.MIN_VALUE, Double.MAX_VALUE); + for (int i = 0; i < LENGTH; i++) { + ba[i] = iGen.next().byteValue(); + bb[i] = iGen.next().byteValue(); + sa[i] = iGen.next().shortValue(); + sb[i] = iGen.next().shortValue(); + ia[i] = iGen.next(); + ib[i] = iGen.next(); + la[i] = lGen.next(); + lb[i] = lGen.next(); + fa[i] = fGen.next(); + fb[i] = fGen.next(); + fnan[i] = Float.NaN; + fpinf[i] = Float.POSITIVE_INFINITY; + fninf[i] = Float.NEGATIVE_INFINITY; + da[i] = dGen.next(); + db[i] = dGen.next(); + dnan[i] = Double.NaN; + dpinf[i] = Double.POSITIVE_INFINITY; + dninf[i] = Double.NEGATIVE_INFINITY; + } + } + + public static int compareUnsigned(Number a, Number b) { + if (a instanceof Byte) { + return Integer.compareUnsigned(Byte.toUnsignedInt(a.byteValue()), Byte.toUnsignedInt(b.byteValue())); + } else if (a instanceof Short) { + return Integer.compareUnsigned(Short.toUnsignedInt(a.shortValue()), Short.toUnsignedInt(b.shortValue())); + } else if (a instanceof Integer) { + return Integer.compareUnsigned(a.intValue(), b.intValue()); + } else if (a instanceof Long) { + return Long.compareUnsigned(a.longValue(), b.longValue()); + } else { + throw new IllegalArgumentException("Unsupported type for unsigned comparison: " + a.getClass() + ", " + b.getClass()); + } + } + + public static > void compareResults(T a, T b, boolean r, VectorOperators.Comparison op) { + if (op == VectorOperators.EQ) { + // For floating point numbers, a is not NaN, b may be NaN. If b is NaN, + // a.compareTo(b) will return 1, 1 != 0 is true, r is expected to be true. + Asserts.assertEquals(a.compareTo(b) != 0, r); + } else if (op == VectorOperators.NE) { + // For floating point numbers, a is not NaN, b may be NaN. If b is NaN, + // a.compareTo(b) will return 1, 1 == 0 is false, r is expected to be false. + Asserts.assertEquals(a.compareTo(b) == 0, r); + } else if (op == VectorOperators.LE) { + Asserts.assertEquals(a.compareTo(b) > 0, r); + } else if (op == VectorOperators.GE) { + Asserts.assertEquals(a.compareTo(b) < 0, r); + } else if (op == VectorOperators.LT) { + Asserts.assertEquals(a.compareTo(b) >= 0, r); + } else if (op == VectorOperators.GT) { + Asserts.assertEquals(a.compareTo(b) <= 0, r); + } else if (op == VectorOperators.ULE) { + Asserts.assertEquals(compareUnsigned(a, b) > 0, r); + } else if (op == VectorOperators.UGE) { + Asserts.assertEquals(compareUnsigned(a, b) < 0, r); + } else if (op == VectorOperators.ULT) { + Asserts.assertEquals(compareUnsigned(a, b) >= 0, r); + } else if (op == VectorOperators.UGT) { + Asserts.assertEquals(compareUnsigned(a, b) <= 0, r); + } else { + throw new IllegalArgumentException("Unknown comparison operator: " + op); + } + } + + @DontInline + public static void verifyResultsByte(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(ba[i], bb[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsShort(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(sa[i], sb[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsInt(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(ia[i], ib[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsLong(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(la[i], lb[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsFloat(VectorSpecies vs, VectorOperators.Comparison op, float[] a, float[] b) { + for (int i = 0; i < vs.length(); i++) { + compareResults(a[i], b[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsDouble(VectorSpecies vs, VectorOperators.Comparison op, double[] a, double[] b) { + for (int i = 0; i < vs.length(); i++) { + compareResults(a[i], b[i], mr[i], op); + } + } + + interface VectorMaskOperator { + public VectorMask apply(VectorMask m); + } + + @ForceInline + public static void testCompareMaskNotByte(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + ByteVector av = ByteVector.fromArray(vs, ba, 0); + ByteVector bv = ByteVector.fromArray(vs, bb, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotShort(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + ShortVector av = ShortVector.fromArray(vs, sa, 0); + ShortVector bv = ShortVector.fromArray(vs, sb, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotInt(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + IntVector av = IntVector.fromArray(vs, ia, 0); + IntVector bv = IntVector.fromArray(vs, ib, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotLong(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + LongVector av = LongVector.fromArray(vs, la, 0); + LongVector bv = LongVector.fromArray(vs, lb, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotFloat(VectorSpecies vs, VectorOperators.Comparison op, float[] a, float[] b, VectorMaskOperator func) { + FloatVector av = FloatVector.fromArray(vs, a, 0); + FloatVector bv = FloatVector.fromArray(vs, b, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotDouble(VectorSpecies vs, VectorOperators.Comparison op, double[] a, double[] b, VectorMaskOperator func) { + DoubleVector av = DoubleVector.fromArray(vs, a, 0); + DoubleVector bv = DoubleVector.fromArray(vs, b, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + // Byte tests + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.EQ); + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.EQ); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.EQ, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.NE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.NE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.NE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.NE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.LT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.LT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.LT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.LT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.GT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.GT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.GT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.GT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.LE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.LE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.LE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.LE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.GE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.GE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.GE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.GE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.ULT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.UGT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.ULE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.UGE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.UGE); + } + + // Short tests + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.EQ); + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.EQ); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.EQ, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.EQ); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.EQ, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.NE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.NE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.NE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.NE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.NE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.NE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.LT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.LT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.LT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.LT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.LT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.LT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.GT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.GT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.GT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.GT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.GT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.GT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.LE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.LE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.LE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.LE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.LE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.LE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.GE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.GE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.GE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.GE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.GE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.GE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.ULT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.ULT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.ULT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.UGT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.UGT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.UGT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.ULE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.ULE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.ULE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.UGE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.UGE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.UGE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.UGE); + } + + // Int tests + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.EQ); + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.EQ); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.EQ, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.EQ); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.EQ, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.NE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.NE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.NE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.NE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.NE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.NE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.LT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.LT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.LT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.LT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.LT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.LT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.GT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.GT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.GT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.GT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.GT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.GT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.LE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.LE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.LE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.LE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.LE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.LE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.GE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.GE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.GE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.GE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.GE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.GE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.ULT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.ULT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.ULT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.UGT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.UGT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.UGT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.ULE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.ULE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.ULE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.UGE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.UGE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.UGE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.UGE); + } + + // Long tests + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.EQ); + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.EQ); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.EQ, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.NE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.NE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.NE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.NE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.LT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.LT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.LT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.LT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.GT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.GT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.GT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.GT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.LE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.LE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.LE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.LE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.GE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.GE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.GE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.GE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.ULT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.UGT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.ULE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.UGE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.UGE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloat() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fb); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fb); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloat() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fb, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fb); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fb, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fb); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloatNaN() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fnan, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fnan); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fnan, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloatNaN() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fnan, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fnan); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fnan, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloatPositiveInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloatPositiveInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fpinf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fpinf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fpinf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloatNegativeInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fninf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fninf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fninf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fninf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloatNegativeInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fninf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fninf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fninf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fninf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDouble() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, db); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, db); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDouble() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, db, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, db); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, db, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, db); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDoubleNaN() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dnan, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dnan); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dnan, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDoubleNaN() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dnan, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dnan); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dnan, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDoublePositiveInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dpinf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dpinf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dpinf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDoublePositiveInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dpinf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dpinf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dpinf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDoubleNegativeInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dninf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dninf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dninf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dninf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDoubleNegativeInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dninf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dninf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dninf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dninf); + } + + // negative tests + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotByteNegative() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsByte(B_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { return B_SPECIES.maskAll(false).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotShortNegative() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsShort(S_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { return S_SPECIES.maskAll(false).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotIntNegative() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsInt(I_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { return I_SPECIES.maskAll(false).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotLongNegative() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsLong(L_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { return L_SPECIES.maskAll(false).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotFloatNegative() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fb); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { return F_SPECIES.maskAll(false).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fb); + + // Float vectors use the LT comparison. + testCompareMaskNotFloat(F_SPECIES, VectorOperators.LT, fa, fb, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.LT, fa, fb); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotDoubleNegative() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, db); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { return D_SPECIES.maskAll(false).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, db); + + // Double vectors use the LT comparison. + testCompareMaskNotDouble(D_SPECIES, VectorOperators.LT, da, db, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.LT, da, db); + } + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.setDefaultWarmup(5000) + .addFlags("--add-modules=jdk.incubator.vector") + .start(); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java new file mode 100644 index 00000000000..d83bc126a1d --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.jdk.incubator.vector; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; + +import jdk.incubator.vector.*; +import java.lang.invoke.*; +import java.util.concurrent.TimeUnit; +import java.util.Random; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 2, jvmArgs = { "--add-modules=jdk.incubator.vector" }) +public abstract class MaskCompareNotBenchmark { + @Param({"4096"}) + protected int ARRAYLEN; + + // Abstract method to get comparison operator from subclasses + protected abstract String getComparisonOperatorName(); + + // To get compile-time constants for comparison operation + static final MutableCallSite MUTABLE_COMPARISON_CONSTANT = new MutableCallSite(MethodType.methodType(VectorOperators.Comparison.class)); + static final MethodHandle MUTABLE_COMPARISON_CONSTANT_HANDLE = MUTABLE_COMPARISON_CONSTANT.dynamicInvoker(); + + private static Random r = new Random(); + + protected static final VectorSpecies B_SPECIES = ByteVector.SPECIES_MAX; + protected static final VectorSpecies S_SPECIES = ShortVector.SPECIES_MAX; + protected static final VectorSpecies I_SPECIES = IntVector.SPECIES_MAX; + protected static final VectorSpecies L_SPECIES = LongVector.SPECIES_MAX; + protected static final VectorSpecies F_SPECIES = FloatVector.SPECIES_MAX; + protected static final VectorSpecies D_SPECIES = DoubleVector.SPECIES_MAX; + + protected boolean[] mr; + protected byte[] ba; + protected byte[] bb; + protected short[] sa; + protected short[] sb; + protected int[] ia; + protected int[] ib; + protected long[] la; + protected long[] lb; + protected float[] fa; + protected float[] fb; + protected double[] da; + protected double[] db; + + @Setup + public void init() throws Throwable { + mr = new boolean[ARRAYLEN]; + ba = new byte[ARRAYLEN]; + bb = new byte[ARRAYLEN]; + sa = new short[ARRAYLEN]; + sb = new short[ARRAYLEN]; + ia = new int[ARRAYLEN]; + ib = new int[ARRAYLEN]; + la = new long[ARRAYLEN]; + lb = new long[ARRAYLEN]; + fa = new float[ARRAYLEN]; + fb = new float[ARRAYLEN]; + da = new double[ARRAYLEN]; + db = new double[ARRAYLEN]; + + for (int i = 0; i < ARRAYLEN; i++) { + mr[i] = r.nextBoolean(); + ba[i] = (byte) r.nextInt(); + bb[i] = (byte) r.nextInt(); + sa[i] = (short) r.nextInt(); + sb[i] = (short) r.nextInt(); + ia[i] = r.nextInt(); + ib[i] = r.nextInt(); + la[i] = r.nextLong(); + lb[i] = r.nextLong(); + fa[i] = r.nextFloat(); + fb[i] = r.nextFloat(); + da[i] = r.nextDouble(); + db[i] = r.nextDouble(); + } + + VectorOperators.Comparison comparisonOp = getComparisonOperator(getComparisonOperatorName()); + MethodHandle constant = MethodHandles.constant(VectorOperators.Comparison.class, comparisonOp); + MUTABLE_COMPARISON_CONSTANT.setTarget(constant); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private static VectorOperators.Comparison getComparisonOperator(String op) { + switch (op) { + case "EQ": return VectorOperators.EQ; + case "NE": return VectorOperators.NE; + case "LT": return VectorOperators.LT; + case "LE": return VectorOperators.LE; + case "GT": return VectorOperators.GT; + case "GE": return VectorOperators.GE; + case "ULT": return VectorOperators.ULT; + case "ULE": return VectorOperators.ULE; + case "UGT": return VectorOperators.UGT; + case "UGE": return VectorOperators.UGE; + default: throw new IllegalArgumentException("Unknown comparison operator: " + op); + } + } + + @CompilerControl(CompilerControl.Mode.INLINE) + protected VectorOperators.Comparison comparison_con() throws Throwable { + return (VectorOperators.Comparison) MUTABLE_COMPARISON_CONSTANT_HANDLE.invokeExact(); + } + + // Subclasses with different comparison operators + public static class IntegerComparisons extends MaskCompareNotBenchmark { + @Param({"EQ", "NE", "LT", "LE", "GT", "GE", "ULT", "ULE", "UGT", "UGE"}) + public String COMPARISON_OP; + + @Override + protected String getComparisonOperatorName() { + return COMPARISON_OP; + } + + @Benchmark + public void testCompareMaskNotByte() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + ByteVector bv = ByteVector.fromArray(B_SPECIES, bb, 0); + for (int j = 0; j < ARRAYLEN; j += B_SPECIES.length()) { + ByteVector av = ByteVector.fromArray(B_SPECIES, ba, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotShort() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + ShortVector bv = ShortVector.fromArray(S_SPECIES, sb, 0); + for (int j = 0; j < ARRAYLEN; j += S_SPECIES.length()) { + ShortVector av = ShortVector.fromArray(S_SPECIES, sa, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotInt() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + IntVector bv = IntVector.fromArray(I_SPECIES, ib, 0); + for (int j = 0; j < ARRAYLEN; j += I_SPECIES.length()) { + IntVector av = IntVector.fromArray(I_SPECIES, ia, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotLong() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + LongVector bv = LongVector.fromArray(L_SPECIES, lb, 0); + for (int j = 0; j < ARRAYLEN; j += L_SPECIES.length()) { + LongVector av = LongVector.fromArray(L_SPECIES, la, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + } + + public static class FloatingPointComparisons extends MaskCompareNotBenchmark { + // "ULT", "ULE", "UGT", "UGE" are not supported for floating point types + @Param({"EQ", "NE", "LT", "LE", "GT", "GE"}) + public String COMPARISON_OP; + + @Override + protected String getComparisonOperatorName() { + return COMPARISON_OP; + } + + @Benchmark + public void testCompareMaskNotFloat() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + FloatVector bv = FloatVector.fromArray(F_SPECIES, fb, 0); + for (int j = 0; j < ARRAYLEN; j += F_SPECIES.length()) { + FloatVector av = FloatVector.fromArray(F_SPECIES, fa, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotDouble() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + DoubleVector bv = DoubleVector.fromArray(D_SPECIES, db, 0); + for (int j = 0; j < ARRAYLEN; j += D_SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(D_SPECIES, da, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + } +} From 9c0f41e9973726df0544bf0c7f06a7eb214b849f Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Wed, 17 Sep 2025 08:07:50 +0000 Subject: [PATCH 111/120] 8225787: java/awt/Window/GetScreenLocation/GetScreenLocationTest.java fails on Ubuntu 8203004: UnixMultiResolutionSplashTest.java fails on Ubuntu16.04 Reviewed-by: psadhukhan, serb --- test/jdk/ProblemList.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 2628d18ae54..528a33c1bd5 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -453,7 +453,6 @@ java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java 71 java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java 6848810 macosx-all,linux-all java/awt/FileDialog/ModalFocus/FileDialogModalFocusTest.java 8194751 linux-all java/awt/image/VolatileImage/BitmaskVolatileImage.java 8133102 linux-all -java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java 8203004 linux-all java/awt/ScrollPane/ScrollPaneEventType.java 8296516 macosx-all java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528 linux-all,macosx-all java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676 linux-all @@ -491,7 +490,6 @@ java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeForModalDia java/awt/KeyboardFocusmanager/TypeAhead/MenuItemActivatedTest/MenuItemActivatedTest.java 8302787 windows-all java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeNextMnemonicKeyTypedTest.java 8321303 linux-all -java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 java/awt/Dialog/ChoiceModalDialogTest.java 8161475 macosx-all java/awt/Dialog/FileDialogUserFilterTest.java 8001142 generic-all From d0ea6686ebe2baff28f5368f5bbf9dc7f34dd6d8 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 17 Sep 2025 08:21:20 +0000 Subject: [PATCH 112/120] 8367417: Serial: Use NMethodToOopClosure during Young GC Reviewed-by: fandreuzzi, stefank, tschatzl --- src/hotspot/share/gc/serial/defNewGeneration.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index b5d65793b90..bcd131a5fa2 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -600,13 +600,11 @@ bool DefNewGeneration::collect(bool clear_all_soft_refs) { &old_gen_cl); { - StrongRootsScope srs(0); RootScanClosure oop_closure{this}; CLDScanClosure cld_closure{this}; - MarkingNMethodClosure nmethod_closure(&oop_closure, - NMethodToOopClosure::FixRelocations, - false /* keepalive_nmethods */); + NMethodToOopClosure nmethod_closure(&oop_closure, + NMethodToOopClosure::FixRelocations); // Starting tracing from roots, there are 4 kinds of roots in young-gc. // From 976207df1fcebf76a5f732b26424d6a4896b359e Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Wed, 17 Sep 2025 08:26:31 +0000 Subject: [PATCH 113/120] 8367476: Shenandoah: Remove use of CollectedHeap::_soft_ref_policy Reviewed-by: ayang, wkemper --- src/hotspot/share/gc/epsilon/epsilonHeap.hpp | 1 - src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 1 - .../gc/parallel/parallelScavengeHeap.cpp | 7 +--- .../gc/parallel/parallelScavengeHeap.hpp | 2 - src/hotspot/share/gc/serial/serialHeap.cpp | 7 +--- src/hotspot/share/gc/serial/serialHeap.hpp | 5 --- src/hotspot/share/gc/shared/collectedHeap.cpp | 1 - src/hotspot/share/gc/shared/collectedHeap.hpp | 6 --- src/hotspot/share/gc/shared/gcCause.hpp | 7 ++++ .../share/gc/shared/gcVMOperations.cpp | 1 - src/hotspot/share/gc/shared/softRefPolicy.hpp | 42 ------------------- .../gc/shenandoah/shenandoahConcurrentGC.cpp | 3 +- .../gc/shenandoah/shenandoahControlThread.cpp | 5 ++- .../shenandoahGenerationalControlThread.cpp | 8 ++-- .../share/gc/shenandoah/shenandoahHeap.hpp | 1 - .../shenandoahReferenceProcessor.cpp | 9 ++-- .../shenandoahReferenceProcessor.hpp | 2 + .../share/gc/shenandoah/shenandoahSTWMark.cpp | 1 - src/hotspot/share/gc/z/zCollectedHeap.hpp | 1 - src/hotspot/share/prims/whitebox.cpp | 1 - 20 files changed, 26 insertions(+), 85 deletions(-) delete mode 100644 src/hotspot/share/gc/shared/softRefPolicy.hpp diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp index f8aa9d7dbf1..e23e24a5afc 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp @@ -29,7 +29,6 @@ #include "gc/epsilon/epsilonBarrierSet.hpp" #include "gc/epsilon/epsilonMonitoringSupport.hpp" #include "gc/shared/collectedHeap.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "gc/shared/space.hpp" #include "memory/virtualspace.hpp" #include "services/memoryManager.hpp" diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 0bb16edaf78..8d26bcb1c0b 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -50,7 +50,6 @@ #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/plab.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "gc/shared/taskqueue.hpp" #include "memory/allocation.hpp" #include "memory/iterator.hpp" diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 21841330fa7..81412e2f614 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -469,14 +469,9 @@ void ParallelScavengeHeap::collect(GCCause::Cause cause) { VMThread::execute(&op); } -bool ParallelScavengeHeap::must_clear_all_soft_refs() { - return _gc_cause == GCCause::_metadata_GC_clear_soft_refs || - _gc_cause == GCCause::_wb_full_gc; -} - void ParallelScavengeHeap::collect_at_safepoint(bool full) { assert(!GCLocker::is_active(), "precondition"); - bool clear_soft_refs = must_clear_all_soft_refs(); + bool clear_soft_refs = GCCause::should_clear_all_soft_refs(_gc_cause); if (!full) { bool success = PSScavenge::invoke(clear_soft_refs); diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index bd701ae8be3..b1176a1637b 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -96,8 +96,6 @@ class ParallelScavengeHeap : public CollectedHeap { void update_parallel_worker_threads_cpu_time(); - bool must_clear_all_soft_refs(); - HeapWord* allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) override; inline bool should_alloc_in_eden(size_t size) const; diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 662a6be695b..e019144d628 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -340,11 +340,6 @@ HeapWord* SerialHeap::mem_allocate(size_t size) { false /* is_tlab */); } -bool SerialHeap::must_clear_all_soft_refs() { - return _gc_cause == GCCause::_metadata_GC_clear_soft_refs || - _gc_cause == GCCause::_wb_full_gc; -} - bool SerialHeap::is_young_gc_safe() const { if (!_young_gen->to()->is_empty()) { return false; @@ -497,7 +492,7 @@ void SerialHeap::scan_evacuated_objs(YoungGenScanClosure* young_cl, void SerialHeap::collect_at_safepoint(bool full) { assert(!GCLocker::is_active(), "precondition"); - bool clear_soft_refs = must_clear_all_soft_refs(); + bool clear_soft_refs = GCCause::should_clear_all_soft_refs(_gc_cause); if (!full) { bool success = do_young_collection(clear_soft_refs); diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index 72778981eee..86fb286f33f 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp @@ -31,7 +31,6 @@ #include "gc/shared/collectedHeap.hpp" #include "gc/shared/oopStorageParState.hpp" #include "gc/shared/preGCValues.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "utilities/growableArray.hpp" class CardTableRS; @@ -104,10 +103,6 @@ private: void do_full_collection(bool clear_all_soft_refs) override; - // Does the "cause" of GC indicate that - // we absolutely __must__ clear soft refs? - bool must_clear_all_soft_refs(); - bool is_young_gc_safe() const; void gc_prologue(); diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp index 71017817d14..9b6956ca75a 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.cpp +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp @@ -276,7 +276,6 @@ bool CollectedHeap::is_oop(oop object) const { CollectedHeap::CollectedHeap() : _capacity_at_last_gc(0), _used_at_last_gc(0), - _soft_ref_policy(), _is_stw_gc_active(false), _last_whole_heap_examined_time_ns(os::javaTimeNanos()), _total_collections(0), diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 57bd9316731..f4f5ce79074 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -27,7 +27,6 @@ #include "gc/shared/gcCause.hpp" #include "gc/shared/gcWhen.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "gc/shared/verifyOption.hpp" #include "memory/allocation.hpp" #include "memory/metaspace.hpp" @@ -104,8 +103,6 @@ class CollectedHeap : public CHeapObj { size_t _capacity_at_last_gc; size_t _used_at_last_gc; - SoftRefPolicy _soft_ref_policy; - // First, set it to java_lang_Object. // Then, set it to FillerObject after the FillerObject_klass loading is complete. static Klass* _filler_object_klass; @@ -395,9 +392,6 @@ protected: } } - // Return the SoftRefPolicy for the heap; - SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; } - virtual MemoryUsage memory_usage(); virtual GrowableArray memory_managers() = 0; virtual GrowableArray memory_pools() = 0; diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp index f775d41340d..aac4b801b74 100644 --- a/src/hotspot/share/gc/shared/gcCause.hpp +++ b/src/hotspot/share/gc/shared/gcCause.hpp @@ -103,6 +103,13 @@ class GCCause : public AllStatic { cause == _codecache_GC_aggressive); } + // Does the "cause" of GC indicate that + // we absolutely __must__ clear soft refs? + inline static bool should_clear_all_soft_refs(GCCause::Cause cause) { + return cause == GCCause::_metadata_GC_clear_soft_refs || + cause == GCCause::_wb_full_gc; + } + // Return a string describing the GCCause. static const char* to_string(GCCause::Cause cause); }; diff --git a/src/hotspot/share/gc/shared/gcVMOperations.cpp b/src/hotspot/share/gc/shared/gcVMOperations.cpp index 1299f64995f..97bae4f6d44 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.cpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.cpp @@ -29,7 +29,6 @@ #include "gc/shared/gcId.hpp" #include "gc/shared/gcLocker.hpp" #include "gc/shared/gcVMOperations.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "interpreter/oopMapCache.hpp" #include "logging/log.hpp" #include "memory/classLoaderMetaspace.hpp" diff --git a/src/hotspot/share/gc/shared/softRefPolicy.hpp b/src/hotspot/share/gc/shared/softRefPolicy.hpp deleted file mode 100644 index 1e8ec356c40..00000000000 --- a/src/hotspot/share/gc/shared/softRefPolicy.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_SHARED_SOFTREFPOLICY_HPP -#define SHARE_GC_SHARED_SOFTREFPOLICY_HPP - -class SoftRefPolicy { - private: - // Set to true when policy wants soft refs cleared. - // Reset to false by gc after it clears all soft refs. - bool _should_clear_all_soft_refs; - - public: - SoftRefPolicy() : - _should_clear_all_soft_refs(false) {} - - bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; } - void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; } -}; - -#endif // SHARE_GC_SHARED_SOFTREFPOLICY_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp index 111e0073470..6d3b93ac406 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp @@ -114,6 +114,8 @@ void ShenandoahConcurrentGC::entry_concurrent_update_refs_prepare(ShenandoahHeap bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) { ShenandoahHeap* const heap = ShenandoahHeap::heap(); + _generation->ref_processor()->set_soft_reference_policy( + GCCause::should_clear_all_soft_refs(cause)); ShenandoahBreakpointGCScope breakpoint_gc_scope(cause); @@ -732,7 +734,6 @@ void ShenandoahConcurrentGC::op_init_mark() { // Weak reference processing ShenandoahReferenceProcessor* rp = _generation->ref_processor(); rp->reset_thread_locals(); - rp->set_soft_reference_policy(heap->soft_ref_policy()->should_clear_all_soft_refs()); // Make above changes visible to worker threads OrderAccess::fence(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 6290101bc49..80e5b709ada 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -34,6 +34,7 @@ #include "gc/shenandoah/shenandoahGeneration.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" +#include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "logging/log.hpp" #include "memory/metaspaceStats.hpp" @@ -118,7 +119,7 @@ void ShenandoahControlThread::run_service() { // Blow all soft references on this cycle, if handling allocation failure, // either implicit or explicit GC request, or we are requested to do so unconditionally. if (alloc_failure_pending || is_gc_requested || ShenandoahAlwaysClearSoftRefs) { - heap->soft_ref_policy()->set_should_clear_all_soft_refs(true); + heap->global_generation()->ref_processor()->set_soft_reference_policy(true); } const bool gc_requested = (mode != none); @@ -193,7 +194,7 @@ void ShenandoahControlThread::run_service() { heap->set_forced_counters_update(false); // Retract forceful part of soft refs policy - heap->soft_ref_policy()->set_should_clear_all_soft_refs(false); + heap->global_generation()->ref_processor()->set_soft_reference_policy(false); // Clear metaspace oom flag, if current cycle unloaded classes if (heap->unload_classes()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index ce8d96308ba..761ba02d569 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp @@ -37,6 +37,7 @@ #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc/shenandoah/shenandoahOldGC.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" +#include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "gc/shenandoah/shenandoahYoungGeneration.hpp" #include "logging/log.hpp" @@ -216,8 +217,9 @@ void ShenandoahGenerationalControlThread::run_gc_cycle(const ShenandoahGCRequest // Blow away all soft references on this cycle, if handling allocation failure, // either implicit or explicit GC request, or we are requested to do so unconditionally. - if (request.generation->is_global() && (ShenandoahCollectorPolicy::is_allocation_failure(request.cause) || ShenandoahCollectorPolicy::is_explicit_gc(request.cause) || ShenandoahAlwaysClearSoftRefs)) { - _heap->soft_ref_policy()->set_should_clear_all_soft_refs(true); + if (GCCause::should_clear_all_soft_refs(request.cause) || (request.generation->is_global() && + (ShenandoahCollectorPolicy::is_allocation_failure(request.cause) || ShenandoahCollectorPolicy::is_explicit_gc(request.cause) || ShenandoahAlwaysClearSoftRefs))) { + request.generation->ref_processor()->set_soft_reference_policy(true); } // GC is starting, bump the internal ID @@ -289,7 +291,7 @@ void ShenandoahGenerationalControlThread::run_gc_cycle(const ShenandoahGCRequest _heap->set_forced_counters_update(false); // Retract forceful part of soft refs policy - _heap->soft_ref_policy()->set_should_clear_all_soft_refs(false); + request.generation->ref_processor()->set_soft_reference_policy(false); // Clear metaspace oom flag, if current cycle unloaded classes if (_heap->unload_classes()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index eafd1b28b3a..322ac26e254 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -29,7 +29,6 @@ #include "gc/shared/collectedHeap.hpp" #include "gc/shared/markBitMap.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "gc/shenandoah/mode/shenandoahMode.hpp" #include "gc/shenandoah/shenandoahAllocRequest.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp index f8726386b5d..4ca6f2fdf49 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp @@ -221,8 +221,10 @@ void ShenandoahRefProcThreadLocal::set_discovered_list_head(oop head) { *discovered_list_addr() = head; } +AlwaysClearPolicy ShenandoahReferenceProcessor::_always_clear_policy; + ShenandoahReferenceProcessor::ShenandoahReferenceProcessor(uint max_workers) : - _soft_reference_policy(nullptr), + _soft_reference_policy(&_always_clear_policy), _ref_proc_thread_locals(NEW_C_HEAP_ARRAY(ShenandoahRefProcThreadLocal, max_workers, mtGC)), _pending_list(nullptr), _pending_list_tail(&_pending_list), @@ -245,12 +247,11 @@ void ShenandoahReferenceProcessor::set_mark_closure(uint worker_id, ShenandoahMa } void ShenandoahReferenceProcessor::set_soft_reference_policy(bool clear) { - static AlwaysClearPolicy always_clear_policy; static LRUMaxHeapPolicy lru_max_heap_policy; if (clear) { log_info(gc, ref)("Clearing All SoftReferences"); - _soft_reference_policy = &always_clear_policy; + _soft_reference_policy = &_always_clear_policy; } else { _soft_reference_policy = &lru_max_heap_policy; } @@ -284,7 +285,7 @@ bool ShenandoahReferenceProcessor::is_softly_live(oop reference, ReferenceType t // Ask SoftReference policy const jlong clock = java_lang_ref_SoftReference::clock(); assert(clock != 0, "Clock not initialized"); - assert(_soft_reference_policy != nullptr, "Policy not initialized"); + assert(_soft_reference_policy != nullptr, "Should never be null"); return !_soft_reference_policy->should_clear_reference(reference, clock); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp index 682c4268754..11099f1303d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp @@ -127,6 +127,8 @@ public: class ShenandoahReferenceProcessor : public ReferenceDiscoverer { private: + static AlwaysClearPolicy _always_clear_policy; + ReferencePolicy* _soft_reference_policy; ShenandoahRefProcThreadLocal* _ref_proc_thread_locals; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp index c2bfea664fd..260c1e0276f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp @@ -77,7 +77,6 @@ void ShenandoahSTWMark::mark() { ShenandoahReferenceProcessor* rp = _generation->ref_processor(); shenandoah_assert_generations_reconciled(); rp->reset_thread_locals(); - rp->set_soft_reference_policy(heap->soft_ref_policy()->should_clear_all_soft_refs()); // Init mark, do not expect forwarded pointers in roots if (ShenandoahVerify) { diff --git a/src/hotspot/share/gc/z/zCollectedHeap.hpp b/src/hotspot/share/gc/z/zCollectedHeap.hpp index c124976c80f..bbcddec917f 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.hpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp @@ -25,7 +25,6 @@ #define SHARE_GC_Z_ZCOLLECTEDHEAP_HPP #include "gc/shared/collectedHeap.hpp" -#include "gc/shared/softRefPolicy.hpp" #include "gc/z/zBarrierSet.hpp" #include "gc/z/zHeap.hpp" #include "gc/z/zInitialize.hpp" diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index ce559d47b24..e8e873fcb66 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -1501,7 +1501,6 @@ WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString WB_END WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o)) - Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true); Universe::heap()->collect(GCCause::_wb_full_gc); WB_END From 5730e908c636ad57e6bbc5a1b64ce88245c38788 Mon Sep 17 00:00:00 2001 From: Daniel Gredler Date: Wed, 17 Sep 2025 09:16:41 +0000 Subject: [PATCH 114/120] 4138921: TextLayout handling of empty strings Reviewed-by: prr, serb --- .../classes/java/awt/font/TextLayout.java | 52 +-- .../share/classes/java/awt/font/TextLine.java | 18 +- .../classes/sun/font/TextLabelFactory.java | 6 +- .../TextLayout/TextLayoutConstructorTest.java | 316 ++++++++++++++++++ 4 files changed, 362 insertions(+), 30 deletions(-) create mode 100644 test/jdk/java/awt/font/TextLayout/TextLayoutConstructorTest.java diff --git a/src/java.desktop/share/classes/java/awt/font/TextLayout.java b/src/java.desktop/share/classes/java/awt/font/TextLayout.java index 74382b4bd83..5e8f3040055 100644 --- a/src/java.desktop/share/classes/java/awt/font/TextLayout.java +++ b/src/java.desktop/share/classes/java/awt/font/TextLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, 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 @@ -256,7 +256,6 @@ public final class TextLayout implements Cloneable { */ private boolean cacheIsValid = false; - // This value is obtained from an attribute, and constrained to the // interval [0,1]. If 0, the layout cannot be justified. private float justifyRatio; @@ -367,6 +366,7 @@ public final class TextLayout implements Cloneable { * device resolution, and attributes such as antialiasing. This * parameter does not specify a translation between the * {@code TextLayout} and user space. + * @throws IllegalArgumentException if any of the parameters are null. */ public TextLayout(String string, Font font, FontRenderContext frc) { @@ -378,8 +378,8 @@ public final class TextLayout implements Cloneable { throw new IllegalArgumentException("Null string passed to TextLayout constructor."); } - if (string.length() == 0) { - throw new IllegalArgumentException("Zero length string passed to TextLayout constructor."); + if (frc == null) { + throw new IllegalArgumentException("Null font render context passed to TextLayout constructor."); } Map attributes = null; @@ -415,6 +415,7 @@ public final class TextLayout implements Cloneable { * device resolution, and attributes such as antialiasing. This * parameter does not specify a translation between the * {@code TextLayout} and user space. + * @throws IllegalArgumentException if any of the parameters are null. */ public TextLayout(String string, Map attributes, FontRenderContext frc) @@ -427,8 +428,8 @@ public final class TextLayout implements Cloneable { throw new IllegalArgumentException("Null map passed to TextLayout constructor."); } - if (string.length() == 0) { - throw new IllegalArgumentException("Zero length string passed to TextLayout constructor."); + if (frc == null) { + throw new IllegalArgumentException("Null font render context passed to TextLayout constructor."); } char[] text = string.toCharArray(); @@ -499,6 +500,7 @@ public final class TextLayout implements Cloneable { * device resolution, and attributes such as antialiasing. This * parameter does not specify a translation between the * {@code TextLayout} and user space. + * @throws IllegalArgumentException if any of the parameters are null. */ public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) { @@ -506,14 +508,13 @@ public final class TextLayout implements Cloneable { throw new IllegalArgumentException("Null iterator passed to TextLayout constructor."); } - int start = text.getBeginIndex(); - int limit = text.getEndIndex(); - if (start == limit) { - throw new IllegalArgumentException("Zero length iterator passed to TextLayout constructor."); + if (frc == null) { + throw new IllegalArgumentException("Null font render context passed to TextLayout constructor."); } + int start = text.getBeginIndex(); + int limit = text.getEndIndex(); int len = limit - start; - text.first(); char[] chars = new char[len]; int n = 0; for (char c = text.first(); @@ -1125,7 +1126,12 @@ public final class TextLayout implements Cloneable { float top1X, top2X; float bottom1X, bottom2X; - if (caret == 0 || caret == characterCount) { + if (caret == 0 && characterCount == 0) { + + top1X = top2X = 0; + bottom1X = bottom2X = 0; + + } else if (caret == 0 || caret == characterCount) { float pos; int logIndex; @@ -1143,8 +1149,8 @@ public final class TextLayout implements Cloneable { pos += angle * shift; top1X = top2X = pos + angle*textLine.getCharAscent(logIndex); bottom1X = bottom2X = pos - angle*textLine.getCharDescent(logIndex); - } - else { + + } else { { int logIndex = textLine.visualToLogical(caret-1); @@ -1884,7 +1890,6 @@ public final class TextLayout implements Cloneable { Shape[] result = new Shape[2]; TextHitInfo hit = TextHitInfo.afterOffset(offset); - int hitCaret = hitToCaret(hit); LayoutPathImpl lp = textLine.getLayoutPath(); @@ -2180,12 +2185,16 @@ public final class TextLayout implements Cloneable { checkTextHit(firstEndpoint); checkTextHit(secondEndpoint); - if(bounds == null) { - throw new IllegalArgumentException("Null Rectangle2D passed to TextLayout.getVisualHighlightShape()"); + if (bounds == null) { + throw new IllegalArgumentException("Null Rectangle2D passed to TextLayout.getVisualHighlightShape()"); } GeneralPath result = new GeneralPath(GeneralPath.WIND_EVEN_ODD); + if (characterCount == 0) { + return result; + } + int firstCaret = hitToCaret(firstEndpoint); int secondCaret = hitToCaret(secondEndpoint); @@ -2194,8 +2203,9 @@ public final class TextLayout implements Cloneable { if (firstCaret == 0 || secondCaret == 0) { GeneralPath ls = leftShape(bounds); - if (!ls.getBounds().isEmpty()) + if (!ls.getBounds().isEmpty()) { result.append(ls, false); + } } if (firstCaret == characterCount || secondCaret == characterCount) { @@ -2282,12 +2292,16 @@ public final class TextLayout implements Cloneable { secondEndpoint = t; } - if(firstEndpoint < 0 || secondEndpoint > characterCount) { + if (firstEndpoint < 0 || secondEndpoint > characterCount) { throw new IllegalArgumentException("Range is invalid in TextLayout.getLogicalHighlightShape()"); } GeneralPath result = new GeneralPath(GeneralPath.WIND_EVEN_ODD); + if (characterCount == 0) { + return result; + } + int[] carets = new int[10]; // would this ever not handle all cases? int count = 0; diff --git a/src/java.desktop/share/classes/java/awt/font/TextLine.java b/src/java.desktop/share/classes/java/awt/font/TextLine.java index 681fcd90083..3464c1626c6 100644 --- a/src/java.desktop/share/classes/java/awt/font/TextLine.java +++ b/src/java.desktop/share/classes/java/awt/font/TextLine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -836,7 +836,7 @@ final class TextLine { } if (result == null) { - result = new Rectangle2D.Float(Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_VALUE); + result = new Rectangle2D.Float(0, 0, 0, 0); } return result; @@ -844,6 +844,10 @@ final class TextLine { public Rectangle2D getItalicBounds() { + if (fComponents.length == 0) { + return new Rectangle2D.Float(0, 0, 0, 0); + } + float left = Float.MAX_VALUE, right = -Float.MAX_VALUE; float top = Float.MAX_VALUE, bottom = -Float.MAX_VALUE; @@ -927,7 +931,7 @@ final class TextLine { // dlf: get baseRot from font for now??? if (!requiresBidi) { - requiresBidi = Bidi.requiresBidi(chars, 0, chars.length); + requiresBidi = Bidi.requiresBidi(chars, 0, characterCount); } if (requiresBidi) { @@ -935,7 +939,7 @@ final class TextLine { ? Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT : values.getRunDirection(); - bidi = new Bidi(chars, 0, embs, 0, chars.length, bidiflags); + bidi = new Bidi(chars, 0, embs, 0, characterCount, bidiflags); if (!bidi.isLeftToRight()) { levels = BidiUtils.getLevels(bidi); int[] charsVtoL = BidiUtils.createVisualToLogicalMap(levels); @@ -945,13 +949,11 @@ final class TextLine { } Decoration decorator = Decoration.getDecoration(values); - int layoutFlags = 0; // no extra info yet, bidi determines run and line direction TextLabelFactory factory = new TextLabelFactory(frc, chars, bidi, layoutFlags); TextLineComponent[] components = new TextLineComponent[1]; - - components = createComponentsOnRun(0, chars.length, + components = createComponentsOnRun(0, characterCount, chars, charsLtoV, levels, factory, font, lm, @@ -972,7 +974,7 @@ final class TextLine { } return new TextLine(frc, components, lm.baselineOffsets, - chars, 0, chars.length, charsLtoV, levels, isDirectionLTR); + chars, 0, characterCount, charsLtoV, levels, isDirectionLTR); } private static TextLineComponent[] expandArray(TextLineComponent[] orig) { diff --git a/src/java.desktop/share/classes/sun/font/TextLabelFactory.java b/src/java.desktop/share/classes/sun/font/TextLabelFactory.java index d245f33b8af..7a41bd2e7f5 100644 --- a/src/java.desktop/share/classes/sun/font/TextLabelFactory.java +++ b/src/java.desktop/share/classes/sun/font/TextLabelFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -119,7 +119,7 @@ public final class TextLabelFactory { int start, int limit) { - if (start >= limit || start < lineStart || limit > lineLimit) { + if (start > limit || start < lineStart || limit > lineLimit) { throw new IllegalArgumentException("bad start: " + start + " or limit: " + limit); } @@ -145,7 +145,7 @@ public final class TextLabelFactory { int start, int limit) { - if (start >= limit || start < lineStart || limit > lineLimit) { + if (start > limit || start < lineStart || limit > lineLimit) { throw new IllegalArgumentException("bad start: " + start + " or limit: " + limit); } diff --git a/test/jdk/java/awt/font/TextLayout/TextLayoutConstructorTest.java b/test/jdk/java/awt/font/TextLayout/TextLayoutConstructorTest.java new file mode 100644 index 00000000000..31117e495bc --- /dev/null +++ b/test/jdk/java/awt/font/TextLayout/TextLayoutConstructorTest.java @@ -0,0 +1,316 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4138921 + * @summary Confirm constructor behavior for various edge cases. + */ + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.TextAttribute; +import java.awt.font.TextHitInfo; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +public class TextLayoutConstructorTest { + + public static void main(String[] args) throws Exception { + testFontConstructor(); + testMapConstructor(); + testIteratorConstructor(); + } + + private static void testFontConstructor() { + + // new TextLayout(String, Font, FontRenderContext) + + Font font = new Font(Font.DIALOG, Font.PLAIN, 20); + FontRenderContext frc = new FontRenderContext(null, true, true); + + assertThrows(() -> new TextLayout(null, font, frc), + IllegalArgumentException.class, + "Null string passed to TextLayout constructor."); + + assertThrows(() -> new TextLayout("test", (Font) null, frc), + IllegalArgumentException.class, + "Null font passed to TextLayout constructor."); + + assertThrows(() -> new TextLayout("test", font, null), + IllegalArgumentException.class, + "Null font render context passed to TextLayout constructor."); + + Function< String, TextLayout > creator = (s) -> new TextLayout(s, font, frc); + assertEmptyTextLayoutBehavior(creator); + } + + private static void testMapConstructor() { + + // new TextLayout(String, Map, FontRenderContext) + + Map< TextAttribute, Object > attributes = Map.of(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); + FontRenderContext frc = new FontRenderContext(null, true, true); + + assertThrows(() -> new TextLayout(null, attributes, frc), + IllegalArgumentException.class, + "Null string passed to TextLayout constructor."); + + assertThrows(() -> new TextLayout("test", (Map) null, frc), + IllegalArgumentException.class, + "Null map passed to TextLayout constructor."); + + assertThrows(() -> new TextLayout("test", attributes, null), + IllegalArgumentException.class, + "Null font render context passed to TextLayout constructor."); + + Function< String, TextLayout > creator = (s) -> new TextLayout(s, attributes, frc); + assertEmptyTextLayoutBehavior(creator); + } + + private static void testIteratorConstructor() { + + // new TextLayout(AttributedCharacterIterator, FontRenderContext) + + Map< TextAttribute, Object > attributes = Map.of(); + FontRenderContext frc = new FontRenderContext(null, true, true); + + assertThrows(() -> new TextLayout(null, frc), + IllegalArgumentException.class, + "Null iterator passed to TextLayout constructor."); + + AttributedCharacterIterator it1 = new AttributedString("test", attributes).getIterator(); + assertThrows(() -> new TextLayout(it1, null), + IllegalArgumentException.class, + "Null font render context passed to TextLayout constructor."); + + Function< String, TextLayout > creator = (s) -> { + AttributedCharacterIterator it2 = new AttributedString(s, attributes).getIterator(); + return new TextLayout(it2, frc); + }; + assertEmptyTextLayoutBehavior(creator); + } + + private static void assertEmptyTextLayoutBehavior(Function< String, TextLayout > creator) { + + TextLayout tl = creator.apply(""); + TextLayout ref = creator.apply(" "); // space + FontRenderContext frc = new FontRenderContext(null, true, true); + Rectangle zero = new Rectangle(0, 0, 0, 0); + Rectangle2D.Float zero2D = new Rectangle2D.Float(0, 0, 0, 0); + Rectangle2D.Float oneTwo = new Rectangle2D.Float(1, 2, 0, 0); + Rectangle2D.Float kilo = new Rectangle2D.Float(0, 0, 1000, 1000); + AffineTransform identity = new AffineTransform(); + TextLayout.CaretPolicy policy = new TextLayout.CaretPolicy(); + TextHitInfo start = TextHitInfo.trailing(-1); + TextHitInfo end = TextHitInfo.leading(0); + + assertEqual(0, tl.getJustifiedLayout(100).getAdvance(), "justified advance"); + assertEqual(0, tl.getBaseline(), "baseline"); + + float[] offsets = tl.getBaselineOffsets(); + float[] refOffsets = ref.getBaselineOffsets(); + assertEqual(3, offsets.length, "baseline offsets"); + assertEqual(refOffsets[0], offsets[0], "baseline offset 1"); + assertEqual(refOffsets[1], offsets[1], "baseline offset 2"); + assertEqual(refOffsets[2], offsets[2], "baseline offset 3"); + + assertEqual(0, tl.getAdvance(), "advance"); + assertEqual(0, tl.getVisibleAdvance(), "visible advance"); + assertEqual(ref.getAscent(), tl.getAscent(), "ascent"); + assertEqual(ref.getDescent(), tl.getDescent(), "descent"); + assertEqual(ref.getLeading(), tl.getLeading(), "leading"); + assertEqual(zero2D, tl.getBounds(), "bounds"); + assertEqual(zero2D, tl.getPixelBounds(frc, 0, 0), "pixel bounds 1"); + assertEqual(oneTwo, tl.getPixelBounds(frc, 1, 2), "pixel bounds 2"); + assertEqual(true, tl.isLeftToRight(), "left to right"); + assertEqual(false, tl.isVertical(), "is vertical"); + assertEqual(0, tl.getCharacterCount(), "character count"); + + float[] caretInfo = tl.getCaretInfo(start, kilo); + float[] refCaretInfo = ref.getCaretInfo(start, kilo); + assertEqual(6, caretInfo.length, "caret info length 1"); + assertEqual(refCaretInfo[0], caretInfo[0], "first caret info 1"); + assertEqual(refCaretInfo[1], caretInfo[1], "second caret info 1"); + assertEqual(refCaretInfo[2], caretInfo[2], "third caret info 1"); + assertEqual(refCaretInfo[3], caretInfo[3], "fourth caret info 1"); + assertEqual(refCaretInfo[4], caretInfo[4], "fifth caret info 1"); + assertEqual(refCaretInfo[5], caretInfo[5], "sixth caret info 1"); + + float[] caretInfo2 = tl.getCaretInfo(start); + float[] refCaretInfo2 = ref.getCaretInfo(start); + assertEqual(6, caretInfo2.length, "caret info length 2"); + assertEqual(refCaretInfo2[0], caretInfo2[0], "first caret info 2"); + assertEqual(refCaretInfo2[1], caretInfo2[1], "second caret info 2"); + assertEqual(refCaretInfo2[2], caretInfo2[2], "third caret info 2"); + assertEqual(refCaretInfo2[3], caretInfo2[3], "fourth caret info 2"); + assertEqual(refCaretInfo2[4], caretInfo2[4], "fifth caret info 2"); + assertEqual(refCaretInfo2[5], caretInfo2[5], "sixth caret info 2"); + + assertEqual(null, tl.getNextRightHit(start), "next right hit 1"); + assertEqual(null, tl.getNextRightHit(end), "next right hit 2"); + assertEqual(null, tl.getNextRightHit(0, policy), "next right hit 3"); + assertEqual(null, tl.getNextRightHit(0), "next right hit 4"); + assertEqual(null, tl.getNextLeftHit(start), "next left hit 1"); + assertEqual(null, tl.getNextLeftHit(end), "next left hit 2"); + assertEqual(null, tl.getNextLeftHit(0, policy), "next left hit 3"); + assertEqual(null, tl.getNextLeftHit(0), "next left hit 4"); + assertEqual(end, tl.getVisualOtherHit(start), "visual other hit"); + + Shape caretShape = tl.getCaretShape(start, kilo); + Shape refCaretShape = ref.getCaretShape(start, kilo); + assertEqual(refCaretShape.getBounds(), caretShape.getBounds(), "caret shape 1"); + + Shape caretShape2 = tl.getCaretShape(start); + Shape refCaretShape2 = ref.getCaretShape(start); + assertEqual(refCaretShape2.getBounds(), caretShape2.getBounds(), "caret shape 2"); + + assertEqual(0, tl.getCharacterLevel(0), "character level"); + + Shape[] caretShapes = tl.getCaretShapes(0, kilo, policy); + Shape[] refCaretShapes = ref.getCaretShapes(0, kilo, policy); + assertEqual(2, caretShapes.length, "caret shapes length 1"); + assertEqual(refCaretShapes[0].getBounds(), caretShapes[0].getBounds(), "caret shapes strong 1"); + assertEqual(refCaretShapes[1], caretShapes[1], "caret shapes weak 1"); + assertEqual(null, caretShapes[1], "caret shapes weak 1"); + + Shape[] caretShapes2 = tl.getCaretShapes(0, kilo); + Shape[] refCaretShapes2 = ref.getCaretShapes(0, kilo); + assertEqual(2, caretShapes2.length, "caret shapes length 2"); + assertEqual(refCaretShapes2[0].getBounds(), caretShapes2[0].getBounds(), "caret shapes strong 2"); + assertEqual(refCaretShapes2[1], caretShapes2[1], "caret shapes weak 2"); + assertEqual(null, caretShapes2[1], "caret shapes weak 2"); + + Shape[] caretShapes3 = tl.getCaretShapes(0); + Shape[] refCaretShapes3 = ref.getCaretShapes(0); + assertEqual(2, caretShapes3.length, "caret shapes length 3"); + assertEqual(refCaretShapes3[0].getBounds(), caretShapes3[0].getBounds(), "caret shapes strong 3"); + assertEqual(refCaretShapes3[1], caretShapes3[1], "caret shapes weak 3"); + assertEqual(null, caretShapes3[1], "caret shapes weak 3"); + + assertEqual(0, tl.getLogicalRangesForVisualSelection(start, start).length, "logical ranges for visual selection"); + assertEqual(zero2D, tl.getVisualHighlightShape(start, start, kilo).getBounds(), "visual highlight shape 1"); + assertEqual(zero2D, tl.getVisualHighlightShape(start, start).getBounds(), "visual highlight shape 2"); + assertEqual(zero, tl.getLogicalHighlightShape(0, 0, kilo).getBounds(), "logical highlight shape 1"); + assertEqual(zero, tl.getLogicalHighlightShape(0, 0).getBounds(), "logical highlight shape 2"); + assertEqual(zero, tl.getBlackBoxBounds(0, 0).getBounds(), "black box bounds"); + + TextHitInfo hit = tl.hitTestChar(0, 0); + assertEqual(-1, hit.getCharIndex(), "hit test char index 1"); + assertEqual(false, hit.isLeadingEdge(), "hit test leading edge 1"); + + TextHitInfo hit2 = tl.hitTestChar(0, 0, kilo); + assertEqual(-1, hit2.getCharIndex(), "hit test char index 2"); + assertEqual(false, hit2.isLeadingEdge(), "hit test leading edge 2"); + + assertEqual(false, tl.equals(creator.apply("")), "equals"); + assertEqual(false, tl.toString().isEmpty(), "to string"); + assertDoesNotDraw(tl); + assertEqual(zero2D, tl.getOutline(identity).getBounds(), "outline"); + assertEqual(null, tl.getLayoutPath(), "layout path"); + + Point2D.Float point = new Point2D.Float(7, 7); + tl.hitToPoint(start, point); + assertEqual(0, point.x, "hit to point x"); + assertEqual(0, point.y, "hit to point y"); + } + + private static void assertEqual(int expected, int actual, String name) { + if (expected != actual) { + throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual); + } + } + + private static void assertEqual(float expected, float actual, String name) { + if (expected != actual) { + throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual); + } + } + + private static void assertEqual(boolean expected, boolean actual, String name) { + if (expected != actual) { + throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual); + } + } + + private static void assertEqual(Object expected, Object actual, String name) { + if (!Objects.equals(expected, actual)) { + throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual); + } + } + + private static void assertThrows(Runnable r, Class< ? > type, String message) { + Class< ? > actualType; + String actualMessage; + Exception actualException; + try { + r.run(); + actualType = null; + actualMessage = null; + actualException = null; + } catch (Exception e) { + actualType = e.getClass(); + actualMessage = e.getMessage(); + actualException = e; + } + if (!Objects.equals(type, actualType)) { + throw new RuntimeException(type + " != " + actualType, actualException); + } + if (!Objects.equals(message, actualMessage)) { + throw new RuntimeException(message + " != " + actualMessage, actualException); + } + } + + private static void assertDoesNotDraw(TextLayout layout) { + + int w = 200; + int h = 200; + BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY); + Graphics2D g2d = image.createGraphics(); + int expected = image.getRGB(0, 0); + + layout.draw(g2d, w / 2f, h / 2f); // should not actually draw anything + + int[] rowPixels = new int[w]; + for (int y = 0; y < h; y++) { + image.getRGB(0, y, w, 1, rowPixels, 0, w); + for (int x = 0; x < w; x++) { + if (rowPixels[x] != expected) { + throw new RuntimeException( + "pixel (" + x + ", " + y +"): " + expected + " != " + rowPixels[x]); + } + } + } + } +} From 005f3a392f20ea2fbe2d7d699448e65d3443a073 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 17 Sep 2025 09:41:44 +0000 Subject: [PATCH 115/120] 8367743: G1: Use named constants for G1CSetCandidateGroup group ids Reviewed-by: ayang, iwalulya --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 2 +- .../share/gc/g1/g1CollectionSetCandidates.cpp | 2 +- .../share/gc/g1/g1CollectionSetCandidates.hpp | 25 ++++++++++++------- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 8 +++--- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 4f7eaa36c2d..4a257265931 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1200,7 +1200,7 @@ G1CollectedHeap::G1CollectedHeap() : _rem_set(nullptr), _card_set_config(), _card_set_freelist_pool(G1CardSetConfiguration::num_mem_object_types()), - _young_regions_cset_group(card_set_config(), &_card_set_freelist_pool, 1u /* group_id */), + _young_regions_cset_group(card_set_config(), &_card_set_freelist_pool, G1CSetCandidateGroup::YoungRegionId), _cm(nullptr), _cm_thread(nullptr), _cr(nullptr), diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp index ccb52922c09..47340fad768 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp @@ -27,7 +27,7 @@ #include "gc/g1/g1HeapRegion.inline.hpp" #include "utilities/growableArray.hpp" -uint G1CSetCandidateGroup::_next_group_id = 2; +uint G1CSetCandidateGroup::_next_group_id = G1CSetCandidateGroup::InitialId; G1CSetCandidateGroup::G1CSetCandidateGroup(G1CardSetConfiguration* config, G1MonotonicArenaFreePool* card_set_freelist_pool, uint group_id) : _candidates(4, mtGCCardSet), diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp index 02a4d5f6d76..0f4e92968fa 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp @@ -73,14 +73,21 @@ class G1CSetCandidateGroup : public CHeapObj{ size_t _reclaimable_bytes; double _gc_efficiency; - // The _group_id is primarily used when printing out per-region liveness information, - // making it easier to associate regions with their assigned G1CSetCandidateGroup, if any. - // Note: - // * _group_id 0 is reserved for special G1CSetCandidateGroups that hold only a single region, - // such as G1CSetCandidateGroups for retained regions. - // * _group_id 1 is reserved for the G1CSetCandidateGroup that contains all young regions. +public: + // The _group_id uniquely identifies a candidate group when printing, making it + // easier to associate regions with their assigned G1CSetCandidateGroup, if any. + // Special values for the id: + // * id 0 is reserved for regions that do not have a remembered set. + // * id 1 is reserved for the G1CollectionSetCandidate that contains all young regions. + // * other ids are handed out incrementally, starting from InitialId. + static const uint NoRemSetId = 0; + static const uint YoungRegionId = 1; + static const uint InitialId = 2; + +private: const uint _group_id; static uint _next_group_id; + public: G1CSetCandidateGroup(); G1CSetCandidateGroup(G1CardSetConfiguration* config, G1MonotonicArenaFreePool* card_set_freelist_pool, uint group_id); @@ -95,8 +102,6 @@ public: G1CardSet* card_set() { return &_card_set; } const G1CardSet* card_set() const { return &_card_set; } - uint group_id() const { return _group_id; } - void calculate_efficiency(); double liveness_percent() const; @@ -127,8 +132,10 @@ public: return _candidates.end(); } + uint group_id() const { return _group_id; } + static void reset_next_group_id() { - _next_group_id = 2; + _next_group_id = InitialId; } }; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 6d30a93dafb..3d95541ae3c 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -3052,11 +3052,9 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(G1HeapRegion* r) { size_t remset_bytes = r->rem_set()->mem_size(); size_t code_roots_bytes = r->rem_set()->code_roots_mem_size(); const char* remset_type = r->rem_set()->get_short_state_str(); - uint cset_group_id = 0; - - if (r->rem_set()->has_cset_group()) { - cset_group_id = r->rem_set()->cset_group_id(); - } + uint cset_group_id = r->rem_set()->has_cset_group() + ? r->rem_set()->cset_group_id() + : G1CSetCandidateGroup::NoRemSetId; _total_used_bytes += used_bytes; _total_capacity_bytes += capacity_bytes; From faebec63a94bb532b9d0ca0736c73ddbf1392ac2 Mon Sep 17 00:00:00 2001 From: Andrew Dinn Date: Wed, 17 Sep 2025 09:42:01 +0000 Subject: [PATCH 116/120] 8367532: Declare all stubgen stub entries including internal cross-stub entries Reviewed-by: fyang, asmehra --- .../cpu/aarch64/macroAssembler_aarch64.hpp | 2 +- .../aarch64/macroAssembler_aarch64_aes.cpp | 7 +- .../cpu/aarch64/stubGenerator_aarch64.cpp | 374 ++++++++++-------- src/hotspot/cpu/arm/stubGenerator_arm.cpp | 5 + src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 8 +- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 178 ++++++--- .../x86/stubGenerator_x86_64_arraycopy.cpp | 113 ++++-- .../share/runtime/stubDeclarations.hpp | 48 +++ 8 files changed, 477 insertions(+), 258 deletions(-) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index fe2440fd3fd..0570fad5b8d 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1623,7 +1623,7 @@ public: FloatRegister p, FloatRegister z, FloatRegister t1); void ghash_reduce_wide(int index, FloatRegister result, FloatRegister lo, FloatRegister hi, FloatRegister p, FloatRegister z, FloatRegister t1); - void ghash_processBlocks_wide(address p, Register state, Register subkeyH, + void ghash_processBlocks_wide(Label& p, Register state, Register subkeyH, Register data, Register blocks, int unrolls); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp index 84b85b7b445..25ec9cf9bdd 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp @@ -507,7 +507,7 @@ void MacroAssembler::ghash_modmul(FloatRegister result, // // Clobbers all vector registers. // -void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register state, +void MacroAssembler::ghash_processBlocks_wide(Label& field_polynomial, Register state, Register subkeyH, Register data, Register blocks, int unrolls) { int register_stride = 7; @@ -531,7 +531,10 @@ void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register FloatRegister p = v31; eor(vzr, T16B, vzr, vzr); // zero register - ldrq(p, field_polynomial); // The field polynomial + // load polynomial via label which must identify local data in the + // same code stub + adr(rscratch1, field_polynomial); + ldrq(p, rscratch1); // The field polynomial ldrq(v0, Address(state)); ldrq(Hprime, Address(subkeyH)); diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 3f1a9f7daaa..ffe5afd93cb 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -802,7 +802,7 @@ class StubGenerator: public StubCodeGenerator { // // s and d are adjusted to point to the remaining words to copy // - void generate_copy_longs(StubId stub_id, DecoratorSet decorators, Label &start, Register s, Register d, Register count) { + address generate_copy_longs(StubId stub_id, DecoratorSet decorators, Register s, Register d, Register count) { BasicType type; copy_direction direction; @@ -854,7 +854,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, stub_id); - __ bind(start); + address start = __ pc(); Label unaligned_copy_long; if (AvoidUnalignedAccesses) { @@ -894,9 +894,9 @@ class StubGenerator: public StubCodeGenerator { int prefetch = PrefetchCopyIntervalInBytes; bool use_stride = false; if (direction == copy_backwards) { - use_stride = prefetch > 256; - prefetch = -prefetch; - if (use_stride) __ mov(stride, prefetch); + use_stride = prefetch > 256; + prefetch = -prefetch; + if (use_stride) __ mov(stride, prefetch); } __ bind(again); @@ -1026,9 +1026,9 @@ class StubGenerator: public StubCodeGenerator { int prefetch = PrefetchCopyIntervalInBytes; bool use_stride = false; if (direction == copy_backwards) { - use_stride = prefetch > 256; - prefetch = -prefetch; - if (use_stride) __ mov(stride, prefetch); + use_stride = prefetch > 256; + prefetch = -prefetch; + if (use_stride) __ mov(stride, prefetch); } __ bind(again); @@ -1037,15 +1037,15 @@ class StubGenerator: public StubCodeGenerator { __ prfm(use_stride ? Address(s, stride) : Address(s, prefetch), PLDL1KEEP); if (direction == copy_forwards) { - // allowing for the offset of -8 the store instructions place - // registers into the target 64 bit block at the following - // offsets - // - // t0 at offset 0 - // t1 at offset 8, t2 at offset 16 - // t3 at offset 24, t4 at offset 32 - // t5 at offset 40, t6 at offset 48 - // t7 at offset 56 + // allowing for the offset of -8 the store instructions place + // registers into the target 64 bit block at the following + // offsets + // + // t0 at offset 0 + // t1 at offset 8, t2 at offset 16 + // t3 at offset 24, t4 at offset 32 + // t5 at offset 40, t6 at offset 48 + // t7 at offset 56 bs.copy_store_at_8(Address(d, 1 * unit), t0); bs.copy_store_at_16(Address(d, 2 * unit), t1, t2); @@ -1057,18 +1057,18 @@ class StubGenerator: public StubCodeGenerator { bs.copy_store_at_8(Address(__ pre(d, 8 * unit)), t7); bs.copy_load_at_16(t6, t7, Address(__ pre(s, 8 * unit))); } else { - // d was not offset when we started so the registers are - // written into the 64 bit block preceding d with the following - // offsets - // - // t1 at offset -8 - // t3 at offset -24, t0 at offset -16 - // t5 at offset -48, t2 at offset -32 - // t7 at offset -56, t4 at offset -48 - // t6 at offset -64 - // - // note that this matches the offsets previously noted for the - // loads + // d was not offset when we started so the registers are + // written into the 64 bit block preceding d with the following + // offsets + // + // t1 at offset -8 + // t3 at offset -24, t0 at offset -16 + // t5 at offset -48, t2 at offset -32 + // t7 at offset -56, t4 at offset -48 + // t6 at offset -64 + // + // note that this matches the offsets previously noted for the + // loads bs.copy_store_at_8(Address(d, 1 * unit), t1); bs.copy_store_at_16(Address(d, 3 * unit), t3, t0); @@ -1109,10 +1109,10 @@ class StubGenerator: public StubCodeGenerator { { Label L1, L2; __ tbz(count, exact_log2(4), L1); - // this is the same as above but copying only 4 longs hence - // with only one intervening stp between the str instructions - // but note that the offsets and registers still follow the - // same pattern + // this is the same as above but copying only 4 longs hence + // with only one intervening stp between the str instructions + // but note that the offsets and registers still follow the + // same pattern bs.copy_load_at_16(t0, t1, Address(s, 2 * unit)); bs.copy_load_at_16(t2, t3, Address(__ pre(s, 4 * unit))); if (direction == copy_forwards) { @@ -1127,10 +1127,10 @@ class StubGenerator: public StubCodeGenerator { __ bind(L1); __ tbz(count, 1, L2); - // this is the same as above but copying only 2 longs hence - // there is no intervening stp between the str instructions - // but note that the offset and register patterns are still - // the same + // this is the same as above but copying only 2 longs hence + // there is no intervening stp between the str instructions + // but note that the offset and register patterns are still + // the same bs.copy_load_at_16(t0, t1, Address(__ pre(s, 2 * unit))); if (direction == copy_forwards) { bs.copy_store_at_8(Address(d, 1 * unit), t0); @@ -1141,18 +1141,20 @@ class StubGenerator: public StubCodeGenerator { } __ bind(L2); - // for forwards copy we need to re-adjust the offsets we - // applied so that s and d are follow the last words written + // for forwards copy we need to re-adjust the offsets we + // applied so that s and d are follow the last words written - if (direction == copy_forwards) { - __ add(s, s, 16); - __ add(d, d, 8); - } + if (direction == copy_forwards) { + __ add(s, s, 16); + __ add(d, d, 8); + } } __ ret(lr); - } + } + + return start; } // Small copy: less than 16 bytes. @@ -1206,10 +1208,6 @@ class StubGenerator: public StubCodeGenerator { } } - Label copy_f, copy_b; - Label copy_obj_f, copy_obj_b; - Label copy_obj_uninit_f, copy_obj_uninit_b; - // All-singing all-dancing memory copy. // // Copy count units of memory from s to d. The size of a unit is @@ -1447,19 +1445,19 @@ class StubGenerator: public StubCodeGenerator { } if (direction == copy_forwards) { if (type != T_OBJECT) { - __ bl(copy_f); + __ bl(StubRoutines::aarch64::copy_byte_f()); } else if ((decorators & IS_DEST_UNINITIALIZED) != 0) { - __ bl(copy_obj_uninit_f); + __ bl(StubRoutines::aarch64::copy_oop_uninit_f()); } else { - __ bl(copy_obj_f); + __ bl(StubRoutines::aarch64::copy_oop_f()); } } else { if (type != T_OBJECT) { - __ bl(copy_b); + __ bl(StubRoutines::aarch64::copy_byte_b()); } else if ((decorators & IS_DEST_UNINITIALIZED) != 0) { - __ bl(copy_obj_uninit_b); + __ bl(StubRoutines::aarch64::copy_oop_uninit_b()); } else { - __ bl(copy_obj_b); + __ bl(StubRoutines::aarch64::copy_oop_b()); } } @@ -1522,11 +1520,11 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - // Side Effects: entry is set to the (post push) entry point so it - // can be used by the corresponding conjoint copy - // method + // Side Effects: nopush_entry is set to the (post push) entry point + // so it can be used by the corresponding conjoint + // copy method // - address generate_disjoint_copy(StubId stub_id, address *entry) { + address generate_disjoint_copy(StubId stub_id, address *nopush_entry) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_reg = RegSet::of(s, d, count); int size; @@ -1615,8 +1613,8 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); - if (entry != nullptr) { - *entry = __ pc(); + if (nopush_entry != nullptr) { + *nopush_entry = __ pc(); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1679,10 +1677,10 @@ class StubGenerator: public StubCodeGenerator { // cache line boundaries will still be loaded and stored atomically. // // Side Effects: - // entry is set to the no-overlap entry point so it can be used by - // some other conjoint copy method + // nopush_entry is set to the no-overlap entry point so it can be + // used by some other conjoint copy method // - address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *entry) { + address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *nopush_entry) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_regs = RegSet::of(s, d, count); int size; @@ -1769,16 +1767,19 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); - if (entry != nullptr) { - *entry = __ pc(); + if (nopush_entry != nullptr) { + *nopush_entry = __ pc(); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } // use fwd copy when (d-s) above_equal (count*size) + Label L_overlapping; __ sub(rscratch1, d, s); __ cmp(rscratch1, count, Assembler::LSL, exact_log2(size)); - __ br(Assembler::HS, nooverlap_target); + __ br(Assembler::LO, L_overlapping); + __ b(RuntimeAddress(nooverlap_target)); + __ bind(L_overlapping); DecoratorSet decorators = IN_HEAP | IS_ARRAY; if (dest_uninitialized) { @@ -1850,7 +1851,7 @@ class StubGenerator: public StubCodeGenerator { // r0 == 0 - success // r0 == -1^K - failure, where K is partial transfer count // - address generate_checkcast_copy(StubId stub_id, address *entry) { + address generate_checkcast_copy(StubId stub_id, address *nopush_entry) { bool dest_uninitialized; switch (stub_id) { case StubId::stubgen_checkcast_arraycopy_id: @@ -1911,8 +1912,8 @@ class StubGenerator: public StubCodeGenerator { #endif //ASSERT // Caller of this entry point must set up the argument registers. - if (entry != nullptr) { - *entry = __ pc(); + if (nopush_entry != nullptr) { + *nopush_entry = __ pc(); BLOCK_COMMENT("Entry:"); } @@ -2724,13 +2725,21 @@ class StubGenerator: public StubCodeGenerator { } void generate_arraycopy_stubs() { - address entry; - address entry_jbyte_arraycopy; - address entry_jshort_arraycopy; - address entry_jint_arraycopy; - address entry_oop_arraycopy; - address entry_jlong_arraycopy; - address entry_checkcast_arraycopy; + // Some copy stubs publish a normal entry and then a 2nd 'fallback' + // entry immediately following their stack push. This can be used + // as a post-push branch target for compatible stubs when they + // identify a special case that can be handled by the fallback + // stub e.g a disjoint copy stub may be use as a special case + // fallback for its compatible conjoint copy stub. + // + // A no push entry is always returned in the following local and + // then published by assigning to the appropriate entry field in + // class StubRoutines. The entry value is then passed to the + // generator for the compatible stub. That means the entry must be + // listed when saving to/restoring from the AOT cache, ensuring + // that the inter-stub jumps are noted at AOT-cache save and + // relocated at AOT cache load. + address nopush_entry; // generate the common exit first so later stubs can rely on it if // they want an UnsafeMemoryAccess exit non-local to the stub @@ -2738,83 +2747,123 @@ class StubGenerator: public StubCodeGenerator { // register the stub as the default exit with class UnsafeMemoryAccess UnsafeMemoryAccess::set_common_exit_stub_pc(StubRoutines::_unsafecopy_common_exit); - generate_copy_longs(StubId::stubgen_copy_byte_f_id, IN_HEAP | IS_ARRAY, copy_f, r0, r1, r15); - generate_copy_longs(StubId::stubgen_copy_byte_b_id, IN_HEAP | IS_ARRAY, copy_b, r0, r1, r15); + // generate and publish arch64-specific bulk copy routines first + // so we can call them from other copy stubs + StubRoutines::aarch64::_copy_byte_f = generate_copy_longs(StubId::stubgen_copy_byte_f_id, IN_HEAP | IS_ARRAY, r0, r1, r15); + StubRoutines::aarch64::_copy_byte_b = generate_copy_longs(StubId::stubgen_copy_byte_b_id, IN_HEAP | IS_ARRAY, r0, r1, r15); - generate_copy_longs(StubId::stubgen_copy_oop_f_id, IN_HEAP | IS_ARRAY, copy_obj_f, r0, r1, r15); - generate_copy_longs(StubId::stubgen_copy_oop_b_id, IN_HEAP | IS_ARRAY, copy_obj_b, r0, r1, r15); + StubRoutines::aarch64::_copy_oop_f = generate_copy_longs(StubId::stubgen_copy_oop_f_id, IN_HEAP | IS_ARRAY, r0, r1, r15); + StubRoutines::aarch64::_copy_oop_b = generate_copy_longs(StubId::stubgen_copy_oop_b_id, IN_HEAP | IS_ARRAY, r0, r1, r15); - generate_copy_longs(StubId::stubgen_copy_oop_uninit_f_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, copy_obj_uninit_f, r0, r1, r15); - generate_copy_longs(StubId::stubgen_copy_oop_uninit_b_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, copy_obj_uninit_b, r0, r1, r15); + StubRoutines::aarch64::_copy_oop_uninit_f = generate_copy_longs(StubId::stubgen_copy_oop_uninit_f_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, r0, r1, r15); + StubRoutines::aarch64::_copy_oop_uninit_b = generate_copy_longs(StubId::stubgen_copy_oop_uninit_b_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, r0, r1, r15); StubRoutines::aarch64::_zero_blocks = generate_zero_blocks(); //*** jbyte // Always need aligned and unaligned versions - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id, &entry); - StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_jbyte_arraycopy_id, entry, &entry_jbyte_arraycopy); - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jbyte_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jbyte_arraycopy_id, entry, nullptr); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jbyte_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_jbyte_arraycopy_id, StubRoutines::_jbyte_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jbyte_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jbyte_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jbyte_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jbyte_arraycopy_id, StubRoutines::_arrayof_jbyte_disjoint_arraycopy_nopush, nullptr); //*** jshort // Always need aligned and unaligned versions - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jshort_disjoint_arraycopy_id, &entry); - StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_jshort_arraycopy_id, entry, &entry_jshort_arraycopy); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jshort_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jshort_arraycopy_id, entry, nullptr); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jshort_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jshort_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_jshort_arraycopy_id, StubRoutines::_jshort_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is used by generic/unsafe copy + StubRoutines::_jshort_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jshort_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jshort_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jshort_arraycopy_id, StubRoutines::_arrayof_jshort_disjoint_arraycopy_nopush, nullptr); //*** jint // Aligned versions - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jint_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jint_arraycopy_id, entry, &entry_jint_arraycopy); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jint_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jint_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jint_arraycopy_id, StubRoutines::_arrayof_jint_disjoint_arraycopy_nopush, nullptr); // In 64 bit we need both aligned and unaligned versions of jint arraycopy. - // entry_jint_arraycopy always points to the unaligned version - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &entry); - StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_jint_arraycopy_id, entry, &entry_jint_arraycopy); + // jint_arraycopy_nopush always points to the unaligned version + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jint_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_jint_arraycopy_id, StubRoutines::_jint_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jint_arraycopy_nopush = nopush_entry; //*** jlong // It is always aligned - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jlong_arraycopy_id, entry, &entry_jlong_arraycopy); + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jlong_arraycopy_id, StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jlong_arraycopy_nopush = nopush_entry; + // disjoint normal/nopush and conjoint normal entries are not + // generated since the arrayof versions are the same StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; + StubRoutines::_jlong_disjoint_arraycopy_nopush = StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush; StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; //*** oops { - // With compressed oops we need unaligned versions; notice that - // we overwrite entry_oop_arraycopy. - bool aligned = !UseCompressedOops; - StubRoutines::_arrayof_oop_disjoint_arraycopy - = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_id, &entry); + = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush = nopush_entry; StubRoutines::_arrayof_oop_arraycopy - = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_id, entry, &entry_oop_arraycopy); + = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_id, StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint arrayof nopush entry is needed by generic/unsafe copy + StubRoutines::_oop_arraycopy_nopush = nopush_entry; // Aligned versions without pre-barriers StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit - = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_uninit_id, &entry); + = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_uninit_id, &nopush_entry); + // disjoint arrayof+uninit nopush entry is needed by conjoint copy + StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic/unsafe copy does not cater for uninit arrays. StubRoutines::_arrayof_oop_arraycopy_uninit - = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_uninit_id, entry, nullptr); + = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_uninit_id, StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush, nullptr); } + // for oop copies reuse arrayof entries for non-arrayof cases StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy; + StubRoutines::_oop_disjoint_arraycopy_nopush = StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush; StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy; StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit; + StubRoutines::_oop_disjoint_arraycopy_uninit_nopush = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush; StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit; - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &entry_checkcast_arraycopy); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &nopush_entry); + // checkcast nopush entry is needed by generic copy + StubRoutines::_checkcast_arraycopy_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic copy does not cater for uninit arrays. StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_uninit_id, nullptr); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_jlong_arraycopy); + // unsafe arraycopy may fallback on conjoint stubs + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(StubRoutines::_jbyte_arraycopy_nopush, + StubRoutines::_jshort_arraycopy_nopush, + StubRoutines::_jint_arraycopy_nopush, + StubRoutines::_jlong_arraycopy_nopush); - StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_oop_arraycopy, - entry_jlong_arraycopy, - entry_checkcast_arraycopy); + // generic arraycopy may fallback on conjoint stubs + StubRoutines::_generic_arraycopy = generate_generic_copy(StubRoutines::_jbyte_arraycopy_nopush, + StubRoutines::_jshort_arraycopy_nopush, + StubRoutines::_jint_arraycopy_nopush, + StubRoutines::_oop_arraycopy_nopush, + StubRoutines::_jlong_arraycopy_nopush, + StubRoutines::_checkcast_arraycopy_nopush); StubRoutines::_jbyte_fill = generate_fill(StubId::stubgen_jbyte_fill_id); StubRoutines::_jshort_fill = generate_fill(StubId::stubgen_jshort_fill_id); @@ -3402,14 +3451,9 @@ class StubGenerator: public StubCodeGenerator { // counter = c_rarg7 - 16 bytes of CTR // return - number of processed bytes address generate_galoisCounterMode_AESCrypt() { - address ghash_polynomial = __ pc(); - __ emit_int64(0x87); // The low-order bits of the field - // polynomial (i.e. p = z^7+z^2+z+1) - // repeated in the low and high parts of a - // 128-bit vector - __ emit_int64(0x87); + Label ghash_polynomial; // local data generated after code - __ align(CodeEntryAlignment); + __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_galoisCounterMode_AESCrypt_id; StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3514,7 +3558,17 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(lr); - return start; + + // bind label and generate polynomial data + __ align(wordSize * 2); + __ bind(ghash_polynomial); + __ emit_int64(0x87); // The low-order bits of the field + // polynomial (i.e. p = z^7+z^2+z+1) + // repeated in the low and high parts of a + // 128-bit vector + __ emit_int64(0x87); + + return start; } class Cached64Bytes { @@ -4559,16 +4613,6 @@ class StubGenerator: public StubCodeGenerator { // by the second lane from all vectors and so on. address generate_chacha20Block_blockpar() { Label L_twoRounds, L_cc20_const; - // The constant data is broken into two 128-bit segments to be loaded - // onto FloatRegisters. The first 128 bits are a counter add overlay - // that adds +0/+1/+2/+3 to the vector holding replicated state[12]. - // The second 128-bits is a table constant used for 8-bit left rotations. - __ BIND(L_cc20_const); - __ emit_int64(0x0000000100000000UL); - __ emit_int64(0x0000000300000002UL); - __ emit_int64(0x0605040702010003UL); - __ emit_int64(0x0E0D0C0F0A09080BUL); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_chacha20Block_id; StubCodeMark mark(this, stub_id); @@ -4716,6 +4760,17 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // bind label and generate local constant data used by this stub + // The constant data is broken into two 128-bit segments to be loaded + // onto FloatRegisters. The first 128 bits are a counter add overlay + // that adds +0/+1/+2/+3 to the vector holding replicated state[12]. + // The second 128-bits is a table constant used for 8-bit left rotations. + __ BIND(L_cc20_const); + __ emit_int64(0x0000000100000000UL); + __ emit_int64(0x0000000300000002UL); + __ emit_int64(0x0605040702010003UL); + __ emit_int64(0x0E0D0C0F0A09080BUL); + return start; } @@ -6036,10 +6091,6 @@ class StubGenerator: public StubCodeGenerator { address generate_kyber12To16() { Label L_F00, L_loop, L_end; - __ BIND(L_F00); - __ emit_int64(0x0f000f000f000f00); - __ emit_int64(0x0f000f000f000f00); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyber12To16_id; StubCodeMark mark(this, stub_id); @@ -6233,6 +6284,11 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // bind label and generate constant data used by this stub + __ BIND(L_F00); + __ emit_int64(0x0f000f000f000f00); + __ emit_int64(0x0f000f000f000f00); + return start; } @@ -9642,14 +9698,7 @@ class StubGenerator: public StubCodeGenerator { StubId stub_id = StubId::stubgen_ghash_processBlocks_id; StubCodeMark mark(this, stub_id); - __ align(wordSize * 2); - address p = __ pc(); - __ emit_int64(0x87); // The low-order bits of the field - // polynomial (i.e. p = z^7+z^2+z+1) - // repeated in the low and high parts of a - // 128-bit vector - __ emit_int64(0x87); - + Label polynomial; // local data generated at end of stub __ align(CodeEntryAlignment); address start = __ pc(); @@ -9661,7 +9710,8 @@ class StubGenerator: public StubCodeGenerator { FloatRegister vzr = v30; __ eor(vzr, __ T16B, vzr, vzr); // zero register - __ ldrq(v24, p); // The field polynomial + __ adr(rscratch1, polynomial); + __ ldrq(v24, rscratch1); // The field polynomial __ ldrq(v0, Address(state)); __ ldrq(v1, Address(subkeyH)); @@ -9701,6 +9751,15 @@ class StubGenerator: public StubCodeGenerator { __ st1(v0, __ T16B, state); __ ret(lr); + // bind label and generate local polynomial data + __ align(wordSize * 2); + __ bind(polynomial); + __ emit_int64(0x87); // The low-order bits of the field + // polynomial (i.e. p = z^7+z^2+z+1) + // repeated in the low and high parts of a + // 128-bit vector + __ emit_int64(0x87); + return start; } @@ -9709,14 +9768,7 @@ class StubGenerator: public StubCodeGenerator { StubId stub_id = StubId::stubgen_ghash_processBlocks_wide_id; StubCodeMark mark(this, stub_id); - __ align(wordSize * 2); - address p = __ pc(); - __ emit_int64(0x87); // The low-order bits of the field - // polynomial (i.e. p = z^7+z^2+z+1) - // repeated in the low and high parts of a - // 128-bit vector - __ emit_int64(0x87); - + Label polynomial; // local data generated after stub __ align(CodeEntryAlignment); address start = __ pc(); @@ -9738,7 +9790,7 @@ class StubGenerator: public StubCodeGenerator { __ st1(v8, v9, v10, v11, __ T16B, Address(sp)); } - __ ghash_processBlocks_wide(p, state, subkeyH, data, blocks, unroll); + __ ghash_processBlocks_wide(polynomial, state, subkeyH, data, blocks, unroll); if (unroll > 1) { // And restore state @@ -9751,7 +9803,17 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // bind label and generate polynomial data + __ align(wordSize * 2); + __ bind(polynomial); + __ emit_int64(0x87); // The low-order bits of the field + // polynomial (i.e. p = z^7+z^2+z+1) + // repeated in the low and high parts of a + // 128-bit vector + __ emit_int64(0x87); + return start; + } void generate_base64_encode_simdround(Register src, Register dst, diff --git a/src/hotspot/cpu/arm/stubGenerator_arm.cpp b/src/hotspot/cpu/arm/stubGenerator_arm.cpp index 2e2e0f7a4b9..a36ad3a0c47 100644 --- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp @@ -3011,6 +3011,10 @@ class StubGenerator: public StubCodeGenerator { // Note: the disjoint stubs must be generated first, some of // the conjoint stubs use them. + // Note: chaining of stubs does not rely on branching to an + // auxiliary post-push entry because none of the stubs + // push/pop a frame. + // these need always status in case they are called from generic_arraycopy StubRoutines::_jbyte_disjoint_arraycopy = generate_primitive_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id); StubRoutines::_jshort_disjoint_arraycopy = generate_primitive_copy(StubId::stubgen_jshort_disjoint_arraycopy_id); @@ -3024,6 +3028,7 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_primitive_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id); StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_oop_copy (StubId::stubgen_arrayof_oop_disjoint_arraycopy_id); + // disjoint copy entry is needed by conjoint copy // these need always status in case they are called from generic_arraycopy StubRoutines::_jbyte_arraycopy = generate_primitive_copy(StubId::stubgen_jbyte_arraycopy_id, StubRoutines::_jbyte_disjoint_arraycopy); StubRoutines::_jshort_arraycopy = generate_primitive_copy(StubId::stubgen_jshort_arraycopy_id, StubRoutines::_jshort_disjoint_arraycopy); diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index f9f43ade501..948092bbb9a 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -3277,8 +3277,12 @@ class StubGenerator: public StubCodeGenerator { // register the stub as the default exit with class UnsafeMemoryAccess UnsafeMemoryAccess::set_common_exit_stub_pc(StubRoutines::_unsafecopy_common_exit); - // Note: the disjoint stubs must be generated first, some of - // the conjoint stubs use them. + // Note: the disjoint stubs must be generated first, some of the + // conjoint stubs use them. + + // Note: chaining of stubs does not rely on branching to an + // auxiliary post-push entry because none of the stubs + // push/pop a frame. // non-aligned disjoint versions StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id); diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 385c839879c..88961ccd5a4 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -732,8 +732,7 @@ class StubGenerator: public StubCodeGenerator { // // s and d are adjusted to point to the remaining words to copy // - void generate_copy_longs(StubId stub_id, Label &start, - Register s, Register d, Register count) { + address generate_copy_longs(StubId stub_id, Register s, Register d, Register count) { BasicType type; copy_direction direction; switch (stub_id) { @@ -763,7 +762,7 @@ class StubGenerator: public StubCodeGenerator { Label again, drain; StubCodeMark mark(this, stub_id); __ align(CodeEntryAlignment); - __ bind(start); + address start = __ pc(); if (direction == copy_forwards) { __ sub(s, s, bias); @@ -879,9 +878,9 @@ class StubGenerator: public StubCodeGenerator { } __ ret(); - } - Label copy_f, copy_b; + return start; + } typedef void (MacroAssembler::*copy_insn)(Register Rd, const Address &adr, Register temp); @@ -1099,8 +1098,8 @@ class StubGenerator: public StubCodeGenerator { // stub_id - is used to name the stub and identify all details of // how to perform the copy. // - // entry - is assigned to the stub's post push entry point unless - // it is null + // nopush_entry - is assigned to the stub's post push entry point + // unless it is null // // Inputs: // c_rarg0 - source array address @@ -1111,11 +1110,11 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - // Side Effects: entry is set to the (post push) entry point so it - // can be used by the corresponding conjoint copy - // method + // Side Effects: nopush_entry is set to the (post push) entry point + // so it can be used by the corresponding conjoint + // copy method // - address generate_disjoint_copy(StubId stub_id, address* entry) { + address generate_disjoint_copy(StubId stub_id, address* nopush_entry) { size_t size; bool aligned; bool is_oop; @@ -1204,8 +1203,8 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); - if (entry != nullptr) { - *entry = __ pc(); + if (nopush_entry != nullptr) { + *nopush_entry = __ pc(); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1256,8 +1255,8 @@ class StubGenerator: public StubCodeGenerator { // corresponding disjoint copy routine which can be // jumped to if the ranges do not actually overlap // - // entry - is assigned to the stub's post push entry point unless - // it is null + // nopush_entry - is assigned to the stub's post push entry point + // unless it is null // // Inputs: // c_rarg0 - source array address @@ -1269,10 +1268,10 @@ class StubGenerator: public StubCodeGenerator { // cache line boundaries will still be loaded and stored atomically. // // Side Effects: - // entry is set to the no-overlap entry point so it can be used by - // some other conjoint copy method + // nopush_entry is set to the no-overlap entry point so it can be + // used by some other conjoint copy method // - address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *entry) { + address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *nopush_entry) { const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_regs = RegSet::of(s, d, count); int size; @@ -1359,8 +1358,8 @@ class StubGenerator: public StubCodeGenerator { address start = __ pc(); __ enter(); - if (entry != nullptr) { - *entry = __ pc(); + if (nopush_entry != nullptr) { + *nopush_entry = __ pc(); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1370,7 +1369,7 @@ class StubGenerator: public StubCodeGenerator { __ slli(t1, count, exact_log2(size)); Label L_continue; __ bltu(t0, t1, L_continue); - __ j(nooverlap_target); + __ j(RuntimeAddress(nooverlap_target)); __ bind(L_continue); DecoratorSet decorators = IN_HEAP | IS_ARRAY; @@ -1445,7 +1444,7 @@ class StubGenerator: public StubCodeGenerator { // x10 == 0 - success // x10 == -1^K - failure, where K is partial transfer count // - address generate_checkcast_copy(StubId stub_id, address* entry) { + address generate_checkcast_copy(StubId stub_id, address* nopush_entry) { bool dest_uninitialized; switch (stub_id) { case StubId::stubgen_checkcast_arraycopy_id: @@ -1496,8 +1495,8 @@ class StubGenerator: public StubCodeGenerator { __ enter(); // required for proper stackwalking of RuntimeStub frame // Caller of this entry point must set up the argument registers. - if (entry != nullptr) { - *entry = __ pc(); + if (nopush_entry != nullptr) { + *nopush_entry = __ pc(); BLOCK_COMMENT("Entry:"); } @@ -2294,13 +2293,21 @@ class StubGenerator: public StubCodeGenerator { } void generate_arraycopy_stubs() { - address entry = nullptr; - address entry_jbyte_arraycopy = nullptr; - address entry_jshort_arraycopy = nullptr; - address entry_jint_arraycopy = nullptr; - address entry_oop_arraycopy = nullptr; - address entry_jlong_arraycopy = nullptr; - address entry_checkcast_arraycopy = nullptr; + // Some copy stubs publish a normal entry and then a 2nd 'fallback' + // entry immediately following their stack push. This can be used + // as a post-push branch target for compatible stubs when they + // identify a special case that can be handled by the fallback + // stub e.g a disjoint copy stub may be use as a special case + // fallback for its compatible conjoint copy stub. + // + // A no push entry is always returned in the following local and + // then published by assigning to the appropriate entry field in + // class StubRoutines. The entry value is then passed to the + // generator for the compatible stub. That means the entry must be + // listed when saving to/restoring from the AOT cache, ensuring + // that the inter-stub jumps are noted at AOT-cache save and + // relocated at AOT cache load. + address nopush_entry = nullptr; // generate the common exit first so later stubs can rely on it if // they want an UnsafeMemoryAccess exit non-local to the stub @@ -2308,72 +2315,117 @@ class StubGenerator: public StubCodeGenerator { // register the stub as the default exit with class UnsafeMemoryAccess UnsafeMemoryAccess::set_common_exit_stub_pc(StubRoutines::_unsafecopy_common_exit); - generate_copy_longs(StubId::stubgen_copy_byte_f_id, copy_f, c_rarg0, c_rarg1, t1); - generate_copy_longs(StubId::stubgen_copy_byte_b_id, copy_b, c_rarg0, c_rarg1, t1); + // generate and publish riscv-specific bulk copy routines first + // so we can call them from other copy stubs + StubRoutines::riscv::_copy_byte_f = generate_copy_longs(StubId::stubgen_copy_byte_f_id, c_rarg0, c_rarg1, t1); + StubRoutines::riscv::_copy_byte_b = generate_copy_longs(StubId::stubgen_copy_byte_b_id, c_rarg0, c_rarg1, t1); StubRoutines::riscv::_zero_blocks = generate_zero_blocks(); //*** jbyte // Always need aligned and unaligned versions - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id, &entry); - StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_jbyte_arraycopy_id, entry, &entry_jbyte_arraycopy); - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jbyte_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jbyte_arraycopy_id, entry, nullptr); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jbyte_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_jbyte_arraycopy_id, StubRoutines::_jbyte_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jbyte_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jbyte_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jbyte_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jbyte_arraycopy_id, StubRoutines::_arrayof_jbyte_disjoint_arraycopy_nopush, nullptr); //*** jshort // Always need aligned and unaligned versions - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jshort_disjoint_arraycopy_id, &entry); - StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_jshort_arraycopy_id, entry, &entry_jshort_arraycopy); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jshort_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jshort_arraycopy_id, entry, nullptr); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jshort_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jshort_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_jshort_arraycopy_id, StubRoutines::_jshort_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is used by generic/unsafe copy + StubRoutines::_jshort_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jshort_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jshort_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jshort_arraycopy_id, StubRoutines::_arrayof_jshort_disjoint_arraycopy_nopush, nullptr); //*** jint // Aligned versions - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jint_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jint_arraycopy_id, entry, &entry_jint_arraycopy); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jint_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jint_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jint_arraycopy_id, StubRoutines::_arrayof_jint_disjoint_arraycopy_nopush, nullptr); // In 64 bit we need both aligned and unaligned versions of jint arraycopy. // entry_jint_arraycopy always points to the unaligned version - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &entry); - StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_jint_arraycopy_id, entry, &entry_jint_arraycopy); + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jint_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_jint_arraycopy_id, StubRoutines::_jint_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jint_arraycopy_nopush = nopush_entry; //*** jlong // It is always aligned - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id, &entry); - StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jlong_arraycopy_id, entry, &entry_jlong_arraycopy); + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jlong_arraycopy_id, StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jlong_arraycopy_nopush = nopush_entry; + // disjoint normal/nopush and conjoint normal entries are not + // generated since the arrayof versions are the same StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; + StubRoutines::_jlong_disjoint_arraycopy_nopush = StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush; StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; //*** oops StubRoutines::_arrayof_oop_disjoint_arraycopy - = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_id, &entry); + = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_id, &nopush_entry); + // disjoint arrayof nopush entry is needed by conjoint copy + StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush = nopush_entry; StubRoutines::_arrayof_oop_arraycopy - = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_id, entry, &entry_oop_arraycopy); + = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_id, StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint arrayof nopush entry is needed by generic/unsafe copy + StubRoutines::_oop_arraycopy_nopush = nopush_entry; // Aligned versions without pre-barriers StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit - = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_uninit_id, &entry); - StubRoutines::_arrayof_oop_arraycopy_uninit - = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_uninit_id, entry, nullptr); + = generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_uninit_id, &nopush_entry); + // disjoint arrayof+uninit nopush entry is needed by conjoint copy + StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic/unsafe copy does not cater for uninit arrays. + StubRoutines::_arrayof_oop_arraycopy_uninit + = generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_uninit_id, StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush, nullptr); + + // for oop copies reuse arrayof entries for non-arrayof cases StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy; + StubRoutines::_oop_disjoint_arraycopy_nopush = StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush; StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy; StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit; + StubRoutines::_oop_disjoint_arraycopy_uninit_nopush = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush; StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit; - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &entry_checkcast_arraycopy); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &nopush_entry); + // checkcast nopush entry is needed by generic copy + StubRoutines::_checkcast_arraycopy_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic copy does not cater for uninit arrays. StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_uninit_id, nullptr); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_jlong_arraycopy); + // unsafe arraycopy may fallback on conjoint stubs + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(StubRoutines::_jbyte_arraycopy_nopush, + StubRoutines::_jshort_arraycopy_nopush, + StubRoutines::_jint_arraycopy_nopush, + StubRoutines::_jlong_arraycopy_nopush); - StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_oop_arraycopy, - entry_jlong_arraycopy, - entry_checkcast_arraycopy); + // generic arraycopy may fallback on conjoint stubs + StubRoutines::_generic_arraycopy = generate_generic_copy(StubRoutines::_jbyte_arraycopy_nopush, + StubRoutines::_jshort_arraycopy_nopush, + StubRoutines::_jint_arraycopy_nopush, + StubRoutines::_oop_arraycopy_nopush, + StubRoutines::_jlong_arraycopy_nopush, + StubRoutines::_checkcast_arraycopy_nopush); StubRoutines::_jbyte_fill = generate_fill(StubId::stubgen_jbyte_fill_id); StubRoutines::_jshort_fill = generate_fill(StubId::stubgen_jshort_fill_id); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp index 743457f87af..d53fafafdb4 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp @@ -76,50 +76,95 @@ static uint& get_profile_ctr(int shift) { #endif // !PRODUCT void StubGenerator::generate_arraycopy_stubs() { - address entry; - address entry_jbyte_arraycopy; - address entry_jshort_arraycopy; - address entry_jint_arraycopy; - address entry_oop_arraycopy; - address entry_jlong_arraycopy; - address entry_checkcast_arraycopy; + // Some copy stubs publish a normal entry and then a 2nd 'fallback' + // entry immediately following their stack push. This can be used + // as a post-push branch target for compatible stubs when they + // identify a special case that can be handled by the fallback + // stub e.g a disjoint copy stub may be use as a special case + // fallback for its compatible conjoint copy stub. + // + // A no push entry is always returned in the following local and + // then published by assigning to the appropriate entry field in + // class StubRoutines. The entry value is then passed to the + // generator for the compatible stub. That means the entry must be + // listed when saving to/restoring from the AOT cache, ensuring + // that the inter-stub jumps are noted at AOT-cache save and + // relocated at AOT cache load. + address nopush_entry; - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(&entry); - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(entry, &entry_jbyte_arraycopy); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(&nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jbyte_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(StubRoutines::_jbyte_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jbyte_arraycopy_nopush = nopush_entry; - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(&entry); - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(entry, &entry_jshort_arraycopy); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(&nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jshort_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(StubRoutines::_jshort_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jshort_arraycopy_nopush = nopush_entry; - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &entry); - StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(StubId::stubgen_jint_arraycopy_id, entry, &entry_jint_arraycopy); + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jint_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(StubId::stubgen_jint_arraycopy_id, StubRoutines::_jint_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jint_arraycopy_nopush = nopush_entry; + + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(StubId::stubgen_jlong_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_jlong_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(StubId::stubgen_jlong_arraycopy_id, StubRoutines::_jlong_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_jlong_arraycopy_nopush = nopush_entry; - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(StubId::stubgen_jlong_disjoint_arraycopy_id, &entry); - StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(StubId::stubgen_jlong_arraycopy_id, entry, &entry_jlong_arraycopy); if (UseCompressedOops) { - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_id, &entry); - StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(StubId::stubgen_oop_arraycopy_id, entry, &entry_oop_arraycopy); - StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_uninit_id, &entry); - StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(StubId::stubgen_oop_arraycopy_uninit_id, entry, nullptr); + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_oop_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(StubId::stubgen_oop_arraycopy_id, StubRoutines::_oop_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_oop_arraycopy_nopush = nopush_entry; + StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_uninit_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_oop_disjoint_arraycopy_uninit_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic/unsafe copy does not cater for uninit arrays. + StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(StubId::stubgen_oop_arraycopy_uninit_id, StubRoutines::_oop_disjoint_arraycopy_uninit_nopush, nullptr); } else { - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_id, &entry); - StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(StubId::stubgen_oop_arraycopy_id, entry, &entry_oop_arraycopy); - StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_uninit_id, &entry); - StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(StubId::stubgen_oop_arraycopy_uninit_id, entry, nullptr); + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_oop_disjoint_arraycopy_nopush = nopush_entry; + StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(StubId::stubgen_oop_arraycopy_id, StubRoutines::_oop_disjoint_arraycopy_nopush, &nopush_entry); + // conjoint nopush entry is needed by generic/unsafe copy + StubRoutines::_oop_arraycopy_nopush = nopush_entry; + StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(StubId::stubgen_oop_disjoint_arraycopy_uninit_id, &nopush_entry); + // disjoint nopush entry is needed by conjoint copy + StubRoutines::_oop_disjoint_arraycopy_uninit_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic/unsafe copy does not cater for uninit arrays. + StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(StubId::stubgen_oop_arraycopy_uninit_id, StubRoutines::_oop_disjoint_arraycopy_uninit_nopush, nullptr); } - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &entry_checkcast_arraycopy); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &nopush_entry); + // checkcast nopush entry is needed by generic copy + StubRoutines::_checkcast_arraycopy_nopush = nopush_entry; + // note that we don't need a returned nopush entry because the + // generic copy does not cater for uninit arrays. StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_uninit_id, nullptr); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_jlong_arraycopy); - StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_oop_arraycopy, - entry_jlong_arraycopy, - entry_checkcast_arraycopy); + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(StubRoutines::_jbyte_arraycopy_nopush, + StubRoutines::_jshort_arraycopy_nopush, + StubRoutines::_jint_arraycopy_nopush, + StubRoutines::_jlong_arraycopy_nopush); + StubRoutines::_generic_arraycopy = generate_generic_copy(StubRoutines::_jbyte_arraycopy_nopush, + StubRoutines::_jshort_arraycopy_nopush, + StubRoutines::_jint_arraycopy_nopush, + StubRoutines::_oop_arraycopy_nopush, + StubRoutines::_jlong_arraycopy_nopush, + StubRoutines::_checkcast_arraycopy_nopush); StubRoutines::_jbyte_fill = generate_fill(StubId::stubgen_jbyte_fill_id); StubRoutines::_jshort_fill = generate_fill(StubId::stubgen_jshort_fill_id); diff --git a/src/hotspot/share/runtime/stubDeclarations.hpp b/src/hotspot/share/runtime/stubDeclarations.hpp index c79caa12a6c..b051c6d0e18 100644 --- a/src/hotspot/share/runtime/stubDeclarations.hpp +++ b/src/hotspot/share/runtime/stubDeclarations.hpp @@ -891,18 +891,28 @@ do_stub(final, jbyte_arraycopy) \ do_entry_init(final, jbyte_arraycopy, jbyte_arraycopy, \ jbyte_arraycopy, StubRoutines::jbyte_copy) \ + do_entry(final, jbyte_arraycopy, jbyte_arraycopy_nopush, \ + jbyte_arraycopy_nopush) \ do_stub(final, jshort_arraycopy) \ do_entry_init(final, jshort_arraycopy, jshort_arraycopy, \ jshort_arraycopy, StubRoutines::jshort_copy) \ + do_entry(final, jshort_arraycopy, jshort_arraycopy_nopush, \ + jshort_arraycopy_nopush) \ do_stub(final, jint_arraycopy) \ do_entry_init(final, jint_arraycopy, jint_arraycopy, \ jint_arraycopy, StubRoutines::jint_copy) \ + do_entry(final, jint_arraycopy, jint_arraycopy_nopush, \ + jint_arraycopy_nopush) \ do_stub(final, jlong_arraycopy) \ do_entry_init(final, jlong_arraycopy, jlong_arraycopy, \ jlong_arraycopy, StubRoutines::jlong_copy) \ + do_entry(final, jlong_arraycopy, jlong_arraycopy_nopush, \ + jlong_arraycopy_nopush) \ do_stub(final, oop_arraycopy) \ do_entry_init(final, oop_arraycopy, oop_arraycopy, \ oop_arraycopy_entry, StubRoutines::oop_copy) \ + do_entry(final, oop_arraycopy, oop_arraycopy_nopush, \ + oop_arraycopy_nopush) \ do_stub(final, oop_arraycopy_uninit) \ do_entry_init(final, oop_arraycopy_uninit, oop_arraycopy_uninit, \ oop_arraycopy_uninit_entry, \ @@ -911,26 +921,44 @@ do_entry_init(final, jbyte_disjoint_arraycopy, \ jbyte_disjoint_arraycopy, jbyte_disjoint_arraycopy, \ StubRoutines::jbyte_copy) \ + do_entry(final, jbyte_disjoint_arraycopy, \ + jbyte_disjoint_arraycopy_nopush, \ + jbyte_disjoint_arraycopy_nopush) \ do_stub(final, jshort_disjoint_arraycopy) \ do_entry_init(final, jshort_disjoint_arraycopy, \ jshort_disjoint_arraycopy, jshort_disjoint_arraycopy, \ StubRoutines::jshort_copy) \ + do_entry(final, jshort_disjoint_arraycopy, \ + jshort_disjoint_arraycopy_nopush, \ + jshort_disjoint_arraycopy_nopush) \ do_stub(final, jint_disjoint_arraycopy) \ do_entry_init(final, jint_disjoint_arraycopy, \ jint_disjoint_arraycopy, jint_disjoint_arraycopy, \ StubRoutines::jint_copy) \ + do_entry(final, jint_disjoint_arraycopy, \ + jint_disjoint_arraycopy_nopush, \ + jint_disjoint_arraycopy_nopush) \ do_stub(final, jlong_disjoint_arraycopy) \ do_entry_init(final, jlong_disjoint_arraycopy, \ jlong_disjoint_arraycopy, jlong_disjoint_arraycopy, \ StubRoutines::jlong_copy) \ + do_entry(final, jlong_disjoint_arraycopy, \ + jlong_disjoint_arraycopy_nopush, \ + jlong_disjoint_arraycopy_nopush) \ do_stub(final, oop_disjoint_arraycopy) \ do_entry_init(final, oop_disjoint_arraycopy, oop_disjoint_arraycopy, \ oop_disjoint_arraycopy_entry, StubRoutines::oop_copy) \ + do_entry(final, oop_disjoint_arraycopy, \ + oop_disjoint_arraycopy_nopush, \ + oop_disjoint_arraycopy_nopush) \ do_stub(final, oop_disjoint_arraycopy_uninit) \ do_entry_init(final, oop_disjoint_arraycopy_uninit, \ oop_disjoint_arraycopy_uninit, \ oop_disjoint_arraycopy_uninit_entry, \ StubRoutines::oop_copy_uninit) \ + do_entry(final, oop_disjoint_arraycopy_uninit, \ + oop_disjoint_arraycopy_uninit_nopush, \ + oop_disjoint_arraycopy_uninit_nopush) \ do_stub(final, arrayof_jbyte_arraycopy) \ do_entry_init(final, arrayof_jbyte_arraycopy, \ arrayof_jbyte_arraycopy, arrayof_jbyte_arraycopy, \ @@ -960,34 +988,54 @@ arrayof_jbyte_disjoint_arraycopy, \ arrayof_jbyte_disjoint_arraycopy, \ StubRoutines::arrayof_jbyte_copy) \ + do_entry(final, arrayof_jbyte_disjoint_arraycopy, \ + arrayof_jbyte_disjoint_arraycopy_nopush, \ + arrayof_jbyte_disjoint_arraycopy_nopush) \ do_stub(final, arrayof_jshort_disjoint_arraycopy) \ do_entry_init(final, arrayof_jshort_disjoint_arraycopy, \ arrayof_jshort_disjoint_arraycopy, \ arrayof_jshort_disjoint_arraycopy, \ StubRoutines::arrayof_jshort_copy) \ + do_entry(final, arrayof_jshort_disjoint_arraycopy, \ + arrayof_jshort_disjoint_arraycopy_nopush, \ + arrayof_jshort_disjoint_arraycopy_nopush) \ do_stub(final, arrayof_jint_disjoint_arraycopy) \ do_entry_init(final, arrayof_jint_disjoint_arraycopy, \ arrayof_jint_disjoint_arraycopy, \ arrayof_jint_disjoint_arraycopy, \ StubRoutines::arrayof_jint_copy) \ + do_entry(final, arrayof_jint_disjoint_arraycopy, \ + arrayof_jint_disjoint_arraycopy_nopush, \ + arrayof_jint_disjoint_arraycopy_nopush) \ do_stub(final, arrayof_jlong_disjoint_arraycopy) \ do_entry_init(final, arrayof_jlong_disjoint_arraycopy, \ arrayof_jlong_disjoint_arraycopy, \ arrayof_jlong_disjoint_arraycopy, \ StubRoutines::arrayof_jlong_copy) \ + do_entry(final, arrayof_jlong_disjoint_arraycopy, \ + arrayof_jlong_disjoint_arraycopy_nopush, \ + arrayof_jlong_disjoint_arraycopy_nopush) \ do_stub(final, arrayof_oop_disjoint_arraycopy) \ do_entry_init(final, arrayof_oop_disjoint_arraycopy, \ arrayof_oop_disjoint_arraycopy, \ arrayof_oop_disjoint_arraycopy_entry, \ StubRoutines::arrayof_oop_copy) \ + do_entry(final, arrayof_oop_disjoint_arraycopy, \ + arrayof_oop_disjoint_arraycopy_nopush, \ + arrayof_oop_disjoint_arraycopy_nopush) \ do_stub(final, arrayof_oop_disjoint_arraycopy_uninit) \ do_entry_init(final, arrayof_oop_disjoint_arraycopy_uninit, \ arrayof_oop_disjoint_arraycopy_uninit, \ arrayof_oop_disjoint_arraycopy_uninit_entry, \ StubRoutines::arrayof_oop_copy_uninit) \ + do_entry(final, arrayof_oop_disjoint_arraycopy_uninit, \ + arrayof_oop_disjoint_arraycopy_uninit_nopush, \ + arrayof_oop_disjoint_arraycopy_uninit_nopush) \ do_stub(final, checkcast_arraycopy) \ do_entry(final, checkcast_arraycopy, checkcast_arraycopy, \ checkcast_arraycopy_entry) \ + do_entry(final, checkcast_arraycopy, checkcast_arraycopy_nopush, \ + checkcast_arraycopy_nopush) \ do_stub(final, checkcast_arraycopy_uninit) \ do_entry(final, checkcast_arraycopy_uninit, \ checkcast_arraycopy_uninit, \ From 6df01178c03968bee7994eddd187f790c74ba541 Mon Sep 17 00:00:00 2001 From: Saranya Natarajan Date: Wed, 17 Sep 2025 09:45:30 +0000 Subject: [PATCH 117/120] 8356779: IGV: dump the index of the SafePointNode containing the current JVMS during parsing Reviewed-by: epeter, chagedorn, qamai --- src/hotspot/share/opto/parse2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index 04b6e49b620..8b44d8b3491 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -2779,7 +2779,7 @@ void Parse::do_one_bytecode() { if (C->should_print_igv(perBytecode)) { IdealGraphPrinter* printer = C->igv_printer(); char buffer[256]; - jio_snprintf(buffer, sizeof(buffer), "Bytecode %d: %s", bci(), Bytecodes::name(bc())); + jio_snprintf(buffer, sizeof(buffer), "Bytecode %d: %s, map: %d", bci(), Bytecodes::name(bc()), map() == nullptr ? -1 : map()->_idx); bool old = printer->traverse_outs(); printer->set_traverse_outs(true); printer->print_graph(buffer); From c28142e7c142b2938823451c1f638f56a7f969d2 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 17 Sep 2025 10:26:26 +0000 Subject: [PATCH 118/120] 8367737: Parallel: Retry allocation after lock acquire in mem_allocate_work Reviewed-by: fandreuzzi, tschatzl, iwalulya --- .../gc/parallel/parallelScavengeHeap.cpp | 54 +++++++++++-------- .../gc/parallel/parallelScavengeHeap.hpp | 1 + 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 81412e2f614..213e8f95d63 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -275,38 +275,46 @@ HeapWord* ParallelScavengeHeap::mem_allocate(size_t size) { return mem_allocate_work(size, is_tlab); } +HeapWord* ParallelScavengeHeap::mem_allocate_cas_noexpand(size_t size, bool is_tlab) { + // Try young-gen first. + HeapWord* result = young_gen()->allocate(size); + if (result != nullptr) { + return result; + } + + // Try allocating from the old gen for non-TLAB in certain scenarios. + if (!is_tlab) { + if (!should_alloc_in_eden(size) || _is_heap_almost_full) { + result = old_gen()->cas_allocate_noexpand(size); + if (result != nullptr) { + return result; + } + } + } + + return nullptr; +} + HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size, bool is_tlab) { for (uint loop_count = 0; /* empty */; ++loop_count) { - // Try young-gen first. - HeapWord* result = young_gen()->allocate(size); + HeapWord* result = mem_allocate_cas_noexpand(size, is_tlab); if (result != nullptr) { return result; } - // Try allocating from the old gen for non-TLAB in certain scenarios. - if (!is_tlab) { - if (!should_alloc_in_eden(size) || _is_heap_almost_full) { - result = old_gen()->cas_allocate_noexpand(size); - if (result != nullptr) { - return result; - } - } - } - - // We don't want to have multiple collections for a single filled generation. - // To prevent this, each thread tracks the total_collections() value, and if - // the count has changed, does not do a new collection. - // - // The collection count must be read only while holding the heap lock. VM - // operations also hold the heap lock during collections. There is a lock - // contention case where thread A blocks waiting on the Heap_lock, while - // thread B is holding it doing a collection. When thread A gets the lock, - // the collection count has already changed. To prevent duplicate collections, - // The policy MUST attempt allocations during the same period it reads the - // total_collections() value! + // Read total_collections() under the lock so that multiple + // allocation-failures result in one GC. uint gc_count; { MutexLocker ml(Heap_lock); + + // Re-try after acquiring the lock, because a GC might have occurred + // while waiting for this lock. + result = mem_allocate_cas_noexpand(size, is_tlab); + if (result != nullptr) { + return result; + } + gc_count = total_collections(); } diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index b1176a1637b..fea827430ca 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -100,6 +100,7 @@ class ParallelScavengeHeap : public CollectedHeap { inline bool should_alloc_in_eden(size_t size) const; + HeapWord* mem_allocate_cas_noexpand(size_t size, bool is_tlab); HeapWord* mem_allocate_work(size_t size, bool is_tlab); HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); From 4719ed671a8a8e10b77c4748a0e1ee63c19dfefb Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Wed, 17 Sep 2025 11:25:49 +0000 Subject: [PATCH 119/120] 8366777: Build fails unknown pseudo-op with old AS on linux-aarch64 Reviewed-by: erikj, ihse --- make/autoconf/flags-cflags.m4 | 42 -------------------------- make/autoconf/flags-other.m4 | 56 +++++++++++++++++++++++++++++++++++ make/autoconf/flags.m4 | 1 + 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 6072cbc74dd..0e2825d14b0 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -934,48 +934,6 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], IF_FALSE: [$2FDLIBM_CFLAGS=""]) fi AC_SUBST($2FDLIBM_CFLAGS) - - # Check whether the compiler supports the Arm C Language Extensions (ACLE) - # for SVE. Set SVE_CFLAGS to -march=armv8-a+sve if it does. - # ACLE and this flag are required to build the aarch64 SVE related functions in - # libvectormath. Apple Silicon does not support SVE; use macOS as a proxy for - # that check. - if test "x$OPENJDK_TARGET_CPU" = "xaarch64" && test "x$OPENJDK_TARGET_OS" = "xlinux"; then - if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then - AC_LANG_PUSH(C) - OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -march=armv8-a+sve" - AC_MSG_CHECKING([if Arm SVE ACLE is supported]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], - [ - svint32_t r = svdup_n_s32(1); - return 0; - ])], - [ - AC_MSG_RESULT([yes]) - $2SVE_CFLAGS="-march=armv8-a+sve" - # Switching the initialization mode with gcc from 'pattern' to 'zero' - # avoids the use of unsupported `__builtin_clear_padding` for variable - # length aggregates - if test "x$DEBUG_LEVEL" != xrelease && test "x$TOOLCHAIN_TYPE" = xgcc ; then - INIT_ZERO_FLAG="-ftrivial-auto-var-init=zero" - FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$INIT_ZERO_FLAG], - IF_TRUE: [ - $2SVE_CFLAGS="${$2SVE_CFLAGS} $INIT_ZERO_FLAG" - ] - ) - fi - ], - [ - AC_MSG_RESULT([no]) - $2SVE_CFLAGS="" - ] - ) - CFLAGS="$OLD_CFLAGS" - AC_LANG_POP(C) - fi - fi - AC_SUBST($2SVE_CFLAGS) ]) AC_DEFUN_ONCE([FLAGS_SETUP_BRANCH_PROTECTION], diff --git a/make/autoconf/flags-other.m4 b/make/autoconf/flags-other.m4 index 9d41cf04791..4570f6ede78 100644 --- a/make/autoconf/flags-other.m4 +++ b/make/autoconf/flags-other.m4 @@ -107,6 +107,62 @@ AC_DEFUN([FLAGS_SETUP_NMFLAGS], AC_SUBST(NMFLAGS) ]) +# Check whether the compiler supports the Arm C Language Extensions (ACLE) +# for SVE. Set SVE_CFLAGS to -march=armv8-a+sve if it does. +# ACLE and this flag are required to build the aarch64 SVE related functions +# in libvectormath. +AC_DEFUN([FLAGS_SETUP_SVE], +[ + AARCH64_SVE_AVAILABLE=false + # Apple Silicon does not support SVE; use macOS as a proxy for that check. + if test "x$OPENJDK_TARGET_CPU" = "xaarch64" && test "x$OPENJDK_TARGET_OS" = "xlinux"; then + if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then + # check the compiler and binutils support sve or not + AC_MSG_CHECKING([if Arm SVE ACLE is supported]) + AC_LANG_PUSH([C]) + saved_cflags="$CFLAGS" + CFLAGS="$CFLAGS -march=armv8-a+sve $CFLAGS_WARNINGS_ARE_ERRORS ARG_ARGUMENT" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [ + #include + svfloat64_t a() {} + ], + [ + svint32_t r = svdup_n_s32(1) + ])], + [ + AARCH64_SVE_AVAILABLE=true + ] + ) + CFLAGS="$saved_cflags" + AC_LANG_POP([C]) + AC_MSG_RESULT([$AARCH64_SVE_AVAILABLE]) + fi + fi + + UTIL_ARG_ENABLE(NAME: aarch64-sve, DEFAULT: auto, + RESULT: AARCH64_SVE_ENABLED, + DESC: [Use SVE when compiling libsleef], + AVAILABLE: $AARCH64_SVE_AVAILABLE) + SVE_CFLAGS="" + if test "x$AARCH64_SVE_ENABLED" = xtrue; then + SVE_CFLAGS="-march=armv8-a+sve" + # Switching the initialization mode with gcc from 'pattern' to 'zero' + # avoids the use of unsupported `__builtin_clear_padding` for variable + # length aggregates + if test "x$DEBUG_LEVEL" != xrelease && test "x$TOOLCHAIN_TYPE" = xgcc ; then + AC_MSG_CHECKING([Switching the initialization mode with gcc from pattern to zero]) + INIT_ZERO_FLAG="-ftrivial-auto-var-init=zero" + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$INIT_ZERO_FLAG], + IF_TRUE: [ + SVE_CFLAGS="${SVE_CFLAGS} $INIT_ZERO_FLAG" + ] + ) + fi + fi + AC_SUBST(SVE_CFLAGS) +]) + ################################################################################ # platform independent AC_DEFUN([FLAGS_SETUP_ASFLAGS], diff --git a/make/autoconf/flags.m4 b/make/autoconf/flags.m4 index c810d15ebbc..10647305757 100644 --- a/make/autoconf/flags.m4 +++ b/make/autoconf/flags.m4 @@ -374,6 +374,7 @@ AC_DEFUN([FLAGS_SETUP_FLAGS], FLAGS_SETUP_RCFLAGS FLAGS_SETUP_NMFLAGS + FLAGS_SETUP_SVE FLAGS_SETUP_ASFLAGS FLAGS_SETUP_ASFLAGS_CPU_DEP([TARGET]) FLAGS_SETUP_ASFLAGS_CPU_DEP([BUILD], [OPENJDK_BUILD_]) From 7e738f0d906e574706a277fabbc2cc1df6f11f19 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 17 Sep 2025 11:36:23 +0000 Subject: [PATCH 120/120] 8367313: CTW: Execute in AWT headless mode Reviewed-by: epeter, kvn --- .../testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java index d721c7d63c5..11694f72837 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java +++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java @@ -292,6 +292,8 @@ public class CtwRunner { "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.reflect=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED", + // Graphics clinits may run, force headless mode + "-Djava.awt.headless=true", // enable diagnostic logging "-XX:+LogCompilation", // use phase specific log, hs_err and ciReplay files