diff --git a/doc/building.html b/doc/building.html index 3aad6eae0742b..69fb371a4770f 100644 --- a/doc/building.html +++ b/doc/building.html @@ -1499,9 +1499,7 @@

Using Debian debootstrap

--resolve-deps \ buster \ ~/sysroot-arm64 \ - https://httpredir.debian.org/debian/ -

If the target architecture is riscv64, the path should -be debian-ports instead of debian.

+ https://httpredir.debian.org/debian/
  • To create an Ubuntu-based chroot:

    sudo debootstrap \
       --arch=arm64 \
    diff --git a/doc/building.md b/doc/building.md
    index 611cfe15915c8..abbd935f652ab 100644
    --- a/doc/building.md
    +++ b/doc/building.md
    @@ -1316,9 +1316,6 @@ For example, cross-compiling to AArch64 from x86_64 could be done like this:
         https://httpredir.debian.org/debian/
       ```
     
    -  If the target architecture is `riscv64`, the path should be `debian-ports`
    -  instead of `debian`.
    -
     * To create an Ubuntu-based chroot:
     
       ```
    diff --git a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java
    index b6298c00c9a19..442a245f92fea 100644
    --- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java
    +++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2012, 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
    @@ -1289,25 +1289,58 @@ private static Map coverageLevelsMap() throws Exception {
          */
         private static void generateTZDBShortNamesMap() throws IOException {
             Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
    -            .filter(p -> p.toFile().isFile())
    +            .filter(p -> p.toFile().isFile() && !p.endsWith("jdk11_backward"))
                 .forEach(p -> {
                     try {
                         String zone = null;
                         String rule = null;
                         String format = null;
    +                    boolean inVanguard = false;
    +                    boolean inRearguard = false;
                         for (var line : Files.readAllLines(p)) {
    -                        if (line.contains("#STDOFF")) continue;
    +                        // Interpret the line in rearguard mode so that STD/DST
    +                        // correctly handles negative DST cases, such as "GMT/IST"
    +                        // vs. "IST/GMT" case for Europe/Dublin
    +                        if (inVanguard) {
    +                            if (line.startsWith("# Rearguard")) {
    +                                inVanguard = false;
    +                                inRearguard = true;
    +                            }
    +                            continue;
    +                        } else if (line.startsWith("# Vanguard")) {
    +                            inVanguard = true;
    +                            continue;
    +                        }
    +                        if (inRearguard) {
    +                            if (line.startsWith("# End of rearguard")) {
    +                                inRearguard = false;
    +                                continue;
    +                            } else {
    +                                if (line.startsWith("#\t")) {
    +                                    line = line.substring(1); // omit #
    +                                }
    +                            }
    +                        }
    +                        if (line.isBlank() || line.matches("^[ \t]*#.*")) {
    +                            // ignore blank/comment lines
    +                            continue;
    +                        }
    +                        // remove comments in-line
                             line = line.replaceAll("[ \t]*#.*", "");
     
                             // Zone line
                             if (line.startsWith("Zone")) {
    +                            if (zone != null) {
    +                                tzdbShortNamesMap.put(zone, format + NBSP + rule);
    +                            }
                                 var zl = line.split("[ \t]+", -1);
                                 zone = zl[1];
                                 rule = zl[3];
                                 format = zl[4];
                             } else {
                                 if (zone != null) {
    -                                if (line.isBlank()) {
    +                                if (line.startsWith("Rule") ||
    +                                    line.startsWith("Link")) {
                                         tzdbShortNamesMap.put(zone, format + NBSP + rule);
                                         zone = null;
                                         rule = null;
    diff --git a/make/modules/java.instrument/Lib.gmk b/make/modules/java.instrument/Lib.gmk
    index ae985b3158fcf..942462266446d 100644
    --- a/make/modules/java.instrument/Lib.gmk
    +++ b/make/modules/java.instrument/Lib.gmk
    @@ -1,5 +1,5 @@
     #
    -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
    +# Copyright (c) 2011, 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
    @@ -47,7 +47,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
         LDFLAGS_macosx := -L$(call FindLibDirForModule, java.base), \
         LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \
         LIBS := $(JDKLIB_LIBS), \
    -    LIBS_unix := -ljava -ljvm $(LIBZ_LIBS), \
    +    LIBS_unix := $(LIBZ_LIBS), \
         LIBS_linux := -ljli $(LIBDL), \
         LIBS_aix := -liconv -ljli_static $(LIBDL), \
         LIBS_macosx := -ljli -liconv -framework Cocoa -framework Security \
    diff --git a/src/demo/share/jfc/J2Ddemo/java2d/Intro.java b/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
    index 046768e3a6a4b..a4fd2e5b75374 100644
    --- a/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
    +++ b/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
    @@ -1,6 +1,6 @@
     /*
      *
    - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
      *
      * Redistribution and use in source and binary forms, with or without
      * modification, are permitted provided that the following conditions
    @@ -1716,7 +1716,7 @@ public Contributors(int beg, int end, Surface surf) {
                     this.beginning = beg;
                     this.ending = end;
                     fm = surf.getMetrics(font);
    -                java.util.Arrays.sort(members);
    +                Arrays.sort(members);
                     cast.add("CONTRIBUTORS");
                     cast.add(" ");
                     cast.addAll(Arrays.asList(members));
    diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
    index 2293d70c8dacd..63f6c9491c8de 100644
    --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
    +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
    @@ -42,8 +42,12 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
     // and Operational Models for ARMv8"
     #define CPU_MULTI_COPY_ATOMIC
     
    +// The expected size in bytes of a cache line.
     #define DEFAULT_CACHE_LINE_SIZE 64
     
    +// The default padding size for data structures to avoid false sharing.
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
    +
     // According to the ARMv8 ARM, "Concurrent modification and execution
     // of instructions can lead to the resulting instruction performing
     // any behavior that can be achieved by executing any sequence of
    diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
    index c7b45ff0dde17..8694734c751c6 100644
    --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
    +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
    @@ -310,7 +310,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
     
       uint int_args = 0;
       uint fp_args = 0;
    -  uint stk_args = 0; // inc by 2 each time
    +  uint stk_args = 0;
     
       for (int i = 0; i < total_args_passed; i++) {
         switch (sig_bt[i]) {
    @@ -322,8 +322,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (int_args < Argument::n_int_register_parameters_j) {
             regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set1(VMRegImpl::stack2reg(stk_args));
    -        stk_args += 2;
    +        stk_args += 1;
           }
           break;
         case T_VOID:
    @@ -340,6 +341,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (int_args < Argument::n_int_register_parameters_j) {
             regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set2(VMRegImpl::stack2reg(stk_args));
             stk_args += 2;
           }
    @@ -348,8 +350,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (fp_args < Argument::n_float_register_parameters_j) {
             regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set1(VMRegImpl::stack2reg(stk_args));
    -        stk_args += 2;
    +        stk_args += 1;
           }
           break;
         case T_DOUBLE:
    @@ -357,6 +360,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (fp_args < Argument::n_float_register_parameters_j) {
             regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set2(VMRegImpl::stack2reg(stk_args));
             stk_args += 2;
           }
    @@ -367,7 +371,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
         }
       }
     
    -  return align_up(stk_args, 2);
    +  return stk_args;
     }
     
     // Patch the callers callsite with entry to compiled code if it exists.
    diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
    index 6fc6be7a5b34c..1a567049a4654 100644
    --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
    +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
    @@ -3603,11 +3603,9 @@ void TemplateTable::_new() {
       // get InstanceKlass
       __ load_resolved_klass_at_offset(r4, r3, r4, rscratch1);
     
    -  // make sure klass is initialized & doesn't have finalizer
    -  // make sure klass is fully initialized
    -  __ ldrb(rscratch1, Address(r4, InstanceKlass::init_state_offset()));
    -  __ cmp(rscratch1, (u1)InstanceKlass::fully_initialized);
    -  __ br(Assembler::NE, slow_case);
    +  // make sure klass is initialized
    +  assert(VM_Version::supports_fast_class_init_checks(), "Optimization requires support for fast class initialization checks");
    +  __ clinit_barrier(r4, rscratch1, nullptr /*L_fast_path*/, &slow_case);
     
       // get instance_size in InstanceKlass (scaled to a count of bytes)
       __ ldrw(r3,
    diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
    index 8b67a207cf93c..4b2e5cc5a4ddd 100644
    --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
    +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
    @@ -165,6 +165,7 @@ enum Ampere_CPU_Model {
       static int dcache_line_size() { return _dcache_line_size; }
       static int get_initial_sve_vector_length()  { return _initial_sve_vector_length; };
     
    +  // Aarch64 supports fast class initialization checks
       static bool supports_fast_class_init_checks() { return true; }
       constexpr static bool supports_stack_watermark_barrier() { return true; }
     
    diff --git a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp
    index 2041cf9e17ead..5b68dbc9dbd8b 100644
    --- a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp
    +++ b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp
    @@ -49,8 +49,12 @@ const bool HaveVFP = true;
     // arm32 is not specified as multi-copy-atomic
     // So we must not #define CPU_MULTI_COPY_ATOMIC
     
    +// The expected size in bytes of a cache line.
     #define DEFAULT_CACHE_LINE_SIZE 64
     
    +// The default padding size for data structures to avoid false sharing.
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
    +
     #define STUBROUTINES_MD_HPP    "stubRoutines_arm.hpp"
     #define INTERP_MASM_MD_HPP     "interp_masm_arm.hpp"
     #define TEMPLATETABLE_MD_HPP   "templateTable_arm.hpp"
    diff --git a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp
    index 9a65f9f09fe17..716c7b7575e9c 100644
    --- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp
    +++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp
    @@ -441,7 +441,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
         }
       }
     
    -  if (slot & 1) slot++;
       return slot;
     }
     
    diff --git a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
    index bced453d784cf..30670d053fa6e 100644
    --- a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
    +++ b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
    @@ -48,9 +48,12 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
     // PPC64 is not specified as multi-copy-atomic
     // So we must not #define CPU_MULTI_COPY_ATOMIC
     
    -// The expected size in bytes of a cache line, used to pad data structures.
    +// The expected size in bytes of a cache line.
     #define DEFAULT_CACHE_LINE_SIZE 128
     
    +// The default padding size for data structures to avoid false sharing.
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
    +
     #define SUPPORT_RESERVED_STACK_AREA
     
     // If UseSIGTRAP is active, we only use the poll bit and no polling page.
    diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
    index 824996168a95b..3382df355da79 100644
    --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
    +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
    @@ -734,7 +734,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           ShouldNotReachHere();
         }
       }
    -  return align_up(stk, 2);
    +  return stk;
     }
     
     #if defined(COMPILER1) || defined(COMPILER2)
    diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ppc.hpp
    index b1168ded45678..a5831ef1590ad 100644
    --- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp
    +++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp
    @@ -91,7 +91,7 @@ class VM_Version: public Abstract_VM_Version {
       // Override Abstract_VM_Version implementation
       static void print_platform_virtualization_info(outputStream*);
     
    -  // PPC64 supports fast class initialization checks for static methods.
    +  // PPC64 supports fast class initialization checks
       static bool supports_fast_class_init_checks() { return true; }
       constexpr static bool supports_stack_watermark_barrier() { return true; }
     
    diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
    index 3ea70429f21f0..e92b3b521d00a 100644
    --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
    +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
    @@ -3184,6 +3184,17 @@ enum Nf {
         return uabs(target - branch) < branch_range;
       }
     
    +  // Decode the given instruction, checking if it's a 16-bit compressed
    +  // instruction and return the address of the next instruction.
    +  static address locate_next_instruction(address inst) {
    +    // Instruction wider than 16 bits has the two least-significant bits set.
    +    if ((0x3 & *inst) == 0x3) {
    +      return inst + instruction_size;
    +    } else {
    +      return inst + compressed_instruction_size;
    +    }
    +  }
    +
       Assembler(CodeBuffer* code) : AbstractAssembler(code), _in_compressible_region(true) {}
     };
     
    diff --git a/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp
    index f40ffbeefa748..e368bbdc9141f 100644
    --- a/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp
    +++ b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp
    @@ -50,6 +50,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
     
     #define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
     
    +// The expected size in bytes of a cache line.
     #define DEFAULT_CACHE_LINE_SIZE 64
     
    +// The default padding size for data structures to avoid false sharing.
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
    +
     #endif // CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP
    diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
    index 5f5a04cc01f06..5008a0c08c219 100644
    --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
    +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
    @@ -4481,6 +4481,57 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm
       bge(cnt, tmp1, loop);
     }
     
    +// java.lang.Math.round(float a)
    +// Returns the closest int to the argument, with ties rounding to positive infinity.
    +void MacroAssembler::java_round_float(Register dst, FloatRegister src, FloatRegister ftmp) {
    +  // this instructions calling sequence provides performance improvement on all tested devices;
    +  // don't change it without re-verification
    +  Label done;
    +  mv(t0, jint_cast(0.5f));
    +  fmv_w_x(ftmp, t0);
    +
    +  // dst = 0 if NaN
    +  feq_s(t0, src, src); // replacing fclass with feq as performance optimization
    +  mv(dst, zr);
    +  beqz(t0, done);
    +
    +  // dst = (src + 0.5f) rounded down towards negative infinity
    +  //   Adding 0.5f to some floats exceeds the precision limits for a float and rounding takes place.
    +  //   RDN is required for fadd_s, RNE gives incorrect results:
    +  //     --------------------------------------------------------------------
    +  //     fadd.s rne (src + 0.5f): src = 8388609.000000  ftmp = 8388610.000000
    +  //     fcvt.w.s rdn: ftmp = 8388610.000000 dst = 8388610
    +  //     --------------------------------------------------------------------
    +  //     fadd.s rdn (src + 0.5f): src = 8388609.000000  ftmp = 8388609.000000
    +  //     fcvt.w.s rdn: ftmp = 8388609.000000 dst = 8388609
    +  //     --------------------------------------------------------------------
    +  fadd_s(ftmp, src, ftmp, RoundingMode::rdn);
    +  fcvt_w_s(dst, ftmp, RoundingMode::rdn);
    +
    +  bind(done);
    +}
    +
    +// java.lang.Math.round(double a)
    +// Returns the closest long to the argument, with ties rounding to positive infinity.
    +void MacroAssembler::java_round_double(Register dst, FloatRegister src, FloatRegister ftmp) {
    +  // this instructions calling sequence provides performance improvement on all tested devices;
    +  // don't change it without re-verification
    +  Label done;
    +  mv(t0, julong_cast(0.5));
    +  fmv_d_x(ftmp, t0);
    +
    +  // dst = 0 if NaN
    +  feq_d(t0, src, src); // replacing fclass with feq as performance optimization
    +  mv(dst, zr);
    +  beqz(t0, done);
    +
    +  // dst = (src + 0.5) rounded down towards negative infinity
    +  fadd_d(ftmp, src, ftmp, RoundingMode::rdn); // RDN is required here otherwise some inputs produce incorrect results
    +  fcvt_l_d(dst, ftmp, RoundingMode::rdn);
    +
    +  bind(done);
    +}
    +
     #define FCVT_SAFE(FLOATCVT, FLOATSIG)                                                     \
     void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) {     \
       Label done;                                                                             \
    diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
    index 62efb92b7117e..3e5be3886a428 100644
    --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
    +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
    @@ -1279,6 +1279,9 @@ class MacroAssembler: public Assembler {
       void fcvt_w_d_safe(Register dst, FloatRegister src, Register tmp = t0);
       void fcvt_l_d_safe(Register dst, FloatRegister src, Register tmp = t0);
     
    +  void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
    +  void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
    +
       // vector load/store unit-stride instructions
       void vlex_v(VectorRegister vd, Register base, Assembler::SEW sew, VectorMask vm = unmasked) {
         switch (sew) {
    diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad
    index 5af25b26a16ad..d5a95b2e3ba5b 100644
    --- a/src/hotspot/cpu/riscv/riscv.ad
    +++ b/src/hotspot/cpu/riscv/riscv.ad
    @@ -8417,6 +8417,34 @@ instruct convN2I(iRegINoSp dst, iRegN src)
       ins_pipe(ialu_reg);
     %}
     
    +instruct round_double_reg(iRegLNoSp dst, fRegD src, fRegD ftmp) %{
    +  match(Set dst (RoundD src));
    +
    +  ins_cost(XFER_COST + BRANCH_COST);
    +  effect(TEMP ftmp);
    +  format %{ "java_round_double $dst, $src\t#@round_double_reg" %}
    +
    +  ins_encode %{
    +    __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
    +  %}
    +
    +  ins_pipe(pipe_slow);
    +%}
    +
    +instruct round_float_reg(iRegINoSp dst, fRegF src, fRegF ftmp) %{
    +  match(Set dst (RoundF src));
    +
    +  ins_cost(XFER_COST + BRANCH_COST);
    +  effect(TEMP ftmp);
    +  format %{ "java_round_float $dst, $src\t#@round_float_reg" %}
    +
    +  ins_encode %{
    +    __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
    +  %}
    +
    +  ins_pipe(pipe_slow);
    +%}
    +
     // Convert oop pointer into compressed form
     instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{
       match(Set dst (EncodeP src));
    diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp
    index f960c78edb9f4..01fe307bc27c3 100644
    --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp
    +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp
    @@ -266,7 +266,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
     
       uint int_args = 0;
       uint fp_args = 0;
    -  uint stk_args = 0; // inc by 2 each time
    +  uint stk_args = 0;
     
       for (int i = 0; i < total_args_passed; i++) {
         switch (sig_bt[i]) {
    @@ -278,8 +278,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
             if (int_args < Argument::n_int_register_parameters_j) {
               regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
             } else {
    +          stk_args = align_up(stk_args, 2);
               regs[i].set1(VMRegImpl::stack2reg(stk_args));
    -          stk_args += 2;
    +          stk_args += 1;
             }
             break;
           case T_VOID:
    @@ -295,6 +296,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
             if (int_args < Argument::n_int_register_parameters_j) {
               regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
             } else {
    +          stk_args = align_up(stk_args, 2);
               regs[i].set2(VMRegImpl::stack2reg(stk_args));
               stk_args += 2;
             }
    @@ -303,8 +305,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
             if (fp_args < Argument::n_float_register_parameters_j) {
               regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
             } else {
    +          stk_args = align_up(stk_args, 2);
               regs[i].set1(VMRegImpl::stack2reg(stk_args));
    -          stk_args += 2;
    +          stk_args += 1;
             }
             break;
           case T_DOUBLE:
    @@ -312,6 +315,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
             if (fp_args < Argument::n_float_register_parameters_j) {
               regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
             } else {
    +          stk_args = align_up(stk_args, 2);
               regs[i].set2(VMRegImpl::stack2reg(stk_args));
               stk_args += 2;
             }
    @@ -321,7 +325,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
         }
       }
     
    -  return align_up(stk_args, 2);
    +  return stk_args;
     }
     
     // Patch the callers callsite with entry to compiled code if it exists.
    diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
    index 921847337306c..1ea853284ff15 100644
    --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp
    +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
    @@ -215,6 +215,9 @@ class VM_Version : public Abstract_VM_Version {
       constexpr static bool supports_stack_watermark_barrier() { return true; }
     
       static bool supports_on_spin_wait() { return UseZihintpause; }
    +
    +  // RISCV64 supports fast class initialization checks
    +  static bool supports_fast_class_init_checks() { return true; }
     };
     
     #endif // CPU_RISCV_VM_VERSION_RISCV_HPP
    diff --git a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
    index 39baf5bf0478e..236d4c5bf69f1 100644
    --- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
    +++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
    @@ -48,6 +48,9 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
     // The expected size in bytes of a cache line, used to pad data structures.
     #define DEFAULT_CACHE_LINE_SIZE 256
     
    +// The default padding size for data structures to avoid false sharing.
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
    +
     #define SUPPORT_RESERVED_STACK_AREA
     
     #endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
    diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp
    index 4798f35f19d05..ed1795cfa339f 100644
    --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp
    +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp
    @@ -755,7 +755,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
             ShouldNotReachHere();
         }
       }
    -  return align_up(stk, 2);
    +  return stk;
     }
     
     int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
    diff --git a/src/hotspot/cpu/s390/vm_version_s390.hpp b/src/hotspot/cpu/s390/vm_version_s390.hpp
    index d72e2712a40dc..93d5b11c473d1 100644
    --- a/src/hotspot/cpu/s390/vm_version_s390.hpp
    +++ b/src/hotspot/cpu/s390/vm_version_s390.hpp
    @@ -410,7 +410,7 @@ class VM_Version: public Abstract_VM_Version {
       // Override Abstract_VM_Version implementation
       static void print_platform_virtualization_info(outputStream*);
     
    -  // s390 supports fast class initialization checks for static methods.
    +  // s390 supports fast class initialization checks
       static bool supports_fast_class_init_checks() { return true; }
     
       // CPU feature query functions
    diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp
    index c262df21e4547..63d6ec9b00f1b 100644
    --- a/src/hotspot/cpu/x86/assembler_x86.cpp
    +++ b/src/hotspot/cpu/x86/assembler_x86.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -889,8 +889,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
         assert(which == imm_operand || which == disp32_operand,
                "which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
     #else
    -    assert((which == call32_operand || which == imm_operand) && is_64bit ||
    -           which == narrow_oop_operand && !is_64bit,
    +    assert(((which == call32_operand || which == imm_operand) && is_64bit) ||
    +           (which == narrow_oop_operand && !is_64bit),
                "which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
     #endif // _LP64
         return ip;
    @@ -7235,7 +7235,7 @@ void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector
     
     // Integer vector arithmetic
     void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
    -  assert(VM_Version::supports_avx() && (vector_len == 0) ||
    +  assert((VM_Version::supports_avx() && (vector_len == 0)) ||
              VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
       InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
       int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
    @@ -7243,7 +7243,7 @@ void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int v
     }
     
     void Assembler::vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
    -  assert(VM_Version::supports_avx() && (vector_len == 0) ||
    +  assert((VM_Version::supports_avx() && (vector_len == 0)) ||
              VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
       InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
       int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
    diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
    index 54e5f55fa2b00..42f675f83c355 100644
    --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
    +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2020, 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
    @@ -5223,8 +5223,8 @@ void C2_MacroAssembler::vector_mask_operation(int opc, Register dst, KRegister m
     
     void C2_MacroAssembler::vector_mask_operation(int opc, Register dst, XMMRegister mask, XMMRegister xtmp,
                                                   Register tmp, int masklen, BasicType bt, int vec_enc) {
    -  assert(vec_enc == AVX_128bit && VM_Version::supports_avx() ||
    -         vec_enc == AVX_256bit && (VM_Version::supports_avx2() || type2aelembytes(bt) >= 4), "");
    +  assert((vec_enc == AVX_128bit && VM_Version::supports_avx()) ||
    +         (vec_enc == AVX_256bit && (VM_Version::supports_avx2() || type2aelembytes(bt) >= 4)), "");
       assert(VM_Version::supports_popcnt(), "");
     
       bool need_clip = false;
    diff --git a/src/hotspot/cpu/x86/frame_x86.inline.hpp b/src/hotspot/cpu/x86/frame_x86.inline.hpp
    index 67e5a1e0c43fe..70008e1011779 100644
    --- a/src/hotspot/cpu/x86/frame_x86.inline.hpp
    +++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -181,7 +181,7 @@ inline bool frame::equal(frame other) const {
                   && unextended_sp() == other.unextended_sp()
                   && fp() == other.fp()
                   && pc() == other.pc();
    -  assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
    +  assert(!ret || (ret && cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
       return ret;
     }
     
    diff --git a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
    index 7eff43471b5dd..2e82453b38002 100644
    --- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
    +++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
    @@ -38,29 +38,18 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
     
     #define CPU_MULTI_COPY_ATOMIC
     
    -// The expected size in bytes of a cache line, used to pad data structures.
    -#if COMPILER1_AND_COMPILER2
    -  #ifdef _LP64
    -    // tiered, 64-bit, large machine
    -    #define DEFAULT_CACHE_LINE_SIZE 128
    -    #define OM_CACHE_LINE_SIZE 64
    -  #else
    -    // tiered, 32-bit, medium machine
    -    #define DEFAULT_CACHE_LINE_SIZE 64
    -  #endif
    -#elif defined(COMPILER1)
    -  // pure C1, 32-bit, small machine
    -  // i486 was the last Intel chip with 16-byte cache line size
    -  #define DEFAULT_CACHE_LINE_SIZE 32
    -#elif defined(COMPILER2)
    -  #ifdef _LP64
    -    // pure C2, 64-bit, large machine
    -    #define DEFAULT_CACHE_LINE_SIZE 128
    -    #define OM_CACHE_LINE_SIZE 64
    -  #else
    -    // pure C2, 32-bit, medium machine
    -    #define DEFAULT_CACHE_LINE_SIZE 64
    -  #endif
    +// The expected size in bytes of a cache line.
    +#define DEFAULT_CACHE_LINE_SIZE 64
    +
    +// The default padding size for data structures to avoid false sharing.
    +#ifdef _LP64
    +// The common wisdom is that adjacent cache line prefetchers on some hardware
    +// may pull two cache lines on access, so we have to pessimistically assume twice
    +// the cache line size for padding. TODO: Check if this is still true for modern
    +// hardware. If not, DEFAULT_CACHE_LINE_SIZE might as well suffice.
    +#define DEFAULT_PADDING_SIZE (DEFAULT_CACHE_LINE_SIZE*2)
    +#else
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
     #endif
     
     #if defined(COMPILER2)
    diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
    index ea6a37d16edba..b474944c4bead 100644
    --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp
    +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
    @@ -111,8 +111,8 @@ class MacroAssembler: public Assembler {
             op == 0xE9 /* jmp */ ||
             op == 0xEB /* short jmp */ ||
             (op & 0xF0) == 0x70 /* short jcc */ ||
    -        op == 0x0F && (branch[1] & 0xF0) == 0x80 /* jcc */ ||
    -        op == 0xC7 && branch[1] == 0xF8 /* xbegin */,
    +        (op == 0x0F && (branch[1] & 0xF0) == 0x80) /* jcc */ ||
    +        (op == 0xC7 && branch[1] == 0xF8) /* xbegin */,
             "Invalid opcode at patch point");
     
         if (op == 0xEB || (op & 0xF0) == 0x70) {
    diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
    index 3ae539bac8d05..571160523cbe4 100644
    --- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
    +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
    @@ -528,8 +528,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
         }
       }
     
    -  // return value can be odd number of VMRegImpl stack slots make multiple of 2
    -  return align_up(stack, 2);
    +  return stack;
     }
     
     // Patch the callers callsite with entry to compiled code if it exists.
    diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
    index bf15dab070369..faa423bcf8e76 100644
    --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
    +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
    @@ -498,7 +498,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
     
       uint int_args = 0;
       uint fp_args = 0;
    -  uint stk_args = 0; // inc by 2 each time
    +  uint stk_args = 0;
     
       for (int i = 0; i < total_args_passed; i++) {
         switch (sig_bt[i]) {
    @@ -510,8 +510,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (int_args < Argument::n_int_register_parameters_j) {
             regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set1(VMRegImpl::stack2reg(stk_args));
    -        stk_args += 2;
    +        stk_args += 1;
           }
           break;
         case T_VOID:
    @@ -528,6 +529,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (int_args < Argument::n_int_register_parameters_j) {
             regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set2(VMRegImpl::stack2reg(stk_args));
             stk_args += 2;
           }
    @@ -536,8 +538,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (fp_args < Argument::n_float_register_parameters_j) {
             regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set1(VMRegImpl::stack2reg(stk_args));
    -        stk_args += 2;
    +        stk_args += 1;
           }
           break;
         case T_DOUBLE:
    @@ -545,6 +548,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
           if (fp_args < Argument::n_float_register_parameters_j) {
             regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
           } else {
    +        stk_args = align_up(stk_args, 2);
             regs[i].set2(VMRegImpl::stack2reg(stk_args));
             stk_args += 2;
           }
    @@ -555,7 +559,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
         }
       }
     
    -  return align_up(stk_args, 2);
    +  return stk_args;
     }
     
     // Patch the callers callsite with entry to compiled code if it exists.
    diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
    index 85f3bbf61094c..cad9e6475c610 100644
    --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
    +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 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
    @@ -2318,7 +2318,7 @@ address StubGenerator::generate_base64_decodeBlock() {
       const Register isURL = c_rarg5;// Base64 or URL character set
       __ movl(isMIME, Address(rbp, 2 * wordSize));
     #else
    -  const Address  dp_mem(rbp, 6 * wordSize);  // length is on stack on Win64
    +  const Address dp_mem(rbp, 6 * wordSize);  // length is on stack on Win64
       const Address isURL_mem(rbp, 7 * wordSize);
       const Register isURL = r10;      // pick the volatile windows register
       const Register dp = r12;
    @@ -2540,10 +2540,12 @@ address StubGenerator::generate_base64_decodeBlock() {
         // output_size in r13
     
         // Strip pad characters, if any, and adjust length and mask
    +    __ addq(length, start_offset);
         __ cmpb(Address(source, length, Address::times_1, -1), '=');
         __ jcc(Assembler::equal, L_padding);
     
         __ BIND(L_donePadding);
    +    __ subq(length, start_offset);
     
         // Output size is (64 - output_size), output mask is (all 1s >> output_size).
         __ kmovql(input_mask, rax);
    diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp
    index b17fc43032c3d..f53a7872451a4 100644
    --- a/src/hotspot/cpu/x86/templateTable_x86.cpp
    +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp
    @@ -4048,11 +4048,16 @@ void TemplateTable::_new() {
       __ load_resolved_klass_at_index(rcx, rcx, rdx);
       __ push(rcx);  // save the contexts of klass for initializing the header
     
    -  // make sure klass is initialized & doesn't have finalizer
    -  // make sure klass is fully initialized
    +  // make sure klass is initialized
    +#ifdef _LP64
    +  assert(VM_Version::supports_fast_class_init_checks(), "must support fast class initialization checks");
    +  __ clinit_barrier(rcx, r15_thread, nullptr /*L_fast_path*/, &slow_case);
    +#else
       __ cmpb(Address(rcx, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
       __ jcc(Assembler::notEqual, slow_case);
    +#endif
     
    +  // make sure klass doesn't have finalizer
       // get instance_size in InstanceKlass (scaled to a count of bytes)
       __ movl(rdx, Address(rcx, Klass::layout_helper_offset()));
       // test to see if it has a finalizer or is malformed in some way
    diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp
    index ac937bef04e7c..df1ea6edd300f 100644
    --- a/src/hotspot/cpu/x86/vm_version_x86.cpp
    +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -1178,7 +1178,7 @@ void VM_Version::get_processor_features() {
         UseMD5Intrinsics = true;
       }
     
    -  if (supports_sha() LP64_ONLY(|| supports_avx2() && supports_bmi2())) {
    +  if (supports_sha() LP64_ONLY(|| (supports_avx2() && supports_bmi2()))) {
         if (FLAG_IS_DEFAULT(UseSHA)) {
           UseSHA = true;
         }
    diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp
    index 454a8f312553a..e521a6ee3bc0e 100644
    --- a/src/hotspot/cpu/x86/vm_version_x86.hpp
    +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp
    @@ -756,7 +756,7 @@ class VM_Version : public Abstract_VM_Version {
       // the intrinsic for java.lang.Thread.onSpinWait()
       static bool supports_on_spin_wait() { return supports_sse2(); }
     
    -  // x86_64 supports fast class initialization checks for static methods.
    +  // x86_64 supports fast class initialization checks
       static bool supports_fast_class_init_checks() {
         return LP64_ONLY(true) NOT_LP64(false); // not implemented on x86_32
       }
    diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
    index 9db209fe48bc3..8d656c136aa89 100644
    --- a/src/hotspot/cpu/x86/x86.ad
    +++ b/src/hotspot/cpu/x86/x86.ad
    @@ -1,5 +1,5 @@
     //
    -// Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
    +// Copyright (c) 2011, 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
    @@ -2532,8 +2532,8 @@ static inline Assembler::ComparisonPredicateFP booltest_pred_to_comparison_pred_
     static void vec_mov_helper(CodeBuffer *cbuf, int src_lo, int dst_lo,
                               int src_hi, int dst_hi, uint ireg, outputStream* st) {
       assert(ireg == Op_VecS || // 32bit vector
    -         (src_lo & 1) == 0 && (src_lo + 1) == src_hi &&
    -         (dst_lo & 1) == 0 && (dst_lo + 1) == dst_hi,
    +         ((src_lo & 1) == 0 && (src_lo + 1) == src_hi &&
    +          (dst_lo & 1) == 0 && (dst_lo + 1) == dst_hi),
              "no non-adjacent vector moves" );
       if (cbuf) {
         C2_MacroAssembler _masm(cbuf);
    diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad
    index 07b3cb35a388d..45cc785a5394d 100644
    --- a/src/hotspot/cpu/x86/x86_32.ad
    +++ b/src/hotspot/cpu/x86/x86_32.ad
    @@ -11142,7 +11142,7 @@ instruct convI2FPR_mem(regFPR dst, memory mem) %{
     
     // Convert an int to a float in xmm; no rounding step needed.
     instruct convI2F_reg(regF dst, rRegI src) %{
    -  predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
    +  predicate( UseSSE==1 || ( UseSSE>=2 && !UseXmmI2F ));
       match(Set dst (ConvI2F src));
       format %{ "CVTSI2SS $dst, $src" %}
       ins_encode %{
    diff --git a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp
    index 810f7de3cb3f6..0f78b3eeefba2 100644
    --- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp
    +++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp
    @@ -30,8 +30,12 @@
     #define SUPPORTS_NATIVE_CX8
     #endif
     
    +// The expected size in bytes of a cache line.
     #define DEFAULT_CACHE_LINE_SIZE 64
     
    +// The default padding size for data structures to avoid false sharing.
    +#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
    +
     #define SUPPORT_MONITOR_COUNT
     
     #include 
    diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp
    index 54c538cf367ed..c75828c0c22f9 100644
    --- a/src/hotspot/os/aix/os_aix.cpp
    +++ b/src/hotspot/os/aix/os_aix.cpp
    @@ -2112,11 +2112,6 @@ bool os::can_commit_large_page_memory() {
       return false;
     }
     
    -bool os::can_execute_large_page_memory() {
    -  // Does not matter, we do not support huge pages.
    -  return false;
    -}
    -
     char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
       assert(file_desc >= 0, "file_desc is not valid");
       char* result = nullptr;
    diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp
    index 18f3cd2b38d49..2f7f31157e89e 100644
    --- a/src/hotspot/os/bsd/os_bsd.cpp
    +++ b/src/hotspot/os/bsd/os_bsd.cpp
    @@ -979,7 +979,7 @@ bool os::dll_address_to_library_name(address addr, char* buf,
     // in case of error it checks if .dll/.so was built for the
     // same architecture as Hotspot is running on
     
    -void *os::Bsd::dlopen_helper(const char *filename, int mode) {
    +void *os::Bsd::dlopen_helper(const char *filename, int mode, char *ebuf, int ebuflen) {
     #ifndef IA32
       bool ieee_handling = IEEE_subnormal_handling_OK();
       if (!ieee_handling) {
    @@ -1005,27 +1005,44 @@ void *os::Bsd::dlopen_helper(const char *filename, int mode) {
       assert(rtn == 0, "fegetenv must succeed");
     #endif // IA32
     
    -  void * result= ::dlopen(filename, RTLD_LAZY);
    -
    +  void* result;
    +  JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
    +  result = ::dlopen(filename, RTLD_LAZY);
    +  if (result == nullptr) {
    +    const char* error_report = ::dlerror();
    +    if (error_report == nullptr) {
    +      error_report = "dlerror returned no error description";
    +    }
    +    if (ebuf != nullptr && ebuflen > 0) {
    +      ::strncpy(ebuf, error_report, ebuflen-1);
    +      ebuf[ebuflen-1]='\0';
    +    }
    +    Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
    +    log_info(os)("shared library load of %s failed, %s", filename, error_report);
    +    JFR_ONLY(load_event.set_error_msg(error_report);)
    +  } else {
    +    Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
    +    log_info(os)("shared library load of %s was successful", filename);
     #ifndef IA32
    -  if (result  != nullptr && ! IEEE_subnormal_handling_OK()) {
    -    // We just dlopen()ed a library that mangled the floating-point
    -    // flags. Silently fix things now.
    -    int rtn = fesetenv(&default_fenv);
    -    assert(rtn == 0, "fesetenv must succeed");
    -    bool ieee_handling_after_issue = IEEE_subnormal_handling_OK();
    -
    -    if (ieee_handling_after_issue) {
    -      Events::log_dll_message(nullptr, "IEEE subnormal handling had to be corrected after loading %s", filename);
    -      log_info(os)("IEEE subnormal handling had to be corrected after loading %s", filename);
    -    } else {
    -      Events::log_dll_message(nullptr, "IEEE subnormal handling could not be corrected after loading %s", filename);
    -      log_info(os)("IEEE subnormal handling could not be corrected after loading %s", filename);
    +    if (! IEEE_subnormal_handling_OK()) {
    +      // We just dlopen()ed a library that mangled the floating-point
    +      // flags. Silently fix things now.
    +      JFR_ONLY(load_event.set_fp_env_correction_attempt(true);)
    +      int rtn = fesetenv(&default_fenv);
    +      assert(rtn == 0, "fesetenv must succeed");
    +
    +      if (IEEE_subnormal_handling_OK()) {
    +        Events::log_dll_message(nullptr, "IEEE subnormal handling had to be corrected after loading %s", filename);
    +        log_info(os)("IEEE subnormal handling had to be corrected after loading %s", filename);
    +        JFR_ONLY(load_event.set_fp_env_correction_success(true);)
    +      } else {
    +        Events::log_dll_message(nullptr, "IEEE subnormal handling could not be corrected after loading %s", filename);
    +        log_info(os)("IEEE subnormal handling could not be corrected after loading %s", filename);
    +        assert(false, "fesetenv didn't work");
    +      }
         }
    -
    -    assert(ieee_handling_after_issue, "fesetenv didn't work");
    -  }
     #endif // IA32
    +  }
     
       return result;
     }
    @@ -1037,30 +1054,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
     #else
       log_info(os)("attempting shared library load of %s", filename);
     
    -  void* result;
    -  JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
    -  result = os::Bsd::dlopen_helper(filename, RTLD_LAZY);
    -  if (result != nullptr) {
    -    Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
    -    // Successful loading
    -    log_info(os)("shared library load of %s was successful", filename);
    -    return result;
    -  }
    -
    -  const char* error_report = ::dlerror();
    -  if (error_report == nullptr) {
    -    error_report = "dlerror returned no error description";
    -  }
    -  if (ebuf != nullptr && ebuflen > 0) {
    -    // Read system error message into ebuf
    -    ::strncpy(ebuf, error_report, ebuflen-1);
    -    ebuf[ebuflen-1]='\0';
    -  }
    -  Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
    -  log_info(os)("shared library load of %s failed, %s", filename, error_report);
    -  JFR_ONLY(load_event.set_error_msg(error_report);)
    -
    -  return nullptr;
    +  return os::Bsd::dlopen_helper(filename, RTLD_LAZY, ebuf, ebuflen);
     #endif // STATIC_BUILD
     }
     #else
    @@ -1071,29 +1065,13 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
       log_info(os)("attempting shared library load of %s", filename);
     
       void* result;
    -  JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
    -  result = os::Bsd::dlopen_helper(filename, RTLD_LAZY);
    +  result = os::Bsd::dlopen_helper(filename, RTLD_LAZY, ebuf, ebuflen);
       if (result != nullptr) {
    -    Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
    -    // Successful loading
    -    log_info(os)("shared library load of %s was successful", filename);
         return result;
       }
     
    -  Elf32_Ehdr elf_head;
    -
    -  const char* const error_report = ::dlerror();
    -  if (error_report == nullptr) {
    -    error_report = "dlerror returned no error description";
    -  }
    -  if (ebuf != nullptr && ebuflen > 0) {
    -    // Read system error message into ebuf
    -    ::strncpy(ebuf, error_report, ebuflen-1);
    -    ebuf[ebuflen-1]='\0';
    -  }
       Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
       log_info(os)("shared library load of %s failed, %s", filename, error_report);
    -  JFR_ONLY(load_event.set_error_msg(error_report);)
       int diag_msg_max_length=ebuflen-strlen(ebuf);
       char* diag_msg_buf=ebuf+strlen(ebuf);
     
    @@ -1102,7 +1080,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
         return nullptr;
       }
     
    -
       int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
     
       if (file_descriptor < 0) {
    @@ -1110,6 +1087,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
         return nullptr;
       }
     
    +  Elf32_Ehdr elf_head;
       bool failed_to_read_elf_head=
         (sizeof(elf_head)!=
          (::read(file_descriptor, &elf_head,sizeof(elf_head))));
    @@ -1809,11 +1787,6 @@ bool os::can_commit_large_page_memory() {
       return false;
     }
     
    -bool os::can_execute_large_page_memory() {
    -  // Does not matter, we do not support huge pages.
    -  return false;
    -}
    -
     char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
       assert(file_desc >= 0, "file_desc is not valid");
       char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);
    diff --git a/src/hotspot/os/bsd/os_bsd.hpp b/src/hotspot/os/bsd/os_bsd.hpp
    index f79212bc43c0f..72de9ca597195 100644
    --- a/src/hotspot/os/bsd/os_bsd.hpp
    +++ b/src/hotspot/os/bsd/os_bsd.hpp
    @@ -70,7 +70,7 @@ class os::Bsd {
       // Real-time clock functions
       static void clock_init(void);
     
    -  static void *dlopen_helper(const char *path, int mode);
    +  static void *dlopen_helper(const char *path, int mode, char *ebuf, int ebuflen);
     
       // Stack repair handling
     
    diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
    index e94e366acc741..5117ccac84bb1 100644
    --- a/src/hotspot/os/linux/os_linux.cpp
    +++ b/src/hotspot/os/linux/os_linux.cpp
    @@ -1,6 +1,6 @@
     /*
    - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
    - * Copyright (c) 2015, 2022 SAP SE. All rights reserved.
    + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2015, 2024 SAP SE. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -1856,18 +1856,19 @@ void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
         if (! IEEE_subnormal_handling_OK()) {
           // We just dlopen()ed a library that mangled the floating-point flags.
           // Attempt to fix things now.
    +      JFR_ONLY(load_event.set_fp_env_correction_attempt(true);)
           int rtn = fesetenv(&default_fenv);
           assert(rtn == 0, "fesetenv must succeed");
    -      bool ieee_handling_after_issue = IEEE_subnormal_handling_OK();
     
    -      if (ieee_handling_after_issue) {
    +      if (IEEE_subnormal_handling_OK()) {
             Events::log_dll_message(nullptr, "IEEE subnormal handling had to be corrected after loading %s", filename);
             log_info(os)("IEEE subnormal handling had to be corrected after loading %s", filename);
    +        JFR_ONLY(load_event.set_fp_env_correction_success(true);)
           } else {
             Events::log_dll_message(nullptr, "IEEE subnormal handling could not be corrected after loading %s", filename);
             log_info(os)("IEEE subnormal handling could not be corrected after loading %s", filename);
    +        assert(false, "fesetenv didn't work");
           }
    -      assert(ieee_handling_after_issue, "fesetenv didn't work");
         }
     #endif // IA32
       }
    @@ -2096,7 +2097,6 @@ const char* distro_files[] = {
       "/etc/mandrake-release",
       "/etc/sun-release",
       "/etc/redhat-release",
    -  "/etc/SuSE-release",
       "/etc/lsb-release",
       "/etc/turbolinux-release",
       "/etc/gentoo-release",
    @@ -2104,6 +2104,7 @@ const char* distro_files[] = {
       "/etc/angstrom-version",
       "/etc/system-release",
       "/etc/os-release",
    +  "/etc/SuSE-release", // Deprecated in favor of os-release since SuSE 12
       nullptr };
     
     void os::Linux::print_distro_info(outputStream* st) {
    @@ -4077,10 +4078,6 @@ bool os::can_commit_large_page_memory() {
       return UseTransparentHugePages;
     }
     
    -bool os::can_execute_large_page_memory() {
    -  return UseTransparentHugePages;
    -}
    -
     char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
       assert(file_desc >= 0, "file_desc is not valid");
       char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);
    diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp
    index 223bc0bd13514..1b5c7850bf23f 100644
    --- a/src/hotspot/os/windows/os_windows.cpp
    +++ b/src/hotspot/os/windows/os_windows.cpp
    @@ -3436,10 +3436,6 @@ bool os::can_commit_large_page_memory() {
       return false;
     }
     
    -bool os::can_execute_large_page_memory() {
    -  return true;
    -}
    -
     static char* reserve_large_pages_individually(size_t size, char* req_addr, bool exec) {
       log_debug(pagesize)("Reserving large pages individually.");
     
    diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
    index 8b9d1178ca567..282467bc9e096 100644
    --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
    +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
    @@ -232,7 +232,7 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
             CompiledMethod* nm = (cb != nullptr) ? cb->as_compiled_method_or_null() : nullptr;
             bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
             if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
    -          address next_pc = pc + NativeCall::instruction_size;
    +          address next_pc = Assembler::locate_next_instruction(pc);
               if (is_unsafe_arraycopy) {
                 next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
               }
    @@ -271,7 +271,7 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
                     thread->thread_state() == _thread_in_native) &&
                     sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                     thread->doing_unsafe_access()) {
    -      address next_pc = pc + NativeCall::instruction_size;
    +      address next_pc = Assembler::locate_next_instruction(pc);
           if (UnsafeCopyMemory::contains_pc(pc)) {
             next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
           }
    diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp
    index 74fd825a07ab5..53fb5fbcf9efe 100644
    --- a/src/hotspot/share/c1/c1_Compilation.cpp
    +++ b/src/hotspot/share/c1/c1_Compilation.cpp
    @@ -76,7 +76,6 @@ static const char * timer_name[] = {
     };
     
     static elapsedTimer timers[max_phase_timers];
    -static uint totalInstructionNodes = 0;
     
     class PhaseTraceTime: public TraceTime {
      private:
    @@ -494,7 +493,6 @@ void Compilation::compile_method() {
       if (log() != nullptr) // Print code cache state into compiler log
         log()->code_cache_state();
     
    -  totalInstructionNodes += Instruction::number_of_instructions();
     }
     
     
    diff --git a/src/hotspot/share/c1/c1_FrameMap.cpp b/src/hotspot/share/c1/c1_FrameMap.cpp
    index c55e41f458398..ace4fe8209db3 100644
    --- a/src/hotspot/share/c1/c1_FrameMap.cpp
    +++ b/src/hotspot/share/c1/c1_FrameMap.cpp
    @@ -72,7 +72,7 @@ CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signa
         }
       }
     
    -  intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
    +  intptr_t out_preserve = align_up(SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs), 2);
       LIR_OprList* args = new LIR_OprList(signature->length());
       for (i = 0; i < sizeargs;) {
         BasicType t = sig_bt[i];
    diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp
    index edf6f29478c4d..fb2aa28ec86a3 100644
    --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp
    +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp
    @@ -4468,7 +4468,9 @@ void GraphBuilder::append_unsafe_get_and_set(ciMethod* callee, bool is_add) {
     
     #ifndef PRODUCT
     void GraphBuilder::print_stats() {
    -  vmap()->print();
    +  if (UseLocalValueNumbering) {
    +    vmap()->print();
    +  }
     }
     #endif // PRODUCT
     
    diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
    index d65c8b2b79ee6..2553b508e1fe3 100644
    --- a/src/hotspot/share/classfile/javaClasses.cpp
    +++ b/src/hotspot/share/classfile/javaClasses.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -1343,7 +1343,7 @@ const char* java_lang_Class::as_external_name(oop java_class) {
     
     Klass* java_lang_Class::array_klass_acquire(oop java_class) {
       Klass* k = ((Klass*)java_class->metadata_field_acquire(_array_klass_offset));
    -  assert(k == nullptr || k->is_klass() && k->is_array_klass(), "should be array klass");
    +  assert(k == nullptr || (k->is_klass() && k->is_array_klass()), "should be array klass");
       return k;
     }
     
    diff --git a/src/hotspot/share/classfile/stringTable.hpp b/src/hotspot/share/classfile/stringTable.hpp
    index 8178e3b3bb7c3..02723a42f420b 100644
    --- a/src/hotspot/share/classfile/stringTable.hpp
    +++ b/src/hotspot/share/classfile/stringTable.hpp
    @@ -25,7 +25,7 @@
     #ifndef SHARE_CLASSFILE_STRINGTABLE_HPP
     #define SHARE_CLASSFILE_STRINGTABLE_HPP
     
    -#include "memory/allocation.hpp"
    +#include "memory/allStatic.hpp"
     #include "memory/padded.hpp"
     #include "oops/oop.hpp"
     #include "oops/oopHandle.hpp"
    @@ -37,15 +37,11 @@ class DumpedInternedStrings;
     class JavaThread;
     class SerializeClosure;
     
    -class StringTable;
     class StringTableConfig;
    -class StringTableCreateEntry;
     
    -class StringTable : public CHeapObj{
    +class StringTable : AllStatic {
       friend class VMStructs;
    -  friend class Symbol;
       friend class StringTableConfig;
    -  friend class StringTableCreateEntry;
     
       static volatile bool _has_work;
     
    diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp
    index 8018604af60bf..bf8c1d84e71a0 100644
    --- a/src/hotspot/share/code/codeCache.cpp
    +++ b/src/hotspot/share/code/codeCache.cpp
    @@ -355,16 +355,8 @@ void CodeCache::initialize_heaps() {
     }
     
     size_t CodeCache::page_size(bool aligned, size_t min_pages) {
    -  if (os::can_execute_large_page_memory()) {
    -    if (InitialCodeCacheSize < ReservedCodeCacheSize) {
    -      // Make sure that the page size allows for an incremental commit of the reserved space
    -      min_pages = MAX2(min_pages, (size_t)8);
    -    }
    -    return aligned ? os::page_size_for_region_aligned(ReservedCodeCacheSize, min_pages) :
    -                     os::page_size_for_region_unaligned(ReservedCodeCacheSize, min_pages);
    -  } else {
    -    return os::vm_page_size();
    -  }
    +  return aligned ? os::page_size_for_region_aligned(ReservedCodeCacheSize, min_pages) :
    +                   os::page_size_for_region_unaligned(ReservedCodeCacheSize, min_pages);
     }
     
     ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size, size_t rs_ps) {
    @@ -1171,7 +1163,11 @@ void CodeCache::initialize() {
         FLAG_SET_ERGO(NonNMethodCodeHeapSize, (uintx)os::vm_page_size());
         FLAG_SET_ERGO(ProfiledCodeHeapSize, 0);
         FLAG_SET_ERGO(NonProfiledCodeHeapSize, 0);
    -    ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize, page_size(false, 8));
    +
    +    // If InitialCodeCacheSize is equal to ReservedCodeCacheSize, then it's more likely
    +    // users want to use the largest available page.
    +    const size_t min_pages = (InitialCodeCacheSize == ReservedCodeCacheSize) ? 1 : 8;
    +    ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize, page_size(false, min_pages));
         // Register CodeHeaps with LSan as we sometimes embed pointers to malloc memory.
         LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size());
         add_heap(rs, "CodeCache", CodeBlobType::All);
    diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp
    index 54a017818fe13..cb185446cccb2 100644
    --- a/src/hotspot/share/code/nmethod.cpp
    +++ b/src/hotspot/share/code/nmethod.cpp
    @@ -3019,7 +3019,7 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bo
             assert(sig_index == sizeargs, "");
           }
           const char* spname = "sp"; // make arch-specific?
    -      intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
    +      SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
           int stack_slot_offset = this->frame_size() * wordSize;
           int tab1 = 14, tab2 = 24;
           int sig_index = 0;
    diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
    index efc6584bda048..a4315ec5f6c48 100644
    --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
    +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
    @@ -167,9 +167,9 @@ class G1CMMarkStack {
         size_t _num_buckets;
         bool _should_grow;
         TaskQueueEntryChunk* volatile* _buckets;
    -    char _pad0[DEFAULT_CACHE_LINE_SIZE];
    +    char _pad0[DEFAULT_PADDING_SIZE];
         volatile size_t _size;
    -    char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)];
    +    char _pad4[DEFAULT_PADDING_SIZE - sizeof(size_t)];
     
         size_t bucket_size(size_t bucket) {
           return (bucket == 0) ?
    @@ -232,12 +232,12 @@ class G1CMMarkStack {
     
       ChunkAllocator _chunk_allocator;
     
    -  char _pad0[DEFAULT_CACHE_LINE_SIZE];
    +  char _pad0[DEFAULT_PADDING_SIZE];
       TaskQueueEntryChunk* volatile _free_list;  // Linked list of free chunks that can be allocated by users.
    -  char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*)];
    +  char _pad1[DEFAULT_PADDING_SIZE - sizeof(TaskQueueEntryChunk*)];
       TaskQueueEntryChunk* volatile _chunk_list; // List of chunks currently containing data.
       volatile size_t _chunks_in_chunk_list;
    -  char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)];
    +  char _pad2[DEFAULT_PADDING_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)];
     
       // Atomically add the given chunk to the list.
       void add_chunk_to_list(TaskQueueEntryChunk* volatile* list, TaskQueueEntryChunk* elem);
    diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
    index b05dd34009a6d..b2ac4b25e9065 100644
    --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
    +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
    @@ -58,56 +58,46 @@ G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thr
       return result;
     }
     
    -G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
    +G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl(uint max_num_threads) :
       _cr(nullptr),
    -  _threads(nullptr),
    -  _max_num_threads(0)
    +  _threads(max_num_threads)
     {}
     
     G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
    -  if (_threads != nullptr) {
    -    for (uint i = 0; i < _max_num_threads; i++) {
    -      G1ConcurrentRefineThread* t = _threads[i];
    -      if (t == nullptr) {
    -#ifdef ASSERT
    -        for (uint j = i + 1; j < _max_num_threads; ++j) {
    -          assert(_threads[j] == nullptr, "invariant");
    -        }
    -#endif // ASSERT
    -        break;
    -      } else {
    -        delete t;
    -      }
    +  while (_threads.is_nonempty()) {
    +    delete _threads.pop();
    +  }
    +}
    +
    +bool G1ConcurrentRefineThreadControl::ensure_threads_created(uint worker_id, bool initializing) {
    +  assert(worker_id < max_num_threads(), "precondition");
    +
    +  while ((uint)_threads.length() <= worker_id) {
    +    G1ConcurrentRefineThread* rt = create_refinement_thread(_threads.length(), initializing);
    +    if (rt == nullptr) {
    +      return false;
         }
    -    FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
    +    _threads.push(rt);
       }
    +
    +  return true;
     }
     
    -jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint max_num_threads) {
    +jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr) {
       assert(cr != nullptr, "G1ConcurrentRefine must not be null");
       _cr = cr;
    -  _max_num_threads = max_num_threads;
     
    -  if (max_num_threads > 0) {
    -    _threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, max_num_threads, mtGC);
    -
    -    _threads[0] = create_refinement_thread(0, true);
    -    if (_threads[0] == nullptr) {
    +  if (max_num_threads() > 0) {
    +    _threads.push(create_refinement_thread(0, true));
    +    if (_threads.at(0) == nullptr) {
           vm_shutdown_during_initialization("Could not allocate primary refinement thread");
           return JNI_ENOMEM;
         }
     
    -    if (UseDynamicNumberOfGCThreads) {
    -      for (uint i = 1; i < max_num_threads; ++i) {
    -        _threads[i] = nullptr;
    -      }
    -    } else {
    -      for (uint i = 1; i < max_num_threads; ++i) {
    -        _threads[i] = create_refinement_thread(i, true);
    -        if (_threads[i] == nullptr) {
    -          vm_shutdown_during_initialization("Could not allocate refinement threads.");
    -          return JNI_ENOMEM;
    -        }
    +    if (!UseDynamicNumberOfGCThreads) {
    +      if (!ensure_threads_created(max_num_threads() - 1, true)) {
    +        vm_shutdown_during_initialization("Could not allocate refinement threads");
    +        return JNI_ENOMEM;
           }
         }
       }
    @@ -117,38 +107,28 @@ jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint ma
     
     #ifdef ASSERT
     void G1ConcurrentRefineThreadControl::assert_current_thread_is_primary_refinement_thread() const {
    -  assert(_threads != nullptr, "No threads");
    -  assert(Thread::current() == _threads[0], "Not primary thread");
    +  assert(Thread::current() == _threads.at(0), "Not primary thread");
     }
     #endif // ASSERT
     
     bool G1ConcurrentRefineThreadControl::activate(uint worker_id) {
    -  assert(worker_id < _max_num_threads, "precondition");
    -  G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
    -  if (thread_to_activate == nullptr) {
    -    thread_to_activate = create_refinement_thread(worker_id, false);
    -    if (thread_to_activate == nullptr) {
    -      return false;
    -    }
    -    _threads[worker_id] = thread_to_activate;
    +  if (ensure_threads_created(worker_id, false)) {
    +    _threads.at(worker_id)->activate();
    +    return true;
       }
    -  thread_to_activate->activate();
    -  return true;
    +
    +  return false;
     }
     
     void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
    -  for (uint i = 0; i < _max_num_threads; i++) {
    -    if (_threads[i] != nullptr) {
    -      tc->do_thread(_threads[i]);
    -    }
    +  for (G1ConcurrentRefineThread* t : _threads) {
    +    tc->do_thread(t);
       }
     }
     
     void G1ConcurrentRefineThreadControl::stop() {
    -  for (uint i = 0; i < _max_num_threads; i++) {
    -    if (_threads[i] != nullptr) {
    -      _threads[i]->stop();
    -    }
    +  for (G1ConcurrentRefineThread* t : _threads) {
    +    t->stop();
       }
     }
     
    @@ -170,12 +150,12 @@ G1ConcurrentRefine::G1ConcurrentRefine(G1Policy* policy) :
       _last_adjust(),
       _needs_adjust(false),
       _threads_needed(policy, adjust_threads_period_ms()),
    -  _thread_control(),
    +  _thread_control(G1ConcRefinementThreads),
       _dcqs(G1BarrierSet::dirty_card_queue_set())
     {}
     
     jint G1ConcurrentRefine::initialize() {
    -  return _thread_control.initialize(this, G1ConcRefinementThreads);
    +  return _thread_control.initialize(this);
     }
     
     G1ConcurrentRefine* G1ConcurrentRefine::create(G1Policy* policy, jint* ecode) {
    diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
    index 4cb66d5d625f4..dd0b62a22ea8c 100644
    --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
    +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
    @@ -30,6 +30,7 @@
     #include "memory/allocation.hpp"
     #include "utilities/debug.hpp"
     #include "utilities/globalDefinitions.hpp"
    +#include "utilities/growableArray.hpp"
     #include "utilities/macros.hpp"
     
     // Forward decl
    @@ -43,24 +44,25 @@ class ThreadClosure;
     // iterate over them.
     class G1ConcurrentRefineThreadControl {
       G1ConcurrentRefine* _cr;
    -  G1ConcurrentRefineThread** _threads;
    -  uint _max_num_threads;
    +  GrowableArrayCHeap _threads;
     
       // Create the refinement thread for the given worker id.
       // If initializing is true, ignore InjectGCWorkerCreationFailure.
       G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing);
     
    +  bool ensure_threads_created(uint worker_id, bool initializing);
    +
       NONCOPYABLE(G1ConcurrentRefineThreadControl);
     
     public:
    -  G1ConcurrentRefineThreadControl();
    +  G1ConcurrentRefineThreadControl(uint max_num_threads);
       ~G1ConcurrentRefineThreadControl();
     
    -  jint initialize(G1ConcurrentRefine* cr, uint max_num_threads);
    +  jint initialize(G1ConcurrentRefine* cr);
     
       void assert_current_thread_is_primary_refinement_thread() const NOT_DEBUG_RETURN;
     
    -  uint max_num_threads() const { return _max_num_threads; }
    +  uint max_num_threads() const { return _threads.capacity(); }
     
       // Activate the indicated thread.  If the thread has not yet been allocated,
       // allocate and then activate.  If allocation is needed and fails, return
    diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp
    index bf25e3828d11f..1dd3a9afacee8 100644
    --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp
    +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp
    @@ -135,7 +135,7 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
         // and install the next list, and meanwhile there can be a thread dealing
         // with the previous list.
         PausedList* volatile _plist;
    -    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(PausedList*));
    +    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(PausedList*));
     
         NONCOPYABLE(PausedBuffers);
     
    @@ -157,19 +157,19 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
         HeadTail take_all();
       };
     
    -  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
       // Upper bound on the number of cards in the completed and paused buffers.
       volatile size_t _num_cards;
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(size_t));
       // If the queue contains more cards than configured here, the
       // mutator must start doing some of the concurrent refinement work.
       volatile size_t _mutator_refinement_threshold;
    -  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
    +  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(size_t));
       // Buffers ready for refinement.
       // NonblockingQueue has inner padding of one cache line.
       NonblockingQueue _completed;
       // Add a trailer padding after NonblockingQueue.
    -  DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
    +  DEFINE_PAD_MINUS_SIZE(3, DEFAULT_PADDING_SIZE, sizeof(BufferNode*));
       // Buffers for which refinement is temporarily paused.
       // PausedBuffers has inner padding, including trailer.
       PausedBuffers _paused;
    diff --git a/src/hotspot/share/gc/g1/g1MonotonicArena.hpp b/src/hotspot/share/gc/g1/g1MonotonicArena.hpp
    index 8a6bb88e008ca..586766a8c8f97 100644
    --- a/src/hotspot/share/gc/g1/g1MonotonicArena.hpp
    +++ b/src/hotspot/share/gc/g1/g1MonotonicArena.hpp
    @@ -125,7 +125,7 @@ class G1MonotonicArena::Segment {
       char* _bottom;  // Actual data.
       // Do not add class member variables beyond this point
     
    -  static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_CACHE_LINE_SIZE); }
    +  static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_PADDING_SIZE); }
     
       static size_t payload_size(uint slot_size, uint num_slots) {
         // The cast (size_t) is required to guard against overflow wrap around.
    diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
    index 8d7ee0b1dfdd0..92aec50def6f2 100644
    --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
    +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
    @@ -95,7 +95,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
       // entries, since entry 0 keeps track of surviving bytes for non-young regions.
       // We also add a few elements at the beginning and at the end in
       // an attempt to eliminate cache contention
    -  const size_t padding_elem_num = (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t));
    +  const size_t padding_elem_num = (DEFAULT_PADDING_SIZE / sizeof(size_t));
       size_t array_length = padding_elem_num + _surviving_words_length + padding_elem_num;
     
       _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
    diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp
    index f270e31f77266..970cce1623ec6 100644
    --- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp
    +++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp
    @@ -66,11 +66,11 @@ class G1RedirtyCardsLocalQueueSet : private PtrQueueSet {
     // collected (and processed) buffers reverts back to collecting, allowing
     // the set to be reused for another round of redirtying.
     class G1RedirtyCardsQueueSet : public PtrQueueSet {
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
       BufferNode::Stack _list;
    -  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
    +  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(size_t));
       volatile size_t _entry_count;
    -  DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
    +  DEFINE_PAD_MINUS_SIZE(3, DEFAULT_PADDING_SIZE, sizeof(BufferNode*));
       BufferNode* _tail;
       DEBUG_ONLY(mutable bool _collecting;)
     
    diff --git a/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp b/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp
    index 57b48d49f9516..e83813c78f48f 100644
    --- a/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp
    +++ b/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp
    @@ -60,7 +60,6 @@ class GCAdaptivePolicyCounters : public GCPolicyCounters {
       PerfVariable*         _decrease_for_footprint_counter;
     
       PerfVariable*         _minor_pause_young_slope_counter;
    -  PerfVariable*         _major_pause_old_slope_counter;
     
       PerfVariable*         _decide_at_full_gc_counter;
     
    diff --git a/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp b/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp
    index 77ecb4da46671..18271fabd050d 100644
    --- a/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp
    +++ b/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp
    @@ -184,8 +184,6 @@ class MutableNUMASpace : public MutableSpace {
       virtual size_t used_in_words() const;
       virtual size_t free_in_words() const;
     
    -  using MutableSpace::capacity_in_words;
    -
       virtual size_t tlab_capacity(Thread* thr) const;
       virtual size_t tlab_used(Thread* thr) const;
       virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
    diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp
    index 0eb16b4dbc3ff..be6d9a501b575 100644
    --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp
    +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp
    @@ -280,7 +280,7 @@ void PSAdaptiveSizePolicy::compute_eden_space_size(
         //
         // Make changes only to affect one of the pauses (the larger)
         // at a time.
    -    adjust_eden_for_pause_time(&desired_promo_size, &desired_eden_size);
    +    adjust_eden_for_pause_time(&desired_eden_size);
     
       } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
         // Adjust only for the minor pause time goal
    @@ -455,7 +455,7 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space(
         // at a time.
         if (is_full_gc) {
           set_decide_at_full_gc(decide_at_full_gc_true);
    -      adjust_promo_for_pause_time(&desired_promo_size, &desired_eden_size);
    +      adjust_promo_for_pause_time(&desired_promo_size);
         }
       } else if (adjusted_mutator_cost() < _throughput_goal) {
         // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
    @@ -592,8 +592,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_minor_pause_time(size_t* desired_eden
       }
     }
     
    -void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_size_ptr,
    -                                                       size_t* desired_eden_size_ptr) {
    +void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_size_ptr) {
     
       size_t promo_heap_delta = 0;
       // Add some checks for a threshold for a change.  For example,
    @@ -627,8 +626,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_siz
         *desired_promo_size_ptr, promo_heap_delta);
     }
     
    -void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t* desired_promo_size_ptr,
    -                                                      size_t* desired_eden_size_ptr) {
    +void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t* desired_eden_size_ptr) {
     
       size_t eden_heap_delta = 0;
       // Add some checks for a threshold for a change.  For example,
    @@ -875,17 +873,6 @@ size_t PSAdaptiveSizePolicy::scale_down(size_t change,
       return reduced_change;
     }
     
    -size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden,
    -                                            uint percent_change) {
    -  size_t eden_heap_delta;
    -  eden_heap_delta = cur_eden / 100 * percent_change;
    -  return eden_heap_delta;
    -}
    -
    -size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) {
    -  return eden_increment(cur_eden, YoungGenerationSizeIncrement);
    -}
    -
     size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
       size_t cur_eden) {
       size_t result = eden_increment(cur_eden,
    @@ -898,23 +885,6 @@ size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
       return align_down(eden_heap_delta, _space_alignment);
     }
     
    -size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
    -  size_t eden_heap_delta = eden_increment(cur_eden) /
    -    AdaptiveSizeDecrementScaleFactor;
    -  return eden_heap_delta;
    -}
    -
    -size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo,
    -                                             uint percent_change) {
    -  size_t promo_heap_delta;
    -  promo_heap_delta = cur_promo / 100 * percent_change;
    -  return promo_heap_delta;
    -}
    -
    -size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) {
    -  return promo_increment(cur_promo, TenuredGenerationSizeIncrement);
    -}
    -
     size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
       size_t cur_promo) {
       size_t result =  promo_increment(cur_promo,
    @@ -927,12 +897,6 @@ size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
       return align_down(promo_heap_delta, _space_alignment);
     }
     
    -size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
    -  size_t promo_heap_delta = promo_increment(cur_promo);
    -  promo_heap_delta = promo_heap_delta / AdaptiveSizeDecrementScaleFactor;
    -  return promo_heap_delta;
    -}
    -
     uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
                                                  bool is_survivor_overflow,
                                                  uint tenuring_threshold,
    diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
    index 1cdc4f0d048e4..f6d4be029fbab 100644
    --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
    +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
    @@ -119,9 +119,8 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
       void adjust_eden_for_minor_pause_time(size_t* desired_eden_size_ptr);
       // Change the generation sizes to achieve a GC pause time goal
       // Returned sizes are not necessarily aligned.
    -  void adjust_promo_for_pause_time(size_t* desired_promo_size_ptr,
    -                                   size_t* desired_eden_size_ptr);
    -  void adjust_eden_for_pause_time(size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr);
    +  void adjust_promo_for_pause_time(size_t* desired_promo_size_ptr);
    +  void adjust_eden_for_pause_time(size_t* desired_eden_size_ptr);
       // Change the generation sizes to achieve an application throughput goal
       // Returned sizes are not necessarily aligned.
       void adjust_promo_for_throughput(bool is_full_gc,
    @@ -136,14 +135,10 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
                                        size_t desired_total);
     
       // Size in bytes for an increment or decrement of eden.
    -  virtual size_t eden_increment(size_t cur_eden, uint percent_change);
    -  virtual size_t eden_decrement(size_t cur_eden);
       size_t eden_decrement_aligned_down(size_t cur_eden);
       size_t eden_increment_with_supplement_aligned_up(size_t cur_eden);
     
       // Size in bytes for an increment or decrement of the promotion area
    -  virtual size_t promo_increment(size_t cur_promo, uint percent_change);
    -  virtual size_t promo_decrement(size_t cur_promo);
       size_t promo_decrement_aligned_down(size_t cur_promo);
       size_t promo_increment_with_supplement_aligned_up(size_t cur_promo);
     
    @@ -174,9 +169,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
       virtual GCPolicyKind kind() const { return _gc_ps_adaptive_size_policy; }
     
      public:
    -  virtual size_t eden_increment(size_t cur_eden);
    -  virtual size_t promo_increment(size_t cur_promo);
    -
       // Accessors for use by performance counters
       AdaptivePaddedNoZeroDevAverage*  avg_promoted() const {
         return _gc_stats.avg_promoted();
    diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
    index 0774597dbfa3c..c0eb546022892 100644
    --- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
    +++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
    @@ -47,9 +47,9 @@ class PCMarkAndPushClosure: public OopClosure {
     public:
       PCMarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
     
    -  template  void do_oop_nv(T* p)      { _compaction_manager->mark_and_push(p); }
    -  virtual void do_oop(oop* p)                     { do_oop_nv(p); }
    -  virtual void do_oop(narrowOop* p)               { do_oop_nv(p); }
    +  template  void do_oop_work(T* p)      { _compaction_manager->mark_and_push(p); }
    +  virtual void do_oop(oop* p)                     { do_oop_work(p); }
    +  virtual void do_oop(narrowOop* p)               { do_oop_work(p); }
     };
     
     class PCIterateMarkAndPushClosure: public ClaimMetadataVisitingOopIterateClosure {
    @@ -60,9 +60,9 @@ class PCIterateMarkAndPushClosure: public ClaimMetadataVisitingOopIterateClosure
         ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_stw_fullgc_mark, rp),
         _compaction_manager(cm) { }
     
    -  template  void do_oop_nv(T* p)      { _compaction_manager->mark_and_push(p); }
    -  virtual void do_oop(oop* p)                     { do_oop_nv(p); }
    -  virtual void do_oop(narrowOop* p)               { do_oop_nv(p); }
    +  template  void do_oop_work(T* p)      { _compaction_manager->mark_and_push(p); }
    +  virtual void do_oop(oop* p)                     { do_oop_work(p); }
    +  virtual void do_oop(narrowOop* p)               { do_oop_work(p); }
     };
     
     inline bool ParCompactionManager::steal(int queue_num, oop& t) {
    diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp
    index ccf01ea30876b..ff6052d5070a7 100644
    --- a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp
    +++ b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp
    @@ -130,9 +130,9 @@ class PCAdjustPointerClosure: public BasicOopIterateClosure {
     public:
       PCAdjustPointerClosure(ParCompactionManager* cm) : _cm(cm) {
       }
    -  template  void do_oop_nv(T* p) { PSParallelCompact::adjust_pointer(p, _cm); }
    -  virtual void do_oop(oop* p)                { do_oop_nv(p); }
    -  virtual void do_oop(narrowOop* p)          { do_oop_nv(p); }
    +  template  void do_oop_work(T* p) { PSParallelCompact::adjust_pointer(p, _cm); }
    +  virtual void do_oop(oop* p)                { do_oop_work(p); }
    +  virtual void do_oop(narrowOop* p)          { do_oop_work(p); }
     
       virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
     private:
    diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp
    index 7610a6e13d77b..149acc1a4297f 100644
    --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp
    +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp
    @@ -173,13 +173,9 @@ void PSPromotionManager::reset_stats() {
     #endif // TASKQUEUE_STATS
     
     PSPromotionManager::PSPromotionManager() {
    -  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
    -
       // We set the old lab's start array.
       _old_lab.set_start_array(old_gen()->start_array());
     
    -  uint queue_size = claimed_stack_depth()->max_elems();
    -
       if (ParallelGCThreads == 1) {
         _target_stack_size = 0;
       } else {
    diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp
    index c1cbeb0f597bb..fd830b831552f 100644
    --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp
    +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp
    @@ -95,14 +95,14 @@ class PSPushContentsClosure: public BasicOopIterateClosure {
      public:
       PSPushContentsClosure(PSPromotionManager* pm) : BasicOopIterateClosure(PSScavenge::reference_processor()), _pm(pm) {}
     
    -  template  void do_oop_nv(T* p) {
    +  template  void do_oop_work(T* p) {
         if (PSScavenge::should_scavenge(p)) {
           _pm->claim_or_forward_depth(p);
         }
       }
     
    -  virtual void do_oop(oop* p)       { do_oop_nv(p); }
    -  virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
    +  virtual void do_oop(oop* p)       { do_oop_work(p); }
    +  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
     };
     
     //
    diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp
    index 69fa18aa0bec7..0c61bc9c30e1e 100644
    --- a/src/hotspot/share/gc/parallel/psScavenge.hpp
    +++ b/src/hotspot/share/gc/parallel/psScavenge.hpp
    @@ -33,12 +33,10 @@
     #include "oops/oop.hpp"
     #include "utilities/stack.hpp"
     
    -class OopStack;
     class ReferenceProcessor;
     class ParallelScavengeHeap;
     class ParallelScavengeTracer;
     class PSIsAliveClosure;
    -class PSRefProcTaskExecutor;
     class STWGCTimer;
     
     class PSScavenge: AllStatic {
    diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.cpp b/src/hotspot/share/gc/parallel/psVirtualspace.cpp
    index f0ccd9a751c85..a4d686d867042 100644
    --- a/src/hotspot/share/gc/parallel/psVirtualspace.cpp
    +++ b/src/hotspot/share/gc/parallel/psVirtualspace.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 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
    @@ -113,7 +113,7 @@ void PSVirtualSpace::verify() const {
     
       // Reserved region must be non-empty or both addrs must be 0.
       assert(reserved_low_addr() < reserved_high_addr() ||
    -         reserved_low_addr() == nullptr && reserved_high_addr() == nullptr,
    +         (reserved_low_addr() == nullptr && reserved_high_addr() == nullptr),
              "bad reserved addrs");
       assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs");
     
    diff --git a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
    index 09e452c2d4997..959fb3102589e 100644
    --- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
    +++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
    @@ -51,15 +51,11 @@ class AdaptiveSizePolicy : public CHeapObj {
         decrease_old_gen_for_throughput_true = -7,
         decrease_young_gen_for_througput_true = -6,
     
    -    increase_old_gen_for_min_pauses_true = -5,
    -    decrease_old_gen_for_min_pauses_true = -4,
    -    decrease_young_gen_for_maj_pauses_true = -3,
         increase_young_gen_for_min_pauses_true = -2,
         increase_old_gen_for_maj_pauses_true = -1,
     
         decrease_young_gen_for_min_pauses_true = 1,
         decrease_old_gen_for_maj_pauses_true = 2,
    -    increase_young_gen_for_maj_pauses_true = 3,
     
         increase_old_gen_for_throughput_true = 4,
         increase_young_gen_for_througput_true = 5,
    @@ -267,12 +263,12 @@ class AdaptiveSizePolicy : public CHeapObj {
         // to use minor_collection_end() in its current form.
       }
     
    -  virtual size_t eden_increment(size_t cur_eden);
    -  virtual size_t eden_increment(size_t cur_eden, uint percent_change);
    -  virtual size_t eden_decrement(size_t cur_eden);
    -  virtual size_t promo_increment(size_t cur_eden);
    -  virtual size_t promo_increment(size_t cur_eden, uint percent_change);
    -  virtual size_t promo_decrement(size_t cur_eden);
    +  size_t eden_increment(size_t cur_eden);
    +  size_t eden_increment(size_t cur_eden, uint percent_change);
    +  size_t eden_decrement(size_t cur_eden);
    +  size_t promo_increment(size_t cur_eden);
    +  size_t promo_increment(size_t cur_eden, uint percent_change);
    +  size_t promo_decrement(size_t cur_eden);
     
       virtual void clear_generation_free_space_flags();
     
    diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp
    index 422fef2431889..1b65ee90b5d7a 100644
    --- a/src/hotspot/share/gc/shared/collectedHeap.cpp
    +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp
    @@ -558,9 +558,13 @@ void CollectedHeap::record_whole_heap_examined_timestamp() {
     
     void CollectedHeap::full_gc_dump(GCTimer* timer, bool before) {
       assert(timer != nullptr, "timer is null");
    +  static uint count = 0;
       if ((HeapDumpBeforeFullGC && before) || (HeapDumpAfterFullGC && !before)) {
    -    GCTraceTime(Info, gc) tm(before ? "Heap Dump (before full gc)" : "Heap Dump (after full gc)", timer);
    -    HeapDumper::dump_heap();
    +    if (FullGCHeapDumpLimit == 0 || count < FullGCHeapDumpLimit) {
    +      GCTraceTime(Info, gc) tm(before ? "Heap Dump (before full gc)" : "Heap Dump (after full gc)", timer);
    +      HeapDumper::dump_heap();
    +      count++;
    +    }
       }
     
       LogTarget(Trace, gc, classhisto) lt;
    diff --git a/src/hotspot/share/gc/shared/freeListAllocator.hpp b/src/hotspot/share/gc/shared/freeListAllocator.hpp
    index d8ab4c4e8bc1b..74b896963a736 100644
    --- a/src/hotspot/share/gc/shared/freeListAllocator.hpp
    +++ b/src/hotspot/share/gc/shared/freeListAllocator.hpp
    @@ -109,10 +109,10 @@ class FreeListAllocator {
       typedef LockFreeStack Stack;
     
       FreeListConfig* _config;
    -  char _name[DEFAULT_CACHE_LINE_SIZE - sizeof(FreeListConfig*)];  // Use name as padding.
    +  char _name[DEFAULT_PADDING_SIZE - sizeof(FreeListConfig*)];  // Use name as padding.
     
     #define DECLARE_PADDED_MEMBER(Id, Type, Name) \
    -  Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_CACHE_LINE_SIZE, sizeof(Type))
    +  Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_PADDING_SIZE, sizeof(Type))
       DECLARE_PADDED_MEMBER(1, volatile size_t, _free_count);
       DECLARE_PADDED_MEMBER(2, Stack, _free_list);
       DECLARE_PADDED_MEMBER(3, volatile bool, _transfer_lock);
    diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp
    index e2b30bc615e13..ae8674c84a9d0 100644
    --- a/src/hotspot/share/gc/shared/gc_globals.hpp
    +++ b/src/hotspot/share/gc/shared/gc_globals.hpp
    @@ -408,11 +408,6 @@
               "Allowed collection cost difference between generations")         \
               range(0, 100)                                                     \
                                                                                 \
    -  product(uint, AdaptiveSizePolicyCollectionCostMargin, 50,                 \
    -          "If collection costs are within margin, reduce both by full "     \
    -          "delta")                                                          \
    -          range(0, 100)                                                     \
    -                                                                            \
       product(uint, YoungGenerationSizeIncrement, 20,                           \
               "Adaptive size percentage change in young generation")            \
               range(0, 100)                                                     \
    diff --git a/src/hotspot/share/gc/shared/satbMarkQueue.hpp b/src/hotspot/share/gc/shared/satbMarkQueue.hpp
    index d92523d7e4f78..78fe203329623 100644
    --- a/src/hotspot/share/gc/shared/satbMarkQueue.hpp
    +++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp
    @@ -85,7 +85,7 @@ class SATBMarkQueue: public PtrQueue {
     
     class SATBMarkQueueSet: public PtrQueueSet {
     
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
       PaddedEnd _list;
       volatile size_t _count_and_process_flag;
       // These are rarely (if ever) changed, so same cache line as count.
    @@ -93,7 +93,7 @@ class SATBMarkQueueSet: public PtrQueueSet {
       size_t _buffer_enqueue_threshold;
       // SATB is only active during marking.  Enqueuing is only done when active.
       bool _all_active;
    -  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 4 * sizeof(size_t));
    +  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, 4 * sizeof(size_t));
     
       BufferNode* get_completed_buffer();
       void abandon_completed_buffers();
    diff --git a/src/hotspot/share/gc/shared/taskTerminator.hpp b/src/hotspot/share/gc/shared/taskTerminator.hpp
    index aac4e065a5ceb..540d91c88bb48 100644
    --- a/src/hotspot/share/gc/shared/taskTerminator.hpp
    +++ b/src/hotspot/share/gc/shared/taskTerminator.hpp
    @@ -72,9 +72,9 @@ class TaskTerminator : public CHeapObj {
       uint _n_threads;
       TaskQueueSetSuper* _queue_set;
     
    -  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
       volatile uint _offered_termination;
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile uint));
     
       Monitor _blocker;
       Thread* _spin_master;
    diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp
    index a5e3dfdf8079d..2e21ba33b0bf7 100644
    --- a/src/hotspot/share/gc/shared/taskqueue.hpp
    +++ b/src/hotspot/share/gc/shared/taskqueue.hpp
    @@ -233,11 +233,11 @@ class TaskQueueSuper: public CHeapObj {
       }
     
     private:
    -  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
     
       // Index of the first free element after the last one pushed (mod N).
       volatile uint _bottom;
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(uint));
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(uint));
     
       // top() is the index of the oldest pushed element (mod N), and tag()
       // is the associated epoch, to distinguish different modifications of
    @@ -245,7 +245,7 @@ class TaskQueueSuper: public CHeapObj {
       // (_bottom - top()) mod N == N-1; the latter indicates underflow
       // during concurrent pop_local/pop_global.
       volatile Age _age;
    -  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(Age));
    +  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(Age));
     
       NONCOPYABLE(TaskQueueSuper);
     
    @@ -396,7 +396,7 @@ class GenericTaskQueue: public TaskQueueSuper {
       // Element array.
       E* _elems;
     
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(E*));
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(E*));
       // Queue owner local variables. Not to be accessed by other threads.
     
       static const uint InvalidQueueId = uint(-1);
    @@ -404,7 +404,7 @@ class GenericTaskQueue: public TaskQueueSuper {
     
       int _seed; // Current random seed used for selecting a random queue during stealing.
     
    -  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(uint) + sizeof(int));
    +  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(uint) + sizeof(int));
     public:
       int next_random_queue_id();
     
    diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
    index acb52602735a5..12eb2aad5e803 100644
    --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
    +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
    @@ -1742,7 +1742,7 @@ void ShenandoahHeap::prepare_update_heap_references(bool concurrent) {
       _update_refs_iterator.reset();
     }
     
    -void ShenandoahHeap::set_gc_state_all_threads() {
    +void ShenandoahHeap::propagate_gc_state_to_java_threads() {
       assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint");
       if (_gc_state_changed) {
         _gc_state_changed = false;
    @@ -1753,7 +1753,7 @@ void ShenandoahHeap::set_gc_state_all_threads() {
       }
     }
     
    -void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
    +void ShenandoahHeap::set_gc_state(uint mask, bool value) {
       assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint");
       _gc_state.set_cond(mask, value);
       _gc_state_changed = true;
    @@ -1761,13 +1761,13 @@ void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
     
     void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) {
       assert(!has_forwarded_objects(), "Not expected before/after mark phase");
    -  set_gc_state_mask(MARKING, in_progress);
    +  set_gc_state(MARKING, in_progress);
       ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
     }
     
     void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) {
       assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint");
    -  set_gc_state_mask(EVACUATION, in_progress);
    +  set_gc_state(EVACUATION, in_progress);
     }
     
     void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) {
    @@ -1779,7 +1779,7 @@ void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) {
     }
     
     void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool cond) {
    -  set_gc_state_mask(WEAK_ROOTS, cond);
    +  set_gc_state(WEAK_ROOTS, cond);
     }
     
     GCTracer* ShenandoahHeap::tracer() {
    @@ -1906,7 +1906,7 @@ void ShenandoahHeap::parallel_cleaning(bool full_gc) {
     }
     
     void ShenandoahHeap::set_has_forwarded_objects(bool cond) {
    -  set_gc_state_mask(HAS_FORWARDED, cond);
    +  set_gc_state(HAS_FORWARDED, cond);
     }
     
     void ShenandoahHeap::set_unload_classes(bool uc) {
    @@ -1945,7 +1945,7 @@ void ShenandoahHeap::set_full_gc_move_in_progress(bool in_progress) {
     }
     
     void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) {
    -  set_gc_state_mask(UPDATEREFS, in_progress);
    +  set_gc_state(UPDATEREFS, in_progress);
     }
     
     void ShenandoahHeap::register_nmethod(nmethod* nm) {
    diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
    index 1873ee040e3f7..deb0a972167e9 100644
    --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
    +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
    @@ -293,12 +293,19 @@ class ShenandoahHeap : public CollectedHeap, public ShenandoahSpaceInfo {
     
       size_t _gc_no_progress_count;
     
    -  void set_gc_state_mask(uint mask, bool value);
    +  // This updates the singlular, global gc state. This must happen on a safepoint.
    +  void set_gc_state(uint mask, bool value);
     
     public:
       char gc_state() const;
    -  void set_gc_state_all_threads();
    -  bool has_gc_state_changed() { return _gc_state_changed; }
    +
    +  // This copies the global gc state into a thread local variable for java threads.
    +  // It is primarily intended to support quick access at barriers.
    +  void propagate_gc_state_to_java_threads();
    +
    +  // This is public to support assertions that the state hasn't been changed off of
    +  // a safepoint and that any changes were propagated to java threads after the safepoint.
    +  bool has_gc_state_changed() const { return _gc_state_changed; }
     
       void set_concurrent_mark_in_progress(bool in_progress);
       void set_evacuation_in_progress(bool in_progress);
    diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
    index 422595e93135c..9eec573cc567b 100644
    --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
    +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
    @@ -89,6 +89,7 @@ class ShenandoahThreadLocalData {
       }
     
       static char gc_state(Thread* thread) {
    +    assert(thread->is_Java_thread(), "GC state is only synchronized to java threads");
         return data(thread)->_gc_state;
       }
     
    diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
    index 970f99ad0f563..eeeb1dcad195a 100644
    --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
    +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
    @@ -62,41 +62,41 @@ void VM_ShenandoahReferenceOperation::doit_epilogue() {
     void VM_ShenandoahInitMark::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT);
       _gc->entry_init_mark();
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
     
     void VM_ShenandoahFinalMarkStartEvac::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT);
       _gc->entry_final_mark();
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
     
     void VM_ShenandoahFullGC::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL);
       _full_gc->entry_full(_gc_cause);
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
     
     void VM_ShenandoahDegeneratedGC::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT);
       _gc->entry_degenerated();
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
     
     void VM_ShenandoahInitUpdateRefs::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT);
       _gc->entry_init_updaterefs();
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
     
     void VM_ShenandoahFinalUpdateRefs::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT);
       _gc->entry_final_updaterefs();
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
     
     void VM_ShenandoahFinalRoots::doit() {
       ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT);
       _gc->entry_final_roots();
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     }
    diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
    index 6a977c2e4a40c..f67cafdb8fe7c 100644
    --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
    +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
    @@ -620,7 +620,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label,
       guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens");
       guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize");
     
    -  ShenandoahHeap::heap()->set_gc_state_all_threads();
    +  ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
     
       // Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check
       ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/);
    diff --git a/src/hotspot/share/gc/x/xHeap.cpp b/src/hotspot/share/gc/x/xHeap.cpp
    index 14661330e132f..75d9bc0846033 100644
    --- a/src/hotspot/share/gc/x/xHeap.cpp
    +++ b/src/hotspot/share/gc/x/xHeap.cpp
    @@ -249,7 +249,7 @@ void XHeap::mark_start() {
       // Enter mark phase
       XGlobalPhase = XPhaseMark;
     
    -  // Reset marking information and mark roots
    +  // Reset marking information
       _mark.start();
     
       // Update statistics
    diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp
    index 3f62ba5bfd14a..5e42fbd7ef8d9 100644
    --- a/src/hotspot/share/gc/z/zGeneration.cpp
    +++ b/src/hotspot/share/gc/z/zGeneration.cpp
    @@ -861,7 +861,7 @@ void ZGenerationYoung::mark_start() {
       // Enter mark phase
       set_phase(Phase::Mark);
     
    -  // Reset marking information and mark roots
    +  // Reset marking information
       _mark.start();
     
       // Flip remembered set bits
    @@ -1213,7 +1213,7 @@ void ZGenerationOld::mark_start() {
       // Enter mark phase
       set_phase(Phase::Mark);
     
    -  // Reset marking information and mark roots
    +  // Reset marking information
       _mark.start();
     
       // Update statistics
    diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp
    index 89dab8382d3a9..af3c1a2dbef3a 100644
    --- a/src/hotspot/share/interpreter/bytecodes.cpp
    +++ b/src/hotspot/share/interpreter/bytecodes.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -536,7 +536,7 @@ jchar Bytecodes::compute_flags(const char* format, jchar more_flags) {
         }
         guarantee(has_size == 0 ||                     // no field yet
                   this_size == has_size ||             // same size
    -              this_size < has_size && *fp == '\0', // last field can be short
    +              (this_size < has_size && *fp == '\0'), // last field can be short
                   "mixed field sizes in format");
         has_size = this_size;
       }
    diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml
    index c1f626a819201..53fa17555c687 100644
    --- a/src/hotspot/share/jfr/metadata/metadata.xml
    +++ b/src/hotspot/share/jfr/metadata/metadata.xml
    @@ -957,6 +957,8 @@
         
         
         
    +    
    +    
       
     
       ();
     }
    @@ -90,8 +90,17 @@ void NativeLibraryUnloadEvent::set_result(bool result) {
       _result = result;
     }
     
    +static void set_additional_data(EventNativeLibraryLoad& event, const NativeLibraryLoadEvent& helper) {
    +  event.set_fpEnvCorrectionAttempt(helper.get_fp_env_correction_attempt());
    +  event.set_fpEnvCorrectionSuccess(helper.get_fp_env_correction_success());
    +}
    +
    +static void set_additional_data(EventNativeLibraryUnload& event, const NativeLibraryUnloadEvent& helper) {
    +  // no additional entries atm. for the unload event
    +}
    +
     template 
    -static void commit(HelperType& helper) {
    +static void commit(const HelperType& helper) {
       if (!helper.has_start_time()) {
         return;
       }
    @@ -101,6 +110,7 @@ static void commit(HelperType& helper) {
       event.set_name(helper.name());
       event.set_errorMessage(helper.error_msg());
       event.set_success(helper.success());
    +  set_additional_data(event, helper);
       Thread* thread = Thread::current();
       assert(thread != nullptr, "invariant");
       if (thread->is_Java_thread()) {
    diff --git a/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp b/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
    index fe8431fdc438e..30281ad4d0540 100644
    --- a/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
    +++ b/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
    @@ -52,10 +52,16 @@ class JfrNativeLibraryEventBase : public StackObj {
     class NativeLibraryLoadEvent : public JfrNativeLibraryEventBase {
      private:
       void** _result;
    +  bool _fp_env_correction_attempt;
    +  bool _fp_env_correction_success;
      public:
       NativeLibraryLoadEvent(const char* name, void** result);
       ~NativeLibraryLoadEvent();
       bool success() const;
    +  bool get_fp_env_correction_attempt() const { return _fp_env_correction_attempt; }
    +  bool get_fp_env_correction_success() const { return _fp_env_correction_success; }
    +  void set_fp_env_correction_attempt(bool v) { _fp_env_correction_attempt = v; }
    +  void set_fp_env_correction_success(bool v) { _fp_env_correction_success = v; }
     };
     
     class NativeLibraryUnloadEvent : public JfrNativeLibraryEventBase {
    diff --git a/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp b/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp
    index 5005b5b8f3f8d..39c40fd714779 100644
    --- a/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp
    +++ b/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp
    @@ -105,9 +105,9 @@ class JfrVersionSystem : public JfrCHeapObj {
       NodePtr synchronize_with(Type version, NodePtr last) const;
       DEBUG_ONLY(void assert_state(const Node* node) const;)
       struct PaddedTip {
    -    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
         volatile Type _value;
    -    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile Type));
    +    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile Type));
       };
       PaddedTip _tip;
       NodePtr _head;
    diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
    index 421ebd7396f43..ff159a490c184 100644
    --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
    +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
    @@ -115,6 +115,13 @@ class CompilerToVM {
         // Minimum alignment of an offset into CodeBuffer::SECT_CONSTS
         static int data_section_item_alignment;
     
    +    /*
    +     * Pointer to JvmtiExport::_should_notify_object_alloc.
    +     * Exposed as an int* instead of an address so the
    +     * underlying type is part of the JVMCIVMStructs definition.
    +     */
    +    static int* _should_notify_object_alloc;
    +
        public:
          static void initialize(JVMCI_TRAPS);
     
    diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
    index a3e2bd525ecf6..89fa78b10f30e 100644
    --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
    +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
    @@ -45,6 +45,7 @@
     #include "memory/universe.hpp"
     #include "oops/compressedOops.hpp"
     #include "oops/klass.inline.hpp"
    +#include "prims/jvmtiExport.hpp"
     #ifdef COMPILER2
     #include "opto/c2compiler.hpp"
     #endif
    @@ -130,6 +131,8 @@ address CompilerToVM::Data::symbol_clinit;
     
     int CompilerToVM::Data::data_section_item_alignment;
     
    +int* CompilerToVM::Data::_should_notify_object_alloc;
    +
     void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
       Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
       Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
    @@ -196,6 +199,8 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
     
       data_section_item_alignment = relocInfo::addr_unit();
     
    +  _should_notify_object_alloc = &JvmtiExport::_should_notify_object_alloc;
    +
       BarrierSet* bs = BarrierSet::barrier_set();
       if (bs->is_a(BarrierSet::CardTableBarrierSet)) {
         CardTable::CardValue* base = ci_card_table_address();
    diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
    index bac9a786fd9fb..2ad442db93483 100644
    --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
    +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
    @@ -122,6 +122,8 @@
                                                                                                                                          \
       static_field(CompilerToVM::Data,             data_section_item_alignment,            int)                                          \
                                                                                                                                          \
    +  static_field(CompilerToVM::Data,             _should_notify_object_alloc,            int*)                                         \
    +                                                                                                                                     \
       static_field(Abstract_VM_Version,            _features,                              uint64_t)                                     \
                                                                                                                                          \
       nonstatic_field(Annotations,                 _class_annotations,                     AnnotationArray*)                             \
    diff --git a/src/hotspot/share/memory/padded.hpp b/src/hotspot/share/memory/padded.hpp
    index 1811810c19e42..0597dbd9f3c20 100644
    --- a/src/hotspot/share/memory/padded.hpp
    +++ b/src/hotspot/share/memory/padded.hpp
    @@ -40,14 +40,14 @@
     // effective only when applied to derived-most (leaf) classes.
     
     // When no args are passed to the base ctor.
    -template 
    +template 
     class Padded : public T {
      private:
       char _pad_buf_[PADDING_SIZE(T, alignment)];
     };
     
     // When either 0 or 1 args may be passed to the base ctor.
    -template 
    +template 
     class Padded01 : public T {
      public:
       Padded01(): T() { }
    @@ -75,7 +75,7 @@ class PaddedEndImpl : public T {
     // minimal amount of padding needed to make the size of the objects be aligned.
     // This will help reducing false sharing,
     // if the start address is a multiple of alignment.
    -template 
    +template 
     class PaddedEnd : public PaddedEndImpl {
       // C++ doesn't allow zero-length arrays. The padding is put in a
       // super class that is specialized for the pad_size == 0 case.
    @@ -89,7 +89,7 @@ class PaddedEnd : public PaddedEndImpl {
     
     // Helper class to create an array of PaddedEnd objects. All elements will
     // start at a multiple of alignment and the size will be aligned to alignment.
    -template 
    +template 
     class PaddedArray {
      public:
       // Creates an aligned padded array.
    @@ -100,7 +100,7 @@ class PaddedArray {
     // Helper class to create an array of references to arrays of primitive types
     // Both the array of references and the data arrays are aligned to the given
     // alignment. The allocated memory is zero-filled.
    -template 
    +template 
     class Padded2DArray {
      public:
       // Creates an aligned padded 2D array.
    @@ -112,7 +112,7 @@ class Padded2DArray {
     
     // Helper class to create an array of T objects. The array as a whole will
     // start at a multiple of alignment and its size will be aligned to alignment.
    -template 
    +template 
     class PaddedPrimitiveArray {
      public:
       static T* create_unfreeable(size_t length);
    diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
    index 25ec68cf8fec5..dfeb6b11f6f21 100644
    --- a/src/hotspot/share/memory/universe.cpp
    +++ b/src/hotspot/share/memory/universe.cpp
    @@ -338,7 +338,7 @@ void Universe::genesis(TRAPS) {
           // Initialization of the fillerArrayKlass must come before regular
           // int-TypeArrayKlass so that the int-Array mirror points to the
           // int-TypeArrayKlass.
    -      _fillerArrayKlassObj = TypeArrayKlass::create_klass(T_INT, "Ljdk/internal/vm/FillerArray;", CHECK);
    +      _fillerArrayKlassObj = TypeArrayKlass::create_klass(T_INT, "[Ljdk/internal/vm/FillerElement;", CHECK);
           for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
             _typeArrayKlassObjs[i] = TypeArrayKlass::create_klass((BasicType)i, CHECK);
           }
    diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp
    index 5963fd194c531..eec628b1e5bd3 100644
    --- a/src/hotspot/share/oops/constantPool.hpp
    +++ b/src/hotspot/share/oops/constantPool.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -539,7 +539,7 @@ class ConstantPool : public Metadata {
         int offset = build_int_from_shorts(operands->at(n+0),
                                            operands->at(n+1));
         // The offset itself must point into the second part of the array.
    -    assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)");
    +    assert(offset == 0 || (offset >= second_part && offset <= operands->length()), "oob (3)");
         return offset;
       }
       static void operand_offset_at_put(Array* operands, int bsms_attribute_index, int offset) {
    diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
    index 0922fc4eac773..5cd59a802be22 100644
    --- a/src/hotspot/share/oops/method.cpp
    +++ b/src/hotspot/share/oops/method.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -326,7 +326,7 @@ int Method::bci_from(address bcp) const {
       }
       // Do not have a ResourceMark here because AsyncGetCallTrace stack walking code
       // may call this after interrupting a nested ResourceMark.
    -  assert(is_native() && bcp == code_base() || contains(bcp) || VMError::is_error_reported(),
    +  assert((is_native() && bcp == code_base()) || contains(bcp) || VMError::is_error_reported(),
              "bcp doesn't belong to this method. bcp: " PTR_FORMAT, p2i(bcp));
     
       return int(bcp - code_base());
    @@ -360,7 +360,7 @@ address Method::bcp_from(int bci) const {
       assert((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()),
              "illegal bci: %d for %s method", bci, is_native() ? "native" : "non-native");
       address bcp = code_base() + bci;
    -  assert(is_native() && bcp == code_base() || contains(bcp), "bcp doesn't belong to this method");
    +  assert((is_native() && bcp == code_base()) || contains(bcp), "bcp doesn't belong to this method");
       return bcp;
     }
     
    diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp
    index 34f982d9f407c..89d5ccbb168f5 100644
    --- a/src/hotspot/share/oops/method.hpp
    +++ b/src/hotspot/share/oops/method.hpp
    @@ -395,7 +395,8 @@ class Method : public Metadata {
       void remove_unshareable_flags() NOT_CDS_RETURN;
     
       // the number of argument reg slots that the compiled method uses on the stack.
    -  int num_stack_arg_slots() const { return constMethod()->num_stack_arg_slots(); }
    +  int num_stack_arg_slots(bool rounded = true) const {
    +    return rounded ? align_up(constMethod()->num_stack_arg_slots(), 2) : constMethod()->num_stack_arg_slots(); }
     
       virtual void metaspace_pointers_do(MetaspaceClosure* iter);
       virtual MetaspaceObj::Type type() const { return MethodType; }
    diff --git a/src/hotspot/share/oops/stackChunkOop.hpp b/src/hotspot/share/oops/stackChunkOop.hpp
    index 36b06ecd3246e..abfe47ad3f1c4 100644
    --- a/src/hotspot/share/oops/stackChunkOop.hpp
    +++ b/src/hotspot/share/oops/stackChunkOop.hpp
    @@ -155,7 +155,7 @@ class stackChunkOopDesc : public instanceOopDesc {
     
       inline void* gc_data() const;
       inline BitMapView bitmap() const;
    -  inline BitMap::idx_t bit_index_for(intptr_t* p) const;
    +  inline BitMap::idx_t bit_index_for(address p) const;
       inline intptr_t* address_for_bit(BitMap::idx_t index) const;
       template  inline BitMap::idx_t bit_index_for(OopT* p) const;
       template  inline OopT* address_for_bit(BitMap::idx_t index) const;
    diff --git a/src/hotspot/share/oops/stackChunkOop.inline.hpp b/src/hotspot/share/oops/stackChunkOop.inline.hpp
    index e19932072664a..c75908610324d 100644
    --- a/src/hotspot/share/oops/stackChunkOop.inline.hpp
    +++ b/src/hotspot/share/oops/stackChunkOop.inline.hpp
    @@ -256,12 +256,13 @@ inline BitMapView stackChunkOopDesc::bitmap() const {
       return bitmap;
     }
     
    -inline BitMap::idx_t stackChunkOopDesc::bit_index_for(intptr_t* p) const {
    +inline BitMap::idx_t stackChunkOopDesc::bit_index_for(address p) const {
       return UseCompressedOops ? bit_index_for((narrowOop*)p) : bit_index_for((oop*)p);
     }
     
     template 
     inline BitMap::idx_t stackChunkOopDesc::bit_index_for(OopT* p) const {
    +  assert(is_aligned(p, alignof(OopT)), "should be aligned: " PTR_FORMAT, p2i(p));
       assert(p >= (OopT*)start_address(), "Address not in chunk");
       return p - (OopT*)start_address();
     }
    diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp
    index 71f780577070c..6e75cf6710909 100644
    --- a/src/hotspot/share/opto/callnode.cpp
    +++ b/src/hotspot/share/opto/callnode.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -977,8 +977,8 @@ Node* CallNode::Ideal(PhaseGVN* phase, bool can_reshape) {
       // Validate attached generator
       CallGenerator* cg = generator();
       if (cg != nullptr) {
    -    assert(is_CallStaticJava()  && cg->is_mh_late_inline() ||
    -           is_CallDynamicJava() && cg->is_virtual_late_inline(), "mismatch");
    +    assert((is_CallStaticJava()  && cg->is_mh_late_inline()) ||
    +           (is_CallDynamicJava() && cg->is_virtual_late_inline()), "mismatch");
       }
     #endif // ASSERT
       return SafePointNode::Ideal(phase, can_reshape);
    @@ -1638,8 +1638,8 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseValu
           //   - the narrow_length is 0
           //   - the narrow_length is not wider than length
           assert(narrow_length_type == TypeInt::ZERO ||
    -             length_type->is_con() && narrow_length_type->is_con() &&
    -                (narrow_length_type->_hi <= length_type->_lo) ||
    +             (length_type->is_con() && narrow_length_type->is_con() &&
    +              (narrow_length_type->_hi <= length_type->_lo)) ||
                  (narrow_length_type->_hi <= length_type->_hi &&
                   narrow_length_type->_lo >= length_type->_lo),
                  "narrow type must be narrower than length type");
    @@ -1652,8 +1652,7 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseValu
           // propagate the fact that the array length must be positive.
           InitializeNode* init = initialization();
           if (init != nullptr) {
    -        length = new CastIINode(length, narrow_length_type);
    -        length->set_req(TypeFunc::Control, init->proj_out_or_null(TypeFunc::Control));
    +        length = new CastIINode(init->proj_out_or_null(TypeFunc::Control), length, narrow_length_type);
           }
         }
       }
    diff --git a/src/hotspot/share/opto/castnode.cpp b/src/hotspot/share/opto/castnode.cpp
    index ec34e5bdbe8d7..fd0d96cc79a2c 100644
    --- a/src/hotspot/share/opto/castnode.cpp
    +++ b/src/hotspot/share/opto/castnode.cpp
    @@ -123,54 +123,12 @@ uint ConstraintCastNode::size_of() const {
       return sizeof(*this);
     }
     
    -Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency,
    -                                    const TypeTuple* extra_types) {
    -  switch(opcode) {
    -  case Op_CastII: {
    -    Node* cast = new CastIINode(n, t, dependency, false, extra_types);
    -    cast->set_req(0, c);
    -    return cast;
    -  }
    -  case Op_CastLL: {
    -    Node* cast = new CastLLNode(n, t, dependency, extra_types);
    -    cast->set_req(0, c);
    -    return cast;
    -  }
    -  case Op_CastPP: {
    -    Node* cast = new CastPPNode(n, t, dependency, extra_types);
    -    cast->set_req(0, c);
    -    return cast;
    -  }
    -  case Op_CastFF: {
    -    Node* cast = new CastFFNode(n, t, dependency, extra_types);
    -    cast->set_req(0, c);
    -    return cast;
    -  }
    -  case Op_CastDD: {
    -    Node* cast = new CastDDNode(n, t, dependency, extra_types);
    -    cast->set_req(0, c);
    -    return cast;
    -  }
    -  case Op_CastVV: {
    -    Node* cast = new CastVVNode(n, t, dependency, extra_types);
    -    cast->set_req(0, c);
    -    return cast;
    -  }
    -  case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency, extra_types);
    -  default:
    -    fatal("Bad opcode %d", opcode);
    -  }
    -  return nullptr;
    -}
    -
    -Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt) {
    +Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt) {
       switch(bt) {
    -  case T_INT: {
    -    return make_cast(Op_CastII, c, n, t, dependency, nullptr);
    -  }
    -  case T_LONG: {
    -    return make_cast(Op_CastLL, c, n, t, dependency, nullptr);
    -  }
    +  case T_INT:
    +    return new CastIINode(c, n, t, dependency);
    +  case T_LONG:
    +    return new CastLLNode(c, n, t, dependency);
       default:
         fatal("Bad basic type %s", type2name(bt));
       }
    @@ -267,7 +225,7 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
     }
     
     static Node* find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInteger* type, ConstraintCastNode::DependencyType dependency, BasicType bt) {
    -  Node* n = ConstraintCastNode::make(control, parent, type, dependency, bt);
    +  Node* n = ConstraintCastNode::make_cast_for_basic_type(control, parent, type, dependency, bt);
       Node* existing = igvn->hash_find_insert(n);
       if (existing != nullptr) {
         n->destruct(igvn);
    @@ -487,21 +445,20 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
     
     Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
                                                  const TypeTuple* types) {
    -  Node* cast= nullptr;
       if (type->isa_int()) {
    -    cast = make_cast(Op_CastII, c, in, type, dependency, types);
    +    return new CastIINode(c, in, type, dependency, false, types);
       } else if (type->isa_long()) {
    -    cast = make_cast(Op_CastLL, c, in, type, dependency, types);
    +    return new CastLLNode(c, in, type, dependency, types);
       } else if (type->isa_float()) {
    -    cast = make_cast(Op_CastFF, c, in, type, dependency, types);
    +    return new CastFFNode(c, in, type, dependency, types);
       } else if (type->isa_double()) {
    -    cast = make_cast(Op_CastDD, c, in, type, dependency, types);
    +    return new CastDDNode(c, in, type, dependency, types);
       } else if (type->isa_vect()) {
    -    cast = make_cast(Op_CastVV, c, in, type, dependency, types);
    +    return new CastVVNode(c, in, type, dependency, types);
       } else if (type->isa_ptr()) {
    -    cast = make_cast(Op_CastPP, c, in, type, dependency, types);
    +    return new CastPPNode(c, in, type, dependency, types);
       }
    -  return cast;
    +  fatal("unreachable. Invalid cast type.");
     }
     
     Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
    diff --git a/src/hotspot/share/opto/castnode.hpp b/src/hotspot/share/opto/castnode.hpp
    index 82f54eb0289d5..32db08cb74829 100644
    --- a/src/hotspot/share/opto/castnode.hpp
    +++ b/src/hotspot/share/opto/castnode.hpp
    @@ -54,10 +54,11 @@ class ConstraintCastNode: public TypeNode {
       const TypeTuple* _extra_types;
     
       public:
    -  ConstraintCastNode(Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
    +  ConstraintCastNode(Node* ctrl, Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
                          const TypeTuple* extra_types)
               : TypeNode(t,2), _dependency(dependency), _extra_types(extra_types) {
         init_class_id(Class_ConstraintCast);
    +    init_req(0, ctrl);
         init_req(1, n);
       }
       virtual Node* Identity(PhaseGVN* phase);
    @@ -68,8 +69,7 @@ class ConstraintCastNode: public TypeNode {
       virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
       bool carry_dependency() const { return _dependency != RegularDependency; }
       TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
    -  static Node* make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency, const TypeTuple* extra_types);
    -  static Node* make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt);
    +  static Node* make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt);
     
     #ifndef PRODUCT
       virtual void dump_spec(outputStream *st) const;
    @@ -102,13 +102,12 @@ class CastIINode: public ConstraintCastNode {
     
       public:
       CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
    -    : ConstraintCastNode(n, t, dependency, types), _range_check_dependency(range_check_dependency) {
    +    : ConstraintCastNode(nullptr, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
         init_class_id(Class_CastII);
       }
    -  CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
    -    : ConstraintCastNode(n, t, dependency, nullptr), _range_check_dependency(range_check_dependency) {
    +  CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
    +    : ConstraintCastNode(ctrl, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
         init_class_id(Class_CastII);
    -    init_req(0, ctrl);
       }
       virtual int Opcode() const;
       virtual uint ideal_reg() const { return Op_RegI; }
    @@ -131,13 +130,8 @@ class CastIINode: public ConstraintCastNode {
     
     class CastLLNode: public ConstraintCastNode {
     public:
    -  CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
    -    : ConstraintCastNode(n, t, dependency, nullptr) {
    -    init_class_id(Class_CastLL);
    -    init_req(0, ctrl);
    -  }
    -  CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    -          : ConstraintCastNode(n, t, dependency, types) {
    +  CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    +          : ConstraintCastNode(ctrl, n, t, dependency, types) {
         init_class_id(Class_CastLL);
       }
     
    @@ -149,8 +143,8 @@ class CastLLNode: public ConstraintCastNode {
     
     class CastFFNode: public ConstraintCastNode {
     public:
    -  CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    -          : ConstraintCastNode(n, t, dependency, types) {
    +  CastFFNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    +          : ConstraintCastNode(ctrl, n, t, dependency, types) {
         init_class_id(Class_CastFF);
       }
       virtual int Opcode() const;
    @@ -159,8 +153,8 @@ class CastFFNode: public ConstraintCastNode {
     
     class CastDDNode: public ConstraintCastNode {
     public:
    -  CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    -          : ConstraintCastNode(n, t, dependency, types) {
    +  CastDDNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    +          : ConstraintCastNode(ctrl, n, t, dependency, types) {
         init_class_id(Class_CastDD);
       }
       virtual int Opcode() const;
    @@ -169,8 +163,8 @@ class CastDDNode: public ConstraintCastNode {
     
     class CastVVNode: public ConstraintCastNode {
     public:
    -  CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    -          : ConstraintCastNode(n, t, dependency, types) {
    +  CastVVNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    +          : ConstraintCastNode(ctrl, n, t, dependency, types) {
         init_class_id(Class_CastVV);
       }
       virtual int Opcode() const;
    @@ -182,8 +176,8 @@ class CastVVNode: public ConstraintCastNode {
     // cast pointer to pointer (different type)
     class CastPPNode: public ConstraintCastNode {
       public:
    -  CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    -    : ConstraintCastNode(n, t, dependency, types) {
    +  CastPPNode (Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    +    : ConstraintCastNode(ctrl, n, t, dependency, types) {
       }
       virtual int Opcode() const;
       virtual uint ideal_reg() const { return Op_RegP; }
    @@ -193,10 +187,9 @@ class CastPPNode: public ConstraintCastNode {
     // for _checkcast, cast pointer to pointer (different type), without JOIN,
     class CheckCastPPNode: public ConstraintCastNode {
       public:
    -  CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    -    : ConstraintCastNode(n, t, dependency, types) {
    +  CheckCastPPNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
    +    : ConstraintCastNode(ctrl, n, t, dependency, types) {
         init_class_id(Class_CheckCastPP);
    -    init_req(0, c);
       }
     
       virtual const Type* Value(PhaseGVN* phase) const;
    diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp
    index 7bffd75d3f624..772e4050987f2 100644
    --- a/src/hotspot/share/opto/cfgnode.cpp
    +++ b/src/hotspot/share/opto/cfgnode.cpp
    @@ -2148,8 +2148,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
           if (phi_type->isa_ptr()) {
             const Type* uin_type = phase->type(uin);
             if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
    -          cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency,
    -                                               extra_types);
    +          cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
             } else {
               // Use a CastPP for a cast to not null and a CheckCastPP for
               // a cast to a new klass (and both if both null-ness and
    @@ -2159,8 +2158,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
               // null, uin's type must be casted to not null
               if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
                   uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
    -            cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL,
    -                                                 ConstraintCastNode::StrongDependency, extra_types);
    +            cast = new CastPPNode(r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency, extra_types);
               }
     
               // If the type of phi and uin, both casted to not null,
    @@ -2172,12 +2170,10 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
                   cast = phase->transform(cast);
                   n = cast;
                 }
    -            cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency,
    -                                                 extra_types);
    +            cast = new CheckCastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
               }
               if (cast == nullptr) {
    -            cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency,
    -                                                 extra_types);
    +            cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
               }
             }
           } else {
    diff --git a/src/hotspot/share/opto/chaitin.hpp b/src/hotspot/share/opto/chaitin.hpp
    index dd917571b0627..f01a849612588 100644
    --- a/src/hotspot/share/opto/chaitin.hpp
    +++ b/src/hotspot/share/opto/chaitin.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -163,8 +163,8 @@ class LRG : public ResourceObj {
       bool is_scalable() {
     #ifdef ASSERT
         if (_is_scalable) {
    -      assert(_is_vector && (_num_regs == RegMask::SlotsPerVecA) ||
    -             _is_predicate && (_num_regs == RegMask::SlotsPerRegVectMask), "unexpected scalable reg");
    +      assert((_is_vector && (_num_regs == RegMask::SlotsPerVecA)) ||
    +             (_is_predicate && (_num_regs == RegMask::SlotsPerRegVectMask)), "unexpected scalable reg");
         }
     #endif
         return Matcher::implements_scalable_vector && _is_scalable;
    diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
    index cbfa514239814..522654803aa19 100644
    --- a/src/hotspot/share/opto/compile.cpp
    +++ b/src/hotspot/share/opto/compile.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -3140,8 +3140,8 @@ void Compile::final_graph_reshaping_impl(Node *n, Final_Reshape_Counts& frc, Uni
         int alias_idx = get_alias_index(n->as_Mem()->adr_type());
         assert( n->in(0) != nullptr || alias_idx != Compile::AliasIdxRaw ||
                 // oop will be recorded in oop map if load crosses safepoint
    -            n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() ||
    -                             LoadNode::is_immutable_value(n->in(MemNode::Address))),
    +            (n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() ||
    +                              LoadNode::is_immutable_value(n->in(MemNode::Address)))),
                 "raw memory operations should have control edge");
       }
       if (n->is_MemBar()) {
    @@ -4471,12 +4471,11 @@ Node* Compile::conv_I2X_index(PhaseGVN* phase, Node* idx, const TypeInt* sizetyp
     Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
       if (ctrl != nullptr) {
         // Express control dependency by a CastII node with a narrow type.
    -    value = new CastIINode(value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
         // Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
         // node from floating above the range check during loop optimizations. Otherwise, the
         // ConvI2L node may be eliminated independently of the range check, causing the data path
         // to become TOP while the control path is still there (although it's unreachable).
    -    value->set_req(0, ctrl);
    +    value = new CastIINode(ctrl, value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
         value = phase->transform(value);
       }
       const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen);
    diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp
    index 514155c6af831..db99d6f6a98bb 100644
    --- a/src/hotspot/share/opto/escape.cpp
    +++ b/src/hotspot/share/opto/escape.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
    + * 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
    @@ -1121,7 +1121,7 @@ void ConnectionGraph::add_final_edges(Node *n) {
         return;
       }
       assert(n->is_Store() || n->is_LoadStore() ||
    -         (n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr),
    +         ((n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr)),
              "node should be registered already");
       int opcode = n->Opcode();
       bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_final_edges(this, _igvn, n, opcode);
    @@ -3856,7 +3856,7 @@ void ConnectionGraph::split_unique_types(GrowableArray  &alloc_worklist,
               record_for_optimizer(n);
             } else {
               assert(tn_type == TypePtr::NULL_PTR ||
    -                 tn_t != nullptr && !tinst->maybe_java_subtype_of(tn_t),
    +                 (tn_t != nullptr && !tinst->maybe_java_subtype_of(tn_t)),
                      "unexpected type");
               continue; // Skip dead path with different type
             }
    diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
    index 0e9fefdc8a74c..2389121528105 100644
    --- a/src/hotspot/share/opto/graphKit.cpp
    +++ b/src/hotspot/share/opto/graphKit.cpp
    @@ -1439,8 +1439,7 @@ Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
       // Object is already not-null?
       if( t == t_not_null ) return obj;
     
    -  Node *cast = new CastPPNode(obj,t_not_null);
    -  cast->init_req(0, control());
    +  Node* cast = new CastPPNode(control(), obj,t_not_null);
       cast = _gvn.transform( cast );
     
       // Scan for instances of 'obj' in the current JVM mapping.
    diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp
    index 61e8946ed3994..549290397e3b7 100644
    --- a/src/hotspot/share/opto/lcm.cpp
    +++ b/src/hotspot/share/opto/lcm.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1998, 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
    @@ -150,8 +150,9 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
       bool is_decoden = ((intptr_t)val) & 1;
       val = (Node*)(((intptr_t)val) & ~1);
     
    -  assert(!is_decoden || (val->in(0) == nullptr) && val->is_Mach() &&
    -         (val->as_Mach()->ideal_Opcode() == Op_DecodeN), "sanity");
    +  assert(!is_decoden ||
    +         ((val->in(0) == nullptr) && val->is_Mach() &&
    +          (val->as_Mach()->ideal_Opcode() == Op_DecodeN)), "sanity");
     
       // Search the successor block for a load or store who's base value is also
       // the tested value.  There may be several.
    diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
    index e8923d3d13495..2bc1cc261c6c6 100644
    --- a/src/hotspot/share/opto/library_call.cpp
    +++ b/src/hotspot/share/opto/library_call.cpp
    @@ -873,8 +873,7 @@ inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* re
       Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
       if (is_neg != nullptr && pos_index != nullptr) {
         // Emulate effect of Parse::adjust_map_after_if.
    -    Node* ccast = new CastIINode(index, TypeInt::POS);
    -    ccast->set_req(0, control());
    +    Node* ccast = new CastIINode(control(), index, TypeInt::POS);
         (*pos_index) = _gvn.transform(ccast);
       }
       return is_neg;
    @@ -1141,7 +1140,9 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
     
       // length is now known positive, add a cast node to make this explicit
       jlong upper_bound = _gvn.type(length)->is_integer(bt)->hi_as_long();
    -  Node* casted_length = ConstraintCastNode::make(control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt), ConstraintCastNode::RegularDependency, bt);
    +  Node* casted_length = ConstraintCastNode::make_cast_for_basic_type(
    +      control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
    +      ConstraintCastNode::RegularDependency, bt);
       casted_length = _gvn.transform(casted_length);
       replace_in_map(length, casted_length);
       length = casted_length;
    @@ -1169,7 +1170,9 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
       }
     
       // index is now known to be >= 0 and < length, cast it
    -  Node* result = ConstraintCastNode::make(control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt), ConstraintCastNode::RegularDependency, bt);
    +  Node* result = ConstraintCastNode::make_cast_for_basic_type(
    +      control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
    +      ConstraintCastNode::RegularDependency, bt);
       result = _gvn.transform(result);
       set_result(result);
       replace_in_map(index, result);
    @@ -4312,8 +4315,7 @@ bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
           // Improve the klass node's type from the new optimistic assumption:
           ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
           const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
    -      Node* cast = new CastPPNode(klass_node, akls);
    -      cast->init_req(0, control());
    +      Node* cast = new CastPPNode(control(), klass_node, akls);
           klass_node = _gvn.transform(cast);
         }
     
    @@ -5940,8 +5942,7 @@ bool LibraryCallKit::inline_multiplyToLen() {
          } __ else_(); {
            // Update graphKit memory and control from IdealKit.
            sync_kit(ideal);
    -       Node *cast = new CastPPNode(z, TypePtr::NOTNULL);
    -       cast->init_req(0, control());
    +       Node* cast = new CastPPNode(control(), z, TypePtr::NOTNULL);
            _gvn.set_type(cast, cast->bottom_type());
            C->record_for_igvn(cast);
     
    diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp
    index e4f6345c6794f..6a8efb0872a5b 100644
    --- a/src/hotspot/share/opto/loopPredicate.cpp
    +++ b/src/hotspot/share/opto/loopPredicate.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2011, 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
    @@ -797,7 +797,8 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree* loop, Node* ctrl, int scal
       overflow = false;
       Node* max_idx_expr = nullptr;
       const TypeInt* idx_type = TypeInt::INT;
    -  if ((stride > 0) == (scale > 0) == upper) {
    +  // same signs and upper, or different signs and not upper.
    +  if (((stride > 0) == (scale > 0)) == upper) {
         guarantee(limit != nullptr, "sanity");
         if (TraceLoopPredicate) {
           if (limit->is_Con()) {
    diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp
    index 3c323d7a2dc4c..3d3e7bdaa7c7b 100644
    --- a/src/hotspot/share/opto/loopTransform.cpp
    +++ b/src/hotspot/share/opto/loopTransform.cpp
    @@ -1284,8 +1284,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
     }
     
     Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
    -  Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
    -  castii->set_req(0, ctrl);
    +  Node* castii = new CastIINode(ctrl, incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
       register_new_node(castii, ctrl);
       for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
         Node* n = incr->fast_out(i);
    @@ -3161,9 +3160,8 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
       // The new loop limit is <= (for an upward loop) >= (for a downward loop) than the orig limit.
       // The expression that computes the new limit may be too complicated and the computed type of the new limit
       // may be too pessimistic. A CastII here guarantees it's not lost.
    -  main_limit = new CastIINode(main_limit, TypeInt::make(upward ? min_jint : orig_limit_t->_lo,
    +  main_limit = new CastIINode(pre_ctrl, main_limit, TypeInt::make(upward ? min_jint : orig_limit_t->_lo,
                                                             upward ? orig_limit_t->_hi : max_jint, Type::WidenMax));
    -  main_limit->init_req(0, pre_ctrl);
       register_new_node(main_limit, pre_ctrl);
       // Hack the now-private loop bounds
       _igvn.replace_input_of(main_cmp, 2, main_limit);
    @@ -3422,7 +3420,10 @@ bool IdealLoopTree::do_remove_empty_loop(PhaseIdealLoop *phase) {
       Node* exact_limit = phase->exact_limit(this);
     
       // We need to pin the exact limit to prevent it from floating above the zero trip guard.
    -  Node* cast_ii = ConstraintCastNode::make(cl->in(LoopNode::EntryControl), exact_limit, phase->_igvn.type(exact_limit), ConstraintCastNode::UnconditionalDependency, T_INT);
    +  Node* cast_ii = ConstraintCastNode::make_cast_for_basic_type(
    +      cl->in(LoopNode::EntryControl), exact_limit,
    +      phase->_igvn.type(exact_limit),
    +      ConstraintCastNode::UnconditionalDependency, T_INT);
       phase->register_new_node(cast_ii, cl->in(LoopNode::EntryControl));
     
       Node* final_iv = new SubINode(cast_ii, cl->stride());
    diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp
    index c402a240acbed..4f2110bfb4cd0 100644
    --- a/src/hotspot/share/opto/memnode.cpp
    +++ b/src/hotspot/share/opto/memnode.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -4955,7 +4955,7 @@ static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) {
     //-----------------------------memory_at---------------------------------------
     Node* MergeMemNode::memory_at(uint alias_idx) const {
       assert(alias_idx >= Compile::AliasIdxRaw ||
    -         alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing(),
    +         (alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing()),
              "must avoid base_memory and AliasIdxTop");
     
       // Otherwise, it is a narrow slice.
    diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp
    index 85f4380188db9..3a521c8f63365 100644
    --- a/src/hotspot/share/opto/memnode.hpp
    +++ b/src/hotspot/share/opto/memnode.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -788,7 +788,7 @@ class StoreCMNode : public StoreNode {
         StoreNode(c, mem, adr, at, val, oop_store, MemNode::release),
         _oop_alias_idx(oop_alias_idx) {
         assert(_oop_alias_idx >= Compile::AliasIdxRaw ||
    -           _oop_alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing(),
    +           (_oop_alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing()),
                "bad oop alias idx");
       }
       virtual int Opcode() const;
    diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
    index 0541409a31269..7e9c5196942fb 100644
    --- a/src/hotspot/share/opto/node.hpp
    +++ b/src/hotspot/share/opto/node.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -448,7 +448,7 @@ class Node {
       }
       // Light version of set_req() to init inputs after node creation.
       void init_req( uint i, Node *n ) {
    -    assert( i == 0 && this == n ||
    +    assert( (i == 0 && this == n) ||
                 is_not_dead(n), "can not use dead node");
         assert( i < _cnt, "oob");
         assert( !VerifyHashTableKeys || _hash_lock == 0,
    diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp
    index 1528615987bb7..0c22409aeee08 100644
    --- a/src/hotspot/share/opto/parse2.cpp
    +++ b/src/hotspot/share/opto/parse2.cpp
    @@ -1730,10 +1730,10 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
           const Type* tboth = tcon->join_speculative(tval);
           if (tboth == tval)  break;        // Nothing to gain.
           if (tcon->isa_int()) {
    -        ccast = new CastIINode(val, tboth);
    +        ccast = new CastIINode(control(), val, tboth);
           } else if (tcon == TypePtr::NULL_PTR) {
             // Cast to null, but keep the pointer identity temporarily live.
    -        ccast = new CastPPNode(val, tboth);
    +        ccast = new CastPPNode(control(), val, tboth);
           } else {
             const TypeF* tf = tcon->isa_float_constant();
             const TypeD* td = tcon->isa_double_constant();
    @@ -1764,7 +1764,6 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
         assert(tcc != tval && tcc->higher_equal(tval), "must improve");
         // Delay transform() call to allow recovery of pre-cast value
         // at the control merge.
    -    ccast->set_req(0, control());
         _gvn.set_type_bottom(ccast);
         record_for_igvn(ccast);
         cast = ccast;
    diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp
    index 46d76258eb4f3..c791146f75769 100644
    --- a/src/hotspot/share/opto/phaseX.cpp
    +++ b/src/hotspot/share/opto/phaseX.cpp
    @@ -685,7 +685,7 @@ Node* PhaseGVN::transform(Node* n) {
         k = i;
     #ifdef ASSERT
         if (loop_count >= K + C->live_nodes()) {
    -      dump_infinite_loop_info(i, "PhaseGVN::transform_no_reclaim");
    +      dump_infinite_loop_info(i, "PhaseGVN::transform");
         }
     #endif
         i = apply_ideal(k, /*can_reshape=*/false);
    diff --git a/src/hotspot/share/opto/vector.cpp b/src/hotspot/share/opto/vector.cpp
    index 1c2c9d982b5b7..641e7ebcde8f6 100644
    --- a/src/hotspot/share/opto/vector.cpp
    +++ b/src/hotspot/share/opto/vector.cpp
    @@ -488,7 +488,7 @@ void PhaseVector::expand_vunbox_node(VectorUnboxNode* vec_unbox) {
         // For proper aliasing, attach concrete payload type.
         ciKlass* payload_klass = ciTypeArrayKlass::make(bt);
         const Type* payload_type = TypeAryPtr::make_from_klass(payload_klass)->cast_to_ptr_type(TypePtr::NotNull);
    -    vec_field_ld = gvn.transform(new CastPPNode(vec_field_ld, payload_type));
    +    vec_field_ld = gvn.transform(new CastPPNode(nullptr, vec_field_ld, payload_type));
     
         Node* adr = kit.array_element_address(vec_field_ld, gvn.intcon(0), bt);
         const TypePtr* adr_type = adr->bottom_type()->is_ptr();
    diff --git a/src/hotspot/share/prims/foreignGlobals.cpp b/src/hotspot/share/prims/foreignGlobals.cpp
    index f3653d29886f9..11b0b8ace7cb7 100644
    --- a/src/hotspot/share/prims/foreignGlobals.cpp
    +++ b/src/hotspot/share/prims/foreignGlobals.cpp
    @@ -140,7 +140,7 @@ int ForeignGlobals::compute_out_arg_bytes(const GrowableArray& out_re
     
     int ForeignGlobals::java_calling_convention(const BasicType* signature, int num_args, GrowableArray& out_regs) {
       VMRegPair* vm_regs = NEW_RESOURCE_ARRAY(VMRegPair, num_args);
    -  int slots = SharedRuntime::java_calling_convention(signature, vm_regs, num_args);
    +  int slots = align_up(SharedRuntime::java_calling_convention(signature, vm_regs, num_args), 2);
       for (int i = 0; i < num_args; i++) {
         VMRegPair pair = vm_regs[i];
         // note, we ignore second here. Signature should consist of register-size values. So there should be
    diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
    index bd6eda2d4681a..9a8a9a5bec0b0 100644
    --- a/src/hotspot/share/prims/jvm.cpp
    +++ b/src/hotspot/share/prims/jvm.cpp
    @@ -3933,8 +3933,6 @@ JVM_ENTRY(void, JVM_VirtualThreadStart(JNIEnv* env, jobject vthread))
         // set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
         JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, false);
       }
    -#else
    -  fatal("Should only be called with JVMTI enabled");
     #endif
     JVM_END
     
    @@ -3950,8 +3948,6 @@ JVM_ENTRY(void, JVM_VirtualThreadEnd(JNIEnv* env, jobject vthread))
         // set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
         JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, true);
       }
    -#else
    -  fatal("Should only be called with JVMTI enabled");
     #endif
     JVM_END
     
    @@ -3969,8 +3965,6 @@ JVM_ENTRY(void, JVM_VirtualThreadMount(JNIEnv* env, jobject vthread, jboolean hi
         // set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
         JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, hide);
       }
    -#else
    -  fatal("Should only be called with JVMTI enabled");
     #endif
     JVM_END
     
    @@ -3988,8 +3982,6 @@ JVM_ENTRY(void, JVM_VirtualThreadUnmount(JNIEnv* env, jobject vthread, jboolean
         // set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
         JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, hide);
       }
    -#else
    -  fatal("Should only be called with JVMTI enabled");
     #endif
     JVM_END
     
    @@ -4003,8 +3995,6 @@ JVM_ENTRY(void, JVM_VirtualThreadHideFrames(JNIEnv* env, jobject vthread, jboole
       assert(!thread->is_in_VTMS_transition(), "sanity check");
       assert(thread->is_in_tmp_VTMS_transition() != (bool)hide, "sanity check");
       thread->toggle_is_in_tmp_VTMS_transition();
    -#else
    -  fatal("Should only be called with JVMTI enabled");
     #endif
     JVM_END
     
    @@ -4019,8 +4009,6 @@ JVM_ENTRY(void, JVM_VirtualThreadDisableSuspend(JNIEnv* env, jobject vthread, jb
       assert(thread->is_disable_suspend() != (bool)enter,
              "nested or unbalanced monitor enter/exit is not allowed");
       thread->toggle_is_disable_suspend();
    -#else
    -  fatal("Should only be called with JVMTI enabled");
     #endif
     JVM_END
     
    diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
    index df466acdcfa31..7dae2cce16ea2 100644
    --- a/src/hotspot/share/runtime/arguments.cpp
    +++ b/src/hotspot/share/runtime/arguments.cpp
    @@ -525,6 +525,7 @@ static SpecialFlag const special_jvm_flags[] = {
       { "RefDiscoveryPolicy",           JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
       { "MetaspaceReclaimPolicy",       JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
     
    +  { "AdaptiveSizePolicyCollectionCostMargin",   JDK_Version::undefined(), JDK_Version::jdk(23), JDK_Version::jdk(24) },
     #ifdef ASSERT
       { "DummyObsoleteTestFlag",        JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() },
     #endif
    @@ -2214,10 +2215,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
         // -bootclasspath/a:
         } else if (match_option(option, "-Xbootclasspath/a:", &tail)) {
           Arguments::append_sysclasspath(tail);
    -#if INCLUDE_CDS
    -      MetaspaceShared::disable_optimized_module_handling();
    -      log_info(cds)("optimized module handling: disabled because bootclasspath was appended");
    -#endif
         // -bootclasspath/p:
         } else if (match_option(option, "-Xbootclasspath/p:", &tail)) {
             jio_fprintf(defaultStream::output_stream(),
    diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
    index fe1dfc62ee48d..969e14f150e17 100644
    --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp
    +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
    @@ -1775,7 +1775,7 @@ class ThawBase : public StackObj {
       inline void before_thaw_java_frame(const frame& hf, const frame& caller, bool bottom, int num_frame);
       inline void after_thaw_java_frame(const frame& f, bool bottom);
       inline void patch(frame& f, const frame& caller, bool bottom);
    -  void clear_bitmap_bits(intptr_t* start, int range);
    +  void clear_bitmap_bits(address start, address end);
     
       NOINLINE void recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames);
       void recurse_thaw_compiled_frame(const frame& hf, frame& caller, int num_frames, bool stub_caller);
    @@ -2166,13 +2166,22 @@ inline void ThawBase::patch(frame& f, const frame& caller, bool bottom) {
       assert(!bottom || (_cont.is_empty() != Continuation::is_cont_barrier_frame(f)), "");
     }
     
    -void ThawBase::clear_bitmap_bits(intptr_t* start, int range) {
    +void ThawBase::clear_bitmap_bits(address start, address end) {
    +  assert(is_aligned(start, wordSize), "should be aligned: " PTR_FORMAT, p2i(start));
    +  assert(is_aligned(end, VMRegImpl::stack_slot_size), "should be aligned: " PTR_FORMAT, p2i(end));
    +
       // we need to clear the bits that correspond to arguments as they reside in the caller frame
    -  // or they will keep objects that are otherwise unreachable alive
    -  log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(start+range));
    +  // or they will keep objects that are otherwise unreachable alive.
    +
    +  // Align `end` if UseCompressedOops is not set to avoid UB when calculating the bit index, since
    +  // `end` could be at an odd number of stack slots from `start`, i.e might not be oop aligned.
    +  // If that's the case the bit range corresponding to the last stack slot should not have bits set
    +  // anyways and we assert that before returning.
    +  address effective_end = UseCompressedOops ? end : align_down(end, wordSize);
    +  log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(effective_end));
       stackChunkOop chunk = _cont.tail();
    -  chunk->bitmap().clear_range(chunk->bit_index_for(start),
    -                              chunk->bit_index_for(start+range));
    +  chunk->bitmap().clear_range(chunk->bit_index_for(start), chunk->bit_index_for(effective_end));
    +  assert(chunk->bitmap().count_one_bits(chunk->bit_index_for(effective_end), chunk->bit_index_for(end)) == 0, "bits should not be set");
     }
     
     NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames) {
    @@ -2225,7 +2234,9 @@ NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& c
         _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
       } else if (_cont.tail()->has_bitmap() && locals > 0) {
         assert(hf.is_heap_frame(), "should be");
    -    clear_bitmap_bits(heap_frame_bottom - locals, locals);
    +    address start = (address)(heap_frame_bottom - locals);
    +    address end = (address)heap_frame_bottom;
    +    clear_bitmap_bits(start, end);
       }
     
       DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
    @@ -2298,7 +2309,10 @@ void ThawBase::recurse_thaw_compiled_frame(const frame& hf, frame& caller, int n
         // can only fix caller once this frame is thawed (due to callee saved regs); this happens on the stack
         _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
       } else if (_cont.tail()->has_bitmap() && added_argsize > 0) {
    -    clear_bitmap_bits(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top, added_argsize);
    +    address start = (address)(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top);
    +    int stack_args_slots = f.cb()->as_compiled_method()->method()->num_stack_arg_slots(false /* rounded */);
    +    int argsize_in_bytes = stack_args_slots * VMRegImpl::stack_slot_size;
    +    clear_bitmap_bits(start, start + argsize_in_bytes);
       }
     
       DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
    diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp
    index f4893bae5db95..c68180e105b7a 100644
    --- a/src/hotspot/share/runtime/frame.cpp
    +++ b/src/hotspot/share/runtime/frame.cpp
    @@ -1439,7 +1439,7 @@ void frame::describe(FrameValues& values, int frame_no, const RegisterMap* reg_m
             assert(sig_index == sizeargs, "");
           }
           int stack_arg_slots = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
    -      assert(stack_arg_slots ==  m->num_stack_arg_slots(), "");
    +      assert(stack_arg_slots ==  m->num_stack_arg_slots(false /* rounded */), "");
           int out_preserve = SharedRuntime::out_preserve_stack_slots();
           int sig_index = 0;
           int arg_index = (m->is_static() ? 0 : -1);
    diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
    index b5ede76434a0b..af1c82b77146b 100644
    --- a/src/hotspot/share/runtime/globals.hpp
    +++ b/src/hotspot/share/runtime/globals.hpp
    @@ -546,10 +546,17 @@ const int ObjectAlignmentInBytes = 8;
               "thrown from JVM")                                                \
                                                                                 \
       product(bool, HeapDumpBeforeFullGC, false, MANAGEABLE,                    \
    -          "Dump heap to file before any major stop-the-world GC")           \
    +          "Dump heap to file before any major stop-the-world GC "           \
    +          "(also see FullGCHeapDumpLimit)")                                 \
                                                                                 \
       product(bool, HeapDumpAfterFullGC, false, MANAGEABLE,                     \
    -          "Dump heap to file after any major stop-the-world GC")            \
    +          "Dump heap to file after any major stop-the-world GC "            \
    +          "(also see FullGCHeapDumpLimit)")                                 \
    +                                                                            \
    +  product(uint, FullGCHeapDumpLimit, 0, MANAGEABLE,                         \
    +          "Limit the number of heap dumps triggered by "                    \
    +          "HeapDumpBeforeFullGC or HeapDumpAfterFullGC "                    \
    +          "(0 means no limit)")                                             \
                                                                                 \
       product(bool, HeapDumpOnOutOfMemoryError, false, MANAGEABLE,              \
               "Dump heap to file when java.lang.OutOfMemoryError is thrown "    \
    diff --git a/src/hotspot/share/runtime/mutex.hpp b/src/hotspot/share/runtime/mutex.hpp
    index 3f38bcd5ed551..10671d651b100 100644
    --- a/src/hotspot/share/runtime/mutex.hpp
    +++ b/src/hotspot/share/runtime/mutex.hpp
    @@ -221,7 +221,7 @@ class Monitor : public Mutex {
     
     class PaddedMutex : public Mutex {
       enum {
    -    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex),
    +    CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Mutex),
         PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
       };
       char _padding[PADDING_LEN];
    @@ -232,7 +232,7 @@ class PaddedMutex : public Mutex {
     
     class PaddedMonitor : public Monitor {
       enum {
    -    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor),
    +    CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Monitor),
         PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
       };
       char _padding[PADDING_LEN];
    diff --git a/src/hotspot/share/runtime/objectMonitor.hpp b/src/hotspot/share/runtime/objectMonitor.hpp
    index fc15e20309f77..ab48bd19b5e43 100644
    --- a/src/hotspot/share/runtime/objectMonitor.hpp
    +++ b/src/hotspot/share/runtime/objectMonitor.hpp
    @@ -121,11 +121,7 @@ class ObjectWaiter : public StackObj {
     //     intptr_t. There's no reason to use a 64-bit type for this field
     //     in a 64-bit JVM.
     
    -#ifndef OM_CACHE_LINE_SIZE
    -// Use DEFAULT_CACHE_LINE_SIZE if not already specified for
    -// the current build platform.
     #define OM_CACHE_LINE_SIZE DEFAULT_CACHE_LINE_SIZE
    -#endif
     
     class ObjectMonitor : public CHeapObj {
       friend class ObjectSynchronizer;
    diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
    index 094fd2509a05b..8ecabde8ca144 100644
    --- a/src/hotspot/share/runtime/os.hpp
    +++ b/src/hotspot/share/runtime/os.hpp
    @@ -531,7 +531,6 @@ class os: AllStatic {
       static void   large_page_init();
       static size_t large_page_size();
       static bool   can_commit_large_page_memory();
    -  static bool   can_execute_large_page_memory();
     
       // Check if pointer points to readable memory (by 4-byte read access)
       static bool    is_readable_pointer(const void* p);
    diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp
    index 9d582b790a15a..94d42622c81e6 100644
    --- a/src/hotspot/share/runtime/sharedRuntime.cpp
    +++ b/src/hotspot/share/runtime/sharedRuntime.cpp
    @@ -2004,7 +2004,7 @@ void SharedRuntime::check_member_name_argument_is_last_argument(const methodHand
       assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob");
       assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object");
     
    -  int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1);
    +  java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1);
     
       for (int i = 0; i < member_arg_pos; i++) {
         VMReg a =    regs_with_member_name[i].first();
    @@ -3102,7 +3102,7 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
           BasicType ret_type = si.return_type();
     
           // Now get the compiled-Java arguments layout.
    -      int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed);
    +      SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed);
     
           // Generate the compiled-to-native wrapper code
           nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type);
    diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp
    index b085bf5fd0514..081bdd2e0d399 100644
    --- a/src/hotspot/share/runtime/signature.cpp
    +++ b/src/hotspot/share/runtime/signature.cpp
    @@ -178,7 +178,6 @@ void Fingerprinter::compute_fingerprint_and_return_type(bool static_flag) {
       }
     
     #if defined(_LP64) && !defined(ZERO)
    -  _stack_arg_slots = align_up(_stack_arg_slots, 2);
     #ifdef ASSERT
       int dbg_stack_arg_slots = compute_num_stack_arg_slots(_signature, _param_size, static_flag);
       assert(_stack_arg_slots == dbg_stack_arg_slots, "fingerprinter: %d full: %d", _stack_arg_slots, dbg_stack_arg_slots);
    @@ -235,14 +234,17 @@ void Fingerprinter::do_type_calling_convention(BasicType type) {
       case T_BYTE:
       case T_SHORT:
       case T_INT:
    -#if defined(PPC64) || defined(S390)
         if (_int_args < Argument::n_int_register_parameters_j) {
           _int_args++;
         } else {
    +#if defined(PPC64) || defined(S390)
    +      _stack_arg_slots += 1;
    +#else
    +      _stack_arg_slots = align_up(_stack_arg_slots, 2);
           _stack_arg_slots += 1;
    +#endif // defined(PPC64) || defined(S390)
         }
         break;
    -#endif // defined(PPC64) || defined(S390)
       case T_LONG:
       case T_OBJECT:
       case T_ARRAY:
    @@ -250,26 +252,27 @@ void Fingerprinter::do_type_calling_convention(BasicType type) {
         if (_int_args < Argument::n_int_register_parameters_j) {
           _int_args++;
         } else {
    -      PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
    -      S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
    +      _stack_arg_slots = align_up(_stack_arg_slots, 2);
           _stack_arg_slots += 2;
         }
         break;
       case T_FLOAT:
    -#if defined(PPC64) || defined(S390)
         if (_fp_args < Argument::n_float_register_parameters_j) {
           _fp_args++;
         } else {
    +#if defined(PPC64) || defined(S390)
    +      _stack_arg_slots += 1;
    +#else
    +      _stack_arg_slots = align_up(_stack_arg_slots, 2);
           _stack_arg_slots += 1;
    +#endif // defined(PPC64) || defined(S390)
         }
         break;
    -#endif // defined(PPC64) || defined(S390)
       case T_DOUBLE:
         if (_fp_args < Argument::n_float_register_parameters_j) {
           _fp_args++;
         } else {
    -      PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
    -      S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
    +      _stack_arg_slots = align_up(_stack_arg_slots, 2);
           _stack_arg_slots += 2;
         }
         break;
    diff --git a/src/hotspot/share/runtime/trimNativeHeap.cpp b/src/hotspot/share/runtime/trimNativeHeap.cpp
    index 3592d39093861..ca9f74a04ed2a 100644
    --- a/src/hotspot/share/runtime/trimNativeHeap.cpp
    +++ b/src/hotspot/share/runtime/trimNativeHeap.cpp
    @@ -71,11 +71,6 @@ class NativeHeapTrimmerThread : public NamedThread {
         return --_suspend_count;
       }
     
    -  bool is_stopped() const {
    -    assert(_lock->is_locked(), "Must be");
    -    return _stop;
    -  }
    -
       bool at_or_nearing_safepoint() const {
         return SafepointSynchronize::is_at_safepoint() ||
                SafepointSynchronize::is_synchronizing();
    @@ -215,13 +210,12 @@ class NativeHeapTrimmerThread : public NamedThread {
       }
     
       void print_state(outputStream* st) const {
    -    // Don't pull lock during error reporting
    -    Mutex* const lock = VMError::is_error_reported() ? nullptr : _lock;
         int64_t num_trims = 0;
         bool stopped = false;
         uint16_t suspenders = 0;
         {
    -      MutexLocker ml(lock, Mutex::_no_safepoint_check_flag);
    +      // Don't pull lock during error reporting
    +      ConditionalMutexLocker ml(_lock, !VMError::is_error_reported(), Mutex::_no_safepoint_check_flag);
           num_trims = _num_trims_performed;
           stopped = _stop;
           suspenders = _suspend_count;
    diff --git a/src/hotspot/share/utilities/copy.cpp b/src/hotspot/share/utilities/copy.cpp
    index 9ead75f2ceb90..ed7797969438b 100644
    --- a/src/hotspot/share/utilities/copy.cpp
    +++ b/src/hotspot/share/utilities/copy.cpp
    @@ -243,6 +243,16 @@ void Copy::fill_to_memory_atomic(void* to, size_t size, jubyte value) {
         }
       } else {
         // Not aligned, so no need to be atomic.
    +#ifdef MUSL_LIBC
    +    // This code is used by Unsafe and may hit the next page after truncation of mapped memory.
    +    // Therefore, we use volatile to prevent compilers from replacing the loop by memset which
    +    // may not trigger SIGBUS as needed (observed on Alpine Linux x86_64)
    +    jbyte fill = value;
    +    for (uintptr_t off = 0; off < size; off += sizeof(jbyte)) {
    +      *(volatile jbyte*)(dst + off) = fill;
    +    }
    +#else
         Copy::fill_to_bytes(dst, size, value);
    +#endif
       }
     }
    diff --git a/src/hotspot/share/utilities/globalCounter.hpp b/src/hotspot/share/utilities/globalCounter.hpp
    index 7e971f33ae3e5..b336ed4a1dac5 100644
    --- a/src/hotspot/share/utilities/globalCounter.hpp
    +++ b/src/hotspot/share/utilities/globalCounter.hpp
    @@ -46,9 +46,9 @@ class GlobalCounter : public AllStatic {
       // Since do not know what we will end up next to in BSS, we make sure the
       // counter is on a separate cacheline.
       struct PaddedCounter {
    -    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
         volatile uintx _counter;
    -    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uintx));
    +    DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile uintx));
       };
     
       // The global counter
    diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp
    index a6bf8a3e7d3ca..08eb25828703f 100644
    --- a/src/hotspot/share/utilities/globalDefinitions.hpp
    +++ b/src/hotspot/share/utilities/globalDefinitions.hpp
    @@ -602,11 +602,16 @@ const bool support_IRIW_for_not_multiple_copy_atomic_cpu = false;
     const bool support_IRIW_for_not_multiple_copy_atomic_cpu = PPC64_ONLY(true) NOT_PPC64(false);
     #endif
     
    -// The expected size in bytes of a cache line, used to pad data structures.
    +// The expected size in bytes of a cache line.
     #ifndef DEFAULT_CACHE_LINE_SIZE
     #error "Platform should define DEFAULT_CACHE_LINE_SIZE"
     #endif
     
    +// The default padding size for data structures to avoid false sharing.
    +#ifndef DEFAULT_PADDING_SIZE
    +#error "Platform should define DEFAULT_PADDING_SIZE"
    +#endif
    +
     
     //----------------------------------------------------------------------------------------------------
     // Utility macros for compilers
    diff --git a/src/hotspot/share/utilities/nonblockingQueue.hpp b/src/hotspot/share/utilities/nonblockingQueue.hpp
    index 0c62f07719012..814132809fa8f 100644
    --- a/src/hotspot/share/utilities/nonblockingQueue.hpp
    +++ b/src/hotspot/share/utilities/nonblockingQueue.hpp
    @@ -62,7 +62,7 @@ template
     class NonblockingQueue {
       T* volatile _head;
       // Padding of one cache line to avoid false sharing.
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(T*));
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(T*));
       T* volatile _tail;
     
       NONCOPYABLE(NonblockingQueue);
    diff --git a/src/hotspot/share/utilities/utf8.cpp b/src/hotspot/share/utilities/utf8.cpp
    index 66e48d5606511..d7798778b2cea 100644
    --- a/src/hotspot/share/utilities/utf8.cpp
    +++ b/src/hotspot/share/utilities/utf8.cpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -341,10 +341,10 @@ bool UTF8::is_legal_utf8(const unsigned char* buffer, int length,
         // For an unsigned char v,
         // (v | v - 1) is < 128 (highest bit 0) for 0 < v < 128;
         // (v | v - 1) is >= 128 (highest bit 1) for v == 0 or v >= 128.
    -    unsigned char res = b0 | b0 - 1 |
    -                        b1 | b1 - 1 |
    -                        b2 | b2 - 1 |
    -                        b3 | b3 - 1;
    +    unsigned char res = b0 | (b0 - 1) |
    +                        b1 | (b1 - 1) |
    +                        b2 | (b2 - 1) |
    +                        b3 | (b3 - 1);
         if (res >= 128) break;
         i += 4;
       }
    diff --git a/src/hotspot/share/utilities/waitBarrier_generic.hpp b/src/hotspot/share/utilities/waitBarrier_generic.hpp
    index d3a45b33b82ef..e980b3022ef8e 100644
    --- a/src/hotspot/share/utilities/waitBarrier_generic.hpp
    +++ b/src/hotspot/share/utilities/waitBarrier_generic.hpp
    @@ -38,7 +38,7 @@ class GenericWaitBarrier : public CHeapObj {
         // This would insulate from stalls when adjacent cells have returning
         // workers and contend over the cache line for current latency-critical
         // cell.
    -    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +    DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
     
         Semaphore _sem;
     
    @@ -81,14 +81,14 @@ class GenericWaitBarrier : public CHeapObj {
       Cell _cells[CELLS_COUNT];
     
       // Trailing padding to protect the last cell.
    -  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
     
       volatile int _barrier_tag;
     
       // Trailing padding to insulate the rest of the barrier from adjacent
       // data structures. The leading padding is not needed, as cell padding
       // handles this for us.
    -  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
    +  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
     
       NONCOPYABLE(GenericWaitBarrier);
     
    diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java b/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java
    index 17f82b2eacc34..ff7e1f4ddd57d 100644
    --- a/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java
    +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -85,7 +85,7 @@ final class DESKey implements SecretKey {
             // Use the cleaner to zero the key when no longer referenced
             final byte[] k = this.key;
             CleanerFactory.cleaner().register(this,
    -                () -> java.util.Arrays.fill(k, (byte)0x00));
    +                () -> Arrays.fill(k, (byte)0x00));
         }
     
         public byte[] getEncoded() {
    @@ -136,7 +136,7 @@ public boolean equals(Object obj) {
     
                 byte[] thatKey = that.getEncoded();
                 boolean ret = MessageDigest.isEqual(this.key, thatKey);
    -            java.util.Arrays.fill(thatKey, (byte)0x00);
    +            Arrays.fill(thatKey, (byte)0x00);
                 return ret;
             } finally {
                 // prevent this from being cleaned for the above block
    @@ -168,7 +168,7 @@ private void readObject(java.io.ObjectInputStream s)
             // Use the cleaner to zero the key when no longer referenced
             final byte[] k = this.key;
             CleanerFactory.cleaner().register(this,
    -                () -> java.util.Arrays.fill(k, (byte)0x00));
    +                () -> Arrays.fill(k, (byte)0x00));
         }
     
         /**
    diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java
    index f5c3d8384df73..53f72499a33d3 100644
    --- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java
    +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 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
    @@ -87,7 +87,7 @@ final class DESedeKey implements SecretKey {
             // Use the cleaner to zero the key when no longer referenced
             final byte[] k = this.key;
             CleanerFactory.cleaner().register(this,
    -                () -> java.util.Arrays.fill(k, (byte)0x00));
    +                () -> Arrays.fill(k, (byte)0x00));
         }
     
         public byte[] getEncoded() {
    @@ -137,7 +137,7 @@ public boolean equals(Object obj) {
     
                 byte[] thatKey = that.getEncoded();
                 boolean ret = MessageDigest.isEqual(this.key, thatKey);
    -            java.util.Arrays.fill(thatKey, (byte)0x00);
    +            Arrays.fill(thatKey, (byte)0x00);
                 return ret;
             } finally {
                 // prevent this from being cleaned for the above block
    @@ -162,7 +162,7 @@ private void readObject(java.io.ObjectInputStream s)
             }
             byte[] temp = key;
             this.key = temp.clone();
    -        java.util.Arrays.fill(temp, (byte)0x00);
    +        Arrays.fill(temp, (byte)0x00);
     
             DESKeyGenerator.setParityBit(key, 0);
             DESKeyGenerator.setParityBit(key, 8);
    @@ -171,7 +171,7 @@ private void readObject(java.io.ObjectInputStream s)
             // Use the cleaner to zero the key when no longer referenced
             final byte[] k = this.key;
             CleanerFactory.cleaner().register(this,
    -                () -> java.util.Arrays.fill(k, (byte)0x00));
    +                () -> Arrays.fill(k, (byte)0x00));
         }
     
         /**
    diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java
    index 902d302cac4b7..a86f313e2c9e1 100644
    --- a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java
    +++ b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java
    @@ -74,7 +74,6 @@ public void padWithLen(byte[] in, int off, int len)
             SunJCE.getRandom().nextBytes(padding);
             System.arraycopy(padding, 0, in, off, len - 1);
             in[idx - 1] = paddingOctet;
    -        return;
         }
     
         /**
    diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java b/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
    index 480a0810425fc..21dc463572ee2 100644
    --- a/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
    +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
    @@ -84,7 +84,7 @@ final class PBEKey implements SecretKey {
             // Use the cleaner to zero the key when no longer referenced
             final byte[] k = this.key;
             cleanable = CleanerFactory.cleaner().register(this,
    -                () -> java.util.Arrays.fill(k, (byte)0x00));
    +                () -> Arrays.fill(k, (byte)0x00));
         }
     
         public byte[] getEncoded() {
    @@ -196,7 +196,7 @@ private void readObject(java.io.ObjectInputStream s)
             // Use cleaner to zero the key when no longer referenced
             final byte[] k = this.key;
             cleanable = CleanerFactory.cleaner().register(this,
    -                () -> java.util.Arrays.fill(k, (byte)0x00));
    +                () -> Arrays.fill(k, (byte)0x00));
         }
     
     
    diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java
    index 7b3850bd55661..af072c6f5d708 100644
    --- a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java
    +++ b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java
    @@ -71,7 +71,6 @@ public void padWithLen(byte[] in, int off, int len)
     
             byte paddingOctet = (byte) (len & 0xff);
             Arrays.fill(in, off, idx, paddingOctet);
    -        return;
         }
     
         /**
    diff --git a/src/java.base/share/classes/java/io/BufferedInputStream.java b/src/java.base/share/classes/java/io/BufferedInputStream.java
    index e5a44761b8aec..d4531d27db1e9 100644
    --- a/src/java.base/share/classes/java/io/BufferedInputStream.java
    +++ b/src/java.base/share/classes/java/io/BufferedInputStream.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1994, 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
    @@ -643,9 +643,13 @@ private long implTransferTo(OutputStream out) throws IOException {
             if (getClass() == BufferedInputStream.class && markpos == -1) {
                 int avail = count - pos;
                 if (avail > 0) {
    -                // Prevent poisoning and leaking of buf
    -                byte[] buffer = Arrays.copyOfRange(getBufIfOpen(), pos, count);
    -                out.write(buffer);
    +                if (isTrusted(out)) {
    +                    out.write(getBufIfOpen(), pos, avail);
    +                } else {
    +                    // Prevent poisoning and leaking of buf
    +                    byte[] buffer = Arrays.copyOfRange(getBufIfOpen(), pos, count);
    +                    out.write(buffer);
    +                }
                     pos = count;
                 }
                 try {
    @@ -658,4 +662,22 @@ private long implTransferTo(OutputStream out) throws IOException {
             }
         }
     
    +    /**
    +     * Returns true if this class satisfies the following conditions:
    +     * 
      + *
    • does not retain a reference to the {@code byte[]}
    • + *
    • does not leak a reference to the {@code byte[]} to non-trusted classes
    • + *
    • does not modify the contents of the {@code byte[]}
    • + *
    • {@code write()} method does not read the contents outside of the offset/length bounds
    • + *
    + * + * @return true if this class is trusted + */ + private static boolean isTrusted(OutputStream os) { + var clazz = os.getClass(); + return clazz == ByteArrayOutputStream.class + || clazz == FileOutputStream.class + || clazz == PipedOutputStream.class; + } + } diff --git a/src/java.base/share/classes/java/io/SequenceInputStream.java b/src/java.base/share/classes/java/io/SequenceInputStream.java index de3fafc884d7e..b89d9ca80b0fa 100644 --- a/src/java.base/share/classes/java/io/SequenceInputStream.java +++ b/src/java.base/share/classes/java/io/SequenceInputStream.java @@ -242,11 +242,14 @@ public long transferTo(OutputStream out) throws IOException { if (getClass() == SequenceInputStream.class) { long transferred = 0; while (in != null) { + long numTransferred = in.transferTo(out); + // increment the total transferred byte count + // only if we haven't already reached the Long.MAX_VALUE if (transferred < Long.MAX_VALUE) { try { - transferred = Math.addExact(transferred, in.transferTo(out)); + transferred = Math.addExact(transferred, numTransferred); } catch (ArithmeticException ignore) { - return Long.MAX_VALUE; + transferred = Long.MAX_VALUE; } } nextStream(); diff --git a/src/java.base/share/classes/java/lang/StringBuffer.java b/src/java.base/share/classes/java/lang/StringBuffer.java index ec7ecb5d2451f..d77462f0c706f 100644 --- a/src/java.base/share/classes/java/lang/StringBuffer.java +++ b/src/java.base/share/classes/java/lang/StringBuffer.java @@ -715,6 +715,7 @@ public synchronized StringBuffer reverse() { */ @Override public synchronized StringBuffer repeat(int codePoint, int count) { + toStringCache = null; super.repeat(codePoint, count); return this; } @@ -726,6 +727,7 @@ public synchronized StringBuffer repeat(int codePoint, int count) { */ @Override public synchronized StringBuffer repeat(CharSequence cs, int count) { + toStringCache = null; super.repeat(cs, count); return this; } diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java index 13ba543348ed7..36a673fde60cf 100644 --- a/src/java.base/share/classes/java/lang/VirtualThread.java +++ b/src/java.base/share/classes/java/lang/VirtualThread.java @@ -975,12 +975,12 @@ StackTraceElement[] asyncGetStackTrace() { * Returns null if the thread is mounted or in transition. */ private StackTraceElement[] tryGetStackTrace() { - int initialState = state(); + int initialState = state() & ~SUSPENDED; switch (initialState) { case NEW, STARTED, TERMINATED -> { return new StackTraceElement[0]; // unmounted, empty stack } - case RUNNING, PINNED -> { + case RUNNING, PINNED, TIMED_PINNED -> { return null; // mounted } case PARKED, TIMED_PARKED -> { @@ -992,7 +992,7 @@ private StackTraceElement[] tryGetStackTrace() { case PARKING, TIMED_PARKING, YIELDING -> { return null; // in transition } - default -> throw new InternalError(); + default -> throw new InternalError("" + initialState); } // thread is unmounted, prevent it from continuing diff --git a/src/java.base/share/classes/java/lang/invoke/Invokers.java b/src/java.base/share/classes/java/lang/invoke/Invokers.java index f14ddc70b4062..6c383dd3f2ca3 100644 --- a/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -190,7 +190,7 @@ static MemberName invokeBasicMethod(MethodType basicType) { private boolean checkInvoker(MethodHandle invoker) { assert(targetType.invokerType().equals(invoker.type())) - : java.util.Arrays.asList(targetType, targetType.invokerType(), invoker); + : Arrays.asList(targetType, targetType.invokerType(), invoker); assert(invoker.internalMemberName() == null || invoker.internalMemberName().getMethodType().equals(targetType)); assert(!invoker.isVarargsCollector()); @@ -200,7 +200,7 @@ private boolean checkInvoker(MethodHandle invoker) { private boolean checkVarHandleInvoker(MethodHandle invoker) { MethodType invokerType = targetType.insertParameterTypes(0, VarHandle.class); assert(invokerType.equals(invoker.type())) - : java.util.Arrays.asList(targetType, invokerType, invoker); + : Arrays.asList(targetType, invokerType, invoker); assert(invoker.internalMemberName() == null || invoker.internalMemberName().getMethodType().equals(targetType)); assert(!invoker.isVarargsCollector()); diff --git a/src/java.base/share/classes/java/math/BigInteger.java b/src/java.base/share/classes/java/math/BigInteger.java index 43c401dd13677..98f55ef3c8c0f 100644 --- a/src/java.base/share/classes/java/math/BigInteger.java +++ b/src/java.base/share/classes/java/math/BigInteger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1774,7 +1774,7 @@ private static BigInteger multiplyByInt(int[] x, int y, int sign) { carry = product >>> 32; } if (carry == 0L) { - rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length); + rmag = Arrays.copyOfRange(rmag, 1, rmag.length); } else { rmag[rstart] = (int)carry; } @@ -1819,7 +1819,7 @@ BigInteger multiply(long v) { rmag[0] = (int)carry; } if (carry == 0L) - rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length); + rmag = Arrays.copyOfRange(rmag, 1, rmag.length); return new BigInteger(rmag, rsign); } @@ -4593,7 +4593,7 @@ private static int[] stripLeadingZeroInts(int[] val) { // Find first nonzero byte for (keep = 0; keep < vlen && val[keep] == 0; keep++) ; - return java.util.Arrays.copyOfRange(val, keep, vlen); + return Arrays.copyOfRange(val, keep, vlen); } /** @@ -4607,7 +4607,7 @@ private static int[] trustedStripLeadingZeroInts(int[] val) { // Find first nonzero byte for (keep = 0; keep < vlen && val[keep] == 0; keep++) ; - return keep == 0 ? val : java.util.Arrays.copyOfRange(val, keep, vlen); + return keep == 0 ? val : Arrays.copyOfRange(val, keep, vlen); } private static int[] stripLeadingZeroBytes(byte[] a, int from, int len) { diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 77f06fb94100b..f1f4b802b5f8f 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -267,7 +267,7 @@ private void init(int initCapacity) { } /** - * Constructs a new identity hash map containing the keys-value mappings + * Constructs a new identity hash map containing the key-value mappings * in the specified map. * * @param m the map whose mappings are to be placed into this map diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 7281db3297b6b..d48910fe5efa0 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -95,7 +95,8 @@ */ public class ZipFile implements ZipConstants, Closeable { - private final String name; // zip file name + private final String filePath; // zip file path + private final String fileName; // name of the file private volatile boolean closeRequested; // The "resource" used by this zip file that needs to be @@ -245,7 +246,8 @@ public ZipFile(File file, int mode, Charset charset) throws IOException } Objects.requireNonNull(charset, "charset"); - this.name = name; + this.filePath = name; + this.fileName = file.getName(); long t0 = System.nanoTime(); this.res = new CleanableResource(this, ZipCoder.get(charset), file, mode); @@ -483,7 +485,16 @@ public int available() throws IOException { * @return the path name of the ZIP file */ public String getName() { - return name; + return filePath; + } + + /** + * {@return a string identifying this {@code ZipFile}, for debugging} + */ + @Override + public String toString() { + return this.fileName + + "@" + Integer.toHexString(System.identityHashCode(this)); } private class ZipEntryIterator diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java index 67bdaa481d372..9b6c7d7ad4c8f 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -189,45 +189,73 @@ public BootstrapMethodEntryImpl bootstrapMethodEntry(int index) { return bsmEntries().get(index); } + private static IllegalArgumentException outOfBoundsError(IndexOutOfBoundsException cause) { + return new IllegalArgumentException("Reading beyond classfile bounds", cause); + } + @Override public int readU1(int p) { - return buffer[p] & 0xFF; + try { + return buffer[p] & 0xFF; + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override public int readU2(int p) { - int b1 = buffer[p] & 0xFF; - int b2 = buffer[p + 1] & 0xFF; - return (b1 << 8) + b2; + try { + int b1 = buffer[p] & 0xFF; + int b2 = buffer[p + 1] & 0xFF; + return (b1 << 8) + b2; + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override public int readS1(int p) { - return buffer[p]; + try { + return buffer[p]; + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override public int readS2(int p) { - int b1 = buffer[p]; - int b2 = buffer[p + 1] & 0xFF; - return (b1 << 8) + b2; + try { + int b1 = buffer[p]; + int b2 = buffer[p + 1] & 0xFF; + return (b1 << 8) + b2; + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override public int readInt(int p) { - int ch1 = buffer[p] & 0xFF; - int ch2 = buffer[p + 1] & 0xFF; - int ch3 = buffer[p + 2] & 0xFF; - int ch4 = buffer[p + 3] & 0xFF; - return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4; + try { + int ch1 = buffer[p] & 0xFF; + int ch2 = buffer[p + 1] & 0xFF; + int ch3 = buffer[p + 2] & 0xFF; + int ch4 = buffer[p + 3] & 0xFF; + return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4; + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override public long readLong(int p) { - return ((long) buffer[p + 0] << 56) + ((long) (buffer[p + 1] & 255) << 48) + - ((long) (buffer[p + 2] & 255) << 40) + ((long) (buffer[p + 3] & 255) << 32) + - ((long) (buffer[p + 4] & 255) << 24) + ((buffer[p + 5] & 255) << 16) + ((buffer[p + 6] & 255) << 8) + - (buffer[p + 7] & 255); + try { + return ((long) buffer[p + 0] << 56) + ((long) (buffer[p + 1] & 255) << 48) + + ((long) (buffer[p + 2] & 255) << 40) + ((long) (buffer[p + 3] & 255) << 32) + + ((long) (buffer[p + 4] & 255) << 24) + ((buffer[p + 5] & 255) << 16) + ((buffer[p + 6] & 255) << 8) + + (buffer[p + 7] & 255); + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override @@ -242,12 +270,20 @@ public double readDouble(int p) { @Override public byte[] readBytes(int p, int len) { - return Arrays.copyOfRange(buffer, p, p + len); + try { + return Arrays.copyOfRange(buffer, p, p + len); + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } @Override public void copyBytesTo(BufWriter buf, int p, int len) { - buf.writeBytes(buffer, p, len); + try { + buf.writeBytes(buffer, p, len); + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } BootstrapMethodsAttribute bootstrapMethodsAttribute() { @@ -446,8 +482,12 @@ public boolean compare(BufWriter bufWriter, int bufWriterOffset, int classReaderOffset, int length) { - return Arrays.equals(((BufWriterImpl) bufWriter).elems, - bufWriterOffset, bufWriterOffset + length, - buffer, classReaderOffset, classReaderOffset + length); + try { + return Arrays.equals(((BufWriterImpl) bufWriter).elems, + bufWriterOffset, bufWriterOffset + length, + buffer, classReaderOffset, classReaderOffset + length); + } catch (IndexOutOfBoundsException e) { + throw outOfBoundsError(e); + } } } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java index fd1e612997ac4..f3efffb5b5615 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -44,49 +44,64 @@ public SignaturesImpl() { public ClassSignature parseClassSignature(String signature) { this.sig = signature; sigp = 0; - List typeParamTypes = parseParamTypes(); - RefTypeSig superclass = referenceTypeSig(); - ArrayList superinterfaces = null; - while (sigp < sig.length()) { - if (superinterfaces == null) - superinterfaces = new ArrayList<>(); - superinterfaces.add(referenceTypeSig()); + try { + List typeParamTypes = parseParamTypes(); + RefTypeSig superclass = referenceTypeSig(); + ArrayList superinterfaces = null; + while (sigp < sig.length()) { + if (superinterfaces == null) + superinterfaces = new ArrayList<>(); + superinterfaces.add(referenceTypeSig()); + } + return new ClassSignatureImpl(typeParamTypes, superclass, null2Empty(superinterfaces)); + } catch (IndexOutOfBoundsException e) { + throw error("Not a valid class signature"); } - return new ClassSignatureImpl(typeParamTypes, superclass, null2Empty(superinterfaces)); } public MethodSignature parseMethodSignature(String signature) { this.sig = signature; sigp = 0; - List typeParamTypes = parseParamTypes(); - assert sig.charAt(sigp) == '('; - sigp++; - ArrayList paramTypes = null; - while (sig.charAt(sigp) != ')') { - if (paramTypes == null) - paramTypes = new ArrayList<>(); - paramTypes.add(typeSig()); - } - sigp++; - Signature returnType = typeSig(); - ArrayList throwsTypes = null; - while (sigp < sig.length() && sig.charAt(sigp) == '^') { + try { + List typeParamTypes = parseParamTypes(); + if (sig.charAt(sigp) != '(') throw error("Expected ( at possition %d of signature".formatted(sigp)); + sigp++; + ArrayList paramTypes = null; + while (sig.charAt(sigp) != ')') { + if (paramTypes == null) + paramTypes = new ArrayList<>(); + paramTypes.add(typeSig()); + } sigp++; - if (throwsTypes == null) - throwsTypes = new ArrayList<>(); - var t = typeSig(); - if (t instanceof ThrowableSig ts) - throwsTypes.add(ts); - else - throw new IllegalArgumentException("not a valid type signature: " + sig); + Signature returnType = typeSig(); + ArrayList throwsTypes = null; + while (sigp < sig.length()) { + if (sig.charAt(sigp) != '^') throw error("Expected ^ at possition %d of signature".formatted(sigp)); + sigp++; + if (throwsTypes == null) + throwsTypes = new ArrayList<>(); + var t = referenceTypeSig(); + if (t instanceof ThrowableSig ts) + throwsTypes.add(ts); + else + throw error("Not a valid throwable signature %s in".formatted(t.signatureString())); + } + return new MethodSignatureImpl(typeParamTypes, null2Empty(throwsTypes), returnType, null2Empty(paramTypes)); + } catch (IndexOutOfBoundsException e) { + throw error("Not a valid method signature"); } - return new MethodSignatureImpl(typeParamTypes, null2Empty(throwsTypes), returnType, null2Empty(paramTypes)); } public Signature parseSignature(String signature) { this.sig = signature; sigp = 0; - return typeSig(); + try { + var s = typeSig(); + if (sigp == signature.length()) + return s; + } catch (IndexOutOfBoundsException e) { + } + throw error("Not a valid type signature"); } private List parseParamTypes() { @@ -157,7 +172,7 @@ private RefTypeSig referenceTypeSig() { return ty; case '[': return ArrayTypeSig.of(typeSig()); } - throw new IllegalArgumentException("not a valid type signature: " + sig); + throw error("Unexpected character %c at possition %d of signature".formatted(c, sigp - 1)); } private TypeArg typeArg() { @@ -292,4 +307,8 @@ public String signatureString() { private static List null2Empty(ArrayList l) { return l == null ? List.of() : Collections.unmodifiableList(l); } + + private IllegalArgumentException error(String message) { + return new IllegalArgumentException("%s: %s".formatted(message, sig)); + } } 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 370fc73fcd0f4..a75ff58208558 100644 --- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java +++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java @@ -119,8 +119,17 @@ public char[] readPassword(String fmt, Object ... args) { else ioe.addSuppressed(x); } - if (ioe != null) + if (ioe != null) { + Arrays.fill(passwd, ' '); + try { + if (reader instanceof LineReader lr) { + lr.zeroOut(); + } + } catch (IOException x) { + // ignore + } throw ioe; + } } pw.println(); } diff --git a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java index 75922c34e652c..7b0f4d13e4096 100644 --- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java +++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java @@ -64,19 +64,19 @@ private static void setArchivedServicesCatalog(ClassLoader loader) { // Creates the built-in class loaders. static { ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get(); + // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute + String append = VM.getSavedProperty("jdk.boot.class.path.append"); + URLClassPath bootUcp = (append != null && !append.isEmpty()) + ? new URLClassPath(append, true) + : null; if (archivedClassLoaders != null) { - // assert VM.getSavedProperty("jdk.boot.class.path.append") == null BOOT_LOADER = (BootClassLoader) archivedClassLoaders.bootLoader(); + BOOT_LOADER.setClassPath(bootUcp); setArchivedServicesCatalog(BOOT_LOADER); PLATFORM_LOADER = (PlatformClassLoader) archivedClassLoaders.platformLoader(); setArchivedServicesCatalog(PLATFORM_LOADER); } else { - // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute - String append = VM.getSavedProperty("jdk.boot.class.path.append"); - URLClassPath ucp = (append != null && !append.isEmpty()) - ? new URLClassPath(append, true) - : null; - BOOT_LOADER = new BootClassLoader(ucp); + BOOT_LOADER = new BootClassLoader(bootUcp); PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER); } // A class path is required when no initial module is specified. diff --git a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java index f8518fff4c4d5..8b6dd9c5ec7b1 100644 --- a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -204,7 +204,7 @@ private static boolean isASCIISuperset(String encoding) throws Exception { 47, 63, 58, 64, 38, 61, 43, 36, 44}; byte[] b = chkS.getBytes(encoding); - return java.util.Arrays.equals(b, chkB); + return Arrays.equals(b, chkB); } private class DefaultParser implements FtpDirParser { diff --git a/src/java.base/share/data/tzdata/VERSION b/src/java.base/share/data/tzdata/VERSION index 66bd061e8bcf9..560884d1a8253 100644 --- a/src/java.base/share/data/tzdata/VERSION +++ b/src/java.base/share/data/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2023c +tzdata2023d diff --git a/src/java.base/share/data/tzdata/africa b/src/java.base/share/data/tzdata/africa index a73405fdb01f2..b4789b16c71e5 100644 --- a/src/java.base/share/data/tzdata/africa +++ b/src/java.base/share/data/tzdata/africa @@ -308,13 +308,6 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - # reproduced by other (more accessible) sites[, e.g.,]... # http://elgornal.net/news/news.aspx?id=4699258 -# From Paul Eggert (2014-06-04): -# Sarah El Deeb and Lee Keath of AP report that the Egyptian government says -# the change is because of blackouts in Cairo, even though Ahram Online (cited -# above) says DST had no affect on electricity consumption. There is -# no information about when DST will end this fall. See: -# http://abcnews.go.com/International/wireStory/el-sissi-pushes-egyptians-line-23614833 - # From Steffen Thorsen (2015-04-08): # Egypt will start DST on midnight after Thursday, April 30, 2015. # This is based on a law (no 35) from May 15, 2014 saying it starts the last diff --git a/src/java.base/share/data/tzdata/antarctica b/src/java.base/share/data/tzdata/antarctica index 3de5e726eb4d7..fc7176cd0d57a 100644 --- a/src/java.base/share/data/tzdata/antarctica +++ b/src/java.base/share/data/tzdata/antarctica @@ -103,6 +103,11 @@ # - 2018 Oct 7 4:00 - 2019 Mar 17 3:00 - 2019 Oct 4 3:00 - 2020 Mar 8 3:00 # and now - 2020 Oct 4 0:01 +# From Paul Eggert (2023-12-20): +# Transitions from 2021 on are taken from: +# https://www.timeanddate.com/time/zone/antarctica/casey +# retrieved at various dates. + # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Antarctica/Casey 0 - -00 1969 8:00 - +08 2009 Oct 18 2:00 @@ -116,7 +121,12 @@ Zone Antarctica/Casey 0 - -00 1969 8:00 - +08 2019 Oct 4 3:00 11:00 - +11 2020 Mar 8 3:00 8:00 - +08 2020 Oct 4 0:01 - 11:00 - +11 + 11:00 - +11 2021 Mar 14 0:00 + 8:00 - +08 2021 Oct 3 0:01 + 11:00 - +11 2022 Mar 13 0:00 + 8:00 - +08 2022 Oct 2 0:01 + 11:00 - +11 2023 Mar 9 3:00 + 8:00 - +08 Zone Antarctica/Davis 0 - -00 1957 Jan 13 7:00 - +07 1964 Nov 0 - -00 1969 Feb @@ -263,7 +273,50 @@ Zone Antarctica/Troll 0 - -00 2005 Feb 12 # year-round from 1960/61 to 1992 # Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11 -# See Asia/Urumqi. +# From Craig Mundell (1994-12-15): +# http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP +# Vostok, which is one of the Russian stations, is set on the same +# time as Moscow, Russia. +# +# From Lee Hotz (2001-03-08): +# I queried the folks at Columbia who spent the summer at Vostok and this is +# what they had to say about time there: +# "in the US Camp (East Camp) we have been on New Zealand (McMurdo) +# time, which is 12 hours ahead of GMT. The Russian Station Vostok was +# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead +# of GMT). This is a time zone I think two hours east of Moscow. The +# natural time zone is in between the two: 8 hours ahead of GMT." +# +# From Paul Eggert (2001-05-04): +# This seems to be hopelessly confusing, so I asked Lee Hotz about it +# in person. He said that some Antarctic locations set their local +# time so that noon is the warmest part of the day, and that this +# changes during the year and does not necessarily correspond to mean +# solar noon. So the Vostok time might have been whatever the clocks +# happened to be during their visit. So we still don't really know what time +# it is at Vostok. +# +# From Zakhary V. Akulov (2023-12-17 22:00:48 +0700): +# ... from December, 18, 2023 00:00 by my decision the local time of +# the Antarctic research base Vostok will correspond to UTC+5. +# (2023-12-19): We constantly interact with Progress base, with company who +# builds new wintering station, with sledge convoys, with aviation - they all +# use UTC+5. Besides, difference between Moscow time is just 2 hours now, not 4. +# (2023-12-19, in response to the question "Has local time at Vostok +# been UTC+6 ever since 1957, or has it changed before?"): No. At least +# since my antarctic career start, 10 years ago, Vostok base has UTC+7. +# (In response to a 2023-12-18 question "from 02:00 to 00:00 today"): This. +# +# From Paul Eggert (2023-12-18): +# For lack of better info, guess Vostok was at +07 from founding through today, +# except when closed. + +# Zone NAME STDOFF RULES FORMAT [UNTIL] +Zone Antarctica/Vostok 0 - -00 1957 Dec 16 + 7:00 - +07 1994 Feb + 0 - -00 1994 Nov + 7:00 - +07 2023 Dec 18 2:00 + 5:00 - +05 # S Africa - year-round bases # Marion Island, -4653+03752 diff --git a/src/java.base/share/data/tzdata/asia b/src/java.base/share/data/tzdata/asia index 6a048c3ad283e..f86f84b2d2707 100644 --- a/src/java.base/share/data/tzdata/asia +++ b/src/java.base/share/data/tzdata/asia @@ -678,7 +678,6 @@ Zone Asia/Shanghai 8:05:43 - LMT 1901 8:00 PRC C%sT # Xinjiang time, used by many in western China; represented by Ürümqi / Ürümchi # / Wulumuqi. (Please use Asia/Shanghai if you prefer Beijing time.) -# Vostok base in Antarctica matches this since 1970. Zone Asia/Urumqi 5:50:20 - LMT 1928 6:00 - +06 @@ -3450,6 +3449,9 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # From Heba Hamad (2023-03-22): # ... summer time will begin in Palestine from Saturday 04-29-2023, # 02:00 AM by 60 minutes forward. +# From Heba Hemad (2023-10-09): +# ... winter time will begin in Palestine from Saturday 10-28-2023, +# 02:00 AM by 60 minutes back. # # From Paul Eggert (2023-03-22): # For now, guess that spring and fall transitions will normally @@ -3571,13 +3573,13 @@ Rule Palestine 2070 only - Oct 4 2:00 0 - Rule Palestine 2071 only - Sep 19 2:00 0 - Rule Palestine 2072 only - Sep 10 2:00 0 - Rule Palestine 2072 only - Oct 15 2:00 1:00 S +Rule Palestine 2072 max - Oct Sat<=30 2:00 0 - Rule Palestine 2073 only - Sep 2 2:00 0 - Rule Palestine 2073 only - Oct 7 2:00 1:00 S Rule Palestine 2074 only - Aug 18 2:00 0 - Rule Palestine 2074 only - Sep 29 2:00 1:00 S Rule Palestine 2075 only - Aug 10 2:00 0 - Rule Palestine 2075 only - Sep 14 2:00 1:00 S -Rule Palestine 2075 max - Oct Sat<=30 2:00 0 - Rule Palestine 2076 only - Jul 25 2:00 0 - Rule Palestine 2076 only - Sep 5 2:00 1:00 S Rule Palestine 2077 only - Jul 17 2:00 0 - diff --git a/src/java.base/share/data/tzdata/australasia b/src/java.base/share/data/tzdata/australasia index 893d7055eaba4..366cfd10cc154 100644 --- a/src/java.base/share/data/tzdata/australasia +++ b/src/java.base/share/data/tzdata/australasia @@ -414,8 +414,14 @@ Zone Antarctica/Macquarie 0 - -00 1899 Nov # Please note that there will not be any daylight savings time change # in Fiji for 2022-2023.... # https://www.facebook.com/FijianGovernment/posts/pfbid0mmWVTYmTibn66ybpFda75pDcf34SSpoSaskJW5gXwaKo5Sgc7273Q4fXWc6kQV6Hl + +# From Almaz Mingaleev (2023-10-06): +# Cabinet approved the suspension of Daylight Saving and appropriate +# legislative changes will be considered including the repeal of the +# Daylight Saving Act 1998 +# https://www.fiji.gov.fj/Media-Centre/Speeches/English/CABINET-DECISIONS-3-OCTOBER-2023 # -# From Paul Eggert (2022-10-27): +# From Paul Eggert (2023-10-06): # For now, assume DST is suspended indefinitely. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S diff --git a/src/java.base/share/data/tzdata/backward b/src/java.base/share/data/tzdata/backward index c0746d6dd1bc8..7ddc6cc3d93b0 100644 --- a/src/java.base/share/data/tzdata/backward +++ b/src/java.base/share/data/tzdata/backward @@ -228,7 +228,6 @@ Link America/Puerto_Rico America/Tortola Link Pacific/Port_Moresby Antarctica/DumontDUrville Link Pacific/Auckland Antarctica/McMurdo Link Asia/Riyadh Antarctica/Syowa -Link Asia/Urumqi Antarctica/Vostok Link Europe/Berlin Arctic/Longyearbyen Link Asia/Riyadh Asia/Aden Link Asia/Qatar Asia/Bahrain diff --git a/src/java.base/share/data/tzdata/europe b/src/java.base/share/data/tzdata/europe index 446d2e1e658fa..f1b084f64d034 100644 --- a/src/java.base/share/data/tzdata/europe +++ b/src/java.base/share/data/tzdata/europe @@ -1146,6 +1146,23 @@ Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn # 2. The shift *from* DST in 2023 happens as normal, but coincides with the # shift to UTC-02 normaltime (people will not change their clocks here). # 3. After this, DST is still observed, but as -02/-01 instead of -03/-02. +# +# From Múte Bourup Egede via Jógvan Svabo Samuelsen (2023-03-15): +# Greenland will not switch to Daylight Saving Time this year, 2023, +# because the standard time for Greenland will change from UTC -3 to UTC -2. +# However, Greenland will change to Daylight Saving Time again in 2024 +# and onwards. + +# From a contributor who wishes to remain anonymous for now (2023-10-29): +# https://www.dr.dk/nyheder/seneste/i-nat-skal-uret-stilles-en-time-tilbage-men-foerste-gang-sker-det-ikke-i-groenland +# with a link to that page: +# https://naalakkersuisut.gl/Nyheder/2023/10/2710_sommertid +# ... Ittoqqortoormiit joins the time of Nuuk at March 2024. +# What would mean that America/Scoresbysund would either be in -01 year round +# or in -02/-01 like America/Nuuk, but no longer in -01/+00. +# +# From Paul Eggert (2023-10-29): +# For now, assume it will be like America/Nuuk. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D @@ -1166,10 +1183,12 @@ Zone America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28 Zone America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 # Ittoqqortoormiit -2:00 - -02 1980 Apr 6 2:00 -2:00 C-Eur -02/-01 1981 Mar 29 - -1:00 EU -01/+00 + -1:00 EU -01/+00 2024 Mar 31 + -2:00 EU -02/-01 Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb -3:00 - -03 1980 Apr 6 2:00 - -3:00 EU -03/-02 2023 Oct 29 1:00u + -3:00 EU -03/-02 2023 Mar 26 1:00u + -2:00 - -02 2023 Oct 29 1:00u -2:00 EU -02/-01 Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik -4:00 Thule A%sT @@ -3734,11 +3753,7 @@ Zone Europe/Istanbul 1:55:52 - LMT 1880 # and not at 3:00 as would have been under EU rules. # This is why I have set the change to EU rules into May 1996, # so that the change in March is stil covered by the Ukraine rule. -# The next change in October 1996 happened under EU rules.... -# TZ database holds three other zones for Ukraine.... I have not yet -# worked out the consequences for these three zones, as we (me and my -# US colleague David Cochrane) are still trying to get more -# information upon these local deviations from Kiev rules. +# The next change in October 1996 happened under EU rules. # # From Paul Eggert (2022-08-27): # For now, assume that Ukraine's zones all followed the same rules, diff --git a/src/java.base/share/data/tzdata/iso3166.tab b/src/java.base/share/data/tzdata/iso3166.tab index cea17732dd138..7fa350ecbe3db 100644 --- a/src/java.base/share/data/tzdata/iso3166.tab +++ b/src/java.base/share/data/tzdata/iso3166.tab @@ -26,17 +26,22 @@ # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. # -# From Paul Eggert (2022-11-18): +# From Paul Eggert (2023-09-06): # This file contains a table of two-letter country codes. Columns are # separated by a single tab. Lines beginning with '#' are comments. # All text uses UTF-8 encoding. The columns of the table are as follows: # # 1. ISO 3166-1 alpha-2 country code, current as of -# ISO 3166-1 N1087 (2022-09-02). See: Updates on ISO 3166-1 -# https://isotc.iso.org/livelink/livelink/Open/16944257 -# 2. The usual English name for the coded region, -# chosen so that alphabetic sorting of subsets produces helpful lists. -# This is not the same as the English name in the ISO 3166 tables. +# ISO/TC 46 N1108 (2023-04-05). See: ISO/TC 46 Documents +# https://www.iso.org/committee/48750.html?view=documents +# 2. The usual English name for the coded region. This sometimes +# departs from ISO-listed names, sometimes so that sorted subsets +# of names are useful (e.g., "Samoa (American)" and "Samoa +# (western)" rather than "American Samoa" and "Samoa"), +# sometimes to avoid confusion among non-experts (e.g., +# "Czech Republic" and "Turkey" rather than "Czechia" and "Türkiye"), +# and sometimes to omit needless detail or churn (e.g., "Netherlands" +# rather than "Netherlands (the)" or "Netherlands (Kingdom of the)"). # # The table is sorted by country code. # diff --git a/src/java.base/share/data/tzdata/leapseconds b/src/java.base/share/data/tzdata/leapseconds index 89ce8b89cd28f..ab2c1af4bed59 100644 --- a/src/java.base/share/data/tzdata/leapseconds +++ b/src/java.base/share/data/tzdata/leapseconds @@ -95,11 +95,11 @@ Leap 2016 Dec 31 23:59:60 + S # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2023 Dec 28 00:00:00 +#Expires 2024 Jun 28 00:00:00 # POSIX timestamps for the data in this file: #updated 1467936000 (2016-07-08 00:00:00 UTC) -#expires 1703721600 (2023-12-28 00:00:00 UTC) +#expires 1719532800 (2024-06-28 00:00:00 UTC) -# Updated through IERS Bulletin C65 -# File expires on: 28 December 2023 +# Updated through IERS Bulletin C66 +# File expires on: 28 June 2024 diff --git a/src/java.base/share/data/tzdata/northamerica b/src/java.base/share/data/tzdata/northamerica index e240cf35103c4..b96269a0e26f5 100644 --- a/src/java.base/share/data/tzdata/northamerica +++ b/src/java.base/share/data/tzdata/northamerica @@ -1,3 +1,4 @@ +# # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -1475,7 +1476,7 @@ Rule StJohns 1989 2006 - Apr Sun>=1 0:01 1:00 D Rule StJohns 2007 2011 - Mar Sun>=8 0:01 1:00 D Rule StJohns 2007 2010 - Nov Sun>=1 0:01 0 S # -# St John's has an apostrophe, but Posix file names can't have apostrophes. +# St John's has an apostrophe, but POSIX file names can't have apostrophes. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/St_Johns -3:30:52 - LMT 1884 -3:30:52 StJohns N%sT 1918 diff --git a/src/java.base/share/data/tzdata/southamerica b/src/java.base/share/data/tzdata/southamerica index 4024e7180cdb9..da2c623926247 100644 --- a/src/java.base/share/data/tzdata/southamerica +++ b/src/java.base/share/data/tzdata/southamerica @@ -1720,6 +1720,12 @@ Rule Para 2010 2012 - Apr Sun>=8 0:00 0 - # From Carlos Raúl Perasso (2014-02-28): # Decree 1264 can be found at: # http://www.presidencia.gov.py/archivos/documentos/DECRETO1264_ey9r8zai.pdf +# +# From Paul Eggert (2023-07-26): +# Transition dates are now set by Law No. 7115, not by presidential decree. +# https://www.abc.com.py/politica/2023/07/12/promulgacion-el-cambio-de-hora-sera-por-ley/ +# From Carlos Raúl Perasso (2023-07-27): +# http://silpy.congreso.gov.py/descarga/ley-144138 Rule Para 2013 max - Mar Sun>=22 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] diff --git a/src/java.base/share/data/tzdata/zone.tab b/src/java.base/share/data/tzdata/zone.tab index 3edb0d61c8099..0a01e8777dd25 100644 --- a/src/java.base/share/data/tzdata/zone.tab +++ b/src/java.base/share/data/tzdata/zone.tab @@ -71,7 +71,7 @@ AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN) AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) AR -2649-06513 America/Argentina/Tucuman Tucuman (TM) -AR -2828-06547 America/Argentina/Catamarca Catamarca (CT); Chubut (CH) +AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) @@ -110,7 +110,7 @@ BN +0456+11455 Asia/Brunei BO -1630-06809 America/La_Paz BQ +120903-0681636 America/Kralendijk BR -0351-03225 America/Noronha Atlantic islands -BR -0127-04829 America/Belem Para (east); Amapa +BR -0127-04829 America/Belem Para (east), Amapa BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB) BR -0803-03454 America/Recife Pernambuco BR -0712-04812 America/Araguaina Tocantins @@ -130,21 +130,21 @@ BT +2728+08939 Asia/Thimphu BW -2439+02555 Africa/Gaborone BY +5354+02734 Europe/Minsk BZ +1730-08812 America/Belize -CA +4734-05243 America/St_Johns Newfoundland; Labrador (southeast) -CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE +CA +4734-05243 America/St_Johns Newfoundland, Labrador (SE) +CA +4439-06336 America/Halifax Atlantic - NS (most areas), PE CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) CA +4606-06447 America/Moncton Atlantic - New Brunswick CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) -CA +4339-07923 America/Toronto Eastern - ON, QC (most areas) +CA +4339-07923 America/Toronto Eastern - ON & QC (most areas) CA +6344-06828 America/Iqaluit Eastern - NU (most areas) -CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H) -CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba +CA +484531-0913718 America/Atikokan EST - ON (Atikokan), NU (Coral H) +CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba CA +744144-0944945 America/Resolute Central - NU (Resolute) CA +624900-0920459 America/Rankin_Inlet Central - NU (central) CA +5024-10439 America/Regina CST - SK (most areas) CA +5017-10750 America/Swift_Current CST - SK (midwest) -CA +5333-11328 America/Edmonton Mountain - AB; BC (E); NT (E); SK (W) +CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W) CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) CA +682059-1334300 America/Inuvik Mountain - NT (west) CA +4906-11631 America/Creston MST - BC (Creston) @@ -230,8 +230,8 @@ HT +1832-07220 America/Port-au-Prince HU +4730+01905 Europe/Budapest ID -0610+10648 Asia/Jakarta Java, Sumatra ID -0002+10920 Asia/Pontianak Borneo (west, central) -ID -0507+11924 Asia/Makassar Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west) -ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya); Malukus/Moluccas +ID -0507+11924 Asia/Makassar Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west) +ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya), Malukus/Moluccas IE +5320-00615 Europe/Dublin IL +314650+0351326 Asia/Jerusalem IM +5409-00428 Europe/Isle_of_Man @@ -378,7 +378,7 @@ RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky RU +5934+15048 Asia/Magadan MSK+08 - Magadan RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island -RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); N Kuril Is +RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E), N Kuril Is RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea RW -0157+03004 Africa/Kigali @@ -441,7 +441,7 @@ US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver) US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) US +394421-1045903 America/Denver Mountain (most areas) -US +433649-1161209 America/Boise Mountain - ID (south); OR (east) +US +433649-1161209 America/Boise Mountain - ID (south), OR (east) US +332654-1120424 America/Phoenix MST - AZ (except Navajo) US +340308-1181434 America/Los_Angeles Pacific US +611305-1495401 America/Anchorage Alaska (most areas) diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java index 0dfd86caf1a9f..88c74322c3997 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -169,7 +169,7 @@ private ElementFilter() {} // Do not instantiate. } /** - * {@return a set of types in {@code elements}} + * {@return a set of classes and interfaces in {@code elements}} * @param elements the elements to filter */ public static Set diff --git a/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java b/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java index 246eb1abbdd65..3547862615aea 100644 --- a/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java +++ b/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -592,7 +592,7 @@ private int calcRealMapSize(int bits, int size) { private BigInteger getAllValid() { int numbytes = (map_size+7)/8; byte[] valid = new byte[numbytes]; - java.util.Arrays.fill(valid, (byte)0xff); + Arrays.fill(valid, (byte)0xff); valid[0] = (byte)(0xff >>> (numbytes*8 - map_size)); return new BigInteger(1, valid); diff --git a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp index 08e03d0095992..12c2677e32a37 100644 --- a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp +++ b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp @@ -46,6 +46,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme); typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect); +typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList); typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi); typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc, @@ -90,6 +91,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION) (HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo, int iPropId, DWORD *pdwDuration); +static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL; static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL; static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL; static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL; @@ -109,13 +111,17 @@ static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT IsThemeBackgroundPartiallyTransparentFunc = NULL; static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDurationFunc = NULL; +constexpr unsigned int defaultDPI = 96; -BOOL InitThemes() { + +static BOOL InitThemes() { static HMODULE hModThemes = NULL; hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL"); DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes); if(hModThemes) { DTRACE_PRINTLN("Loaded UxTheme.dll\n"); + OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes, + "OpenThemeData"); OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress( hModThemes, "OpenThemeDataForDpi"); DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress( @@ -152,7 +158,7 @@ BOOL InitThemes() { (PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes, "GetThemeTransitionDuration"); - if(OpenThemeDataForDpiFunc + if((OpenThemeDataForDpiFunc || OpenThemeDataFunc) && DrawThemeBackgroundFunc && CloseThemeDataFunc && DrawThemeTextFunc @@ -173,10 +179,12 @@ BOOL InitThemes() { DTRACE_PRINTLN("Loaded function pointers.\n"); // We need to make sure we can load the Theme. // Use the default DPI value of 96 on windows. - constexpr unsigned int defaultDPI = 96; - HTHEME hTheme = OpenThemeDataForDpiFunc ( - AwtToolkit::GetInstance().GetHWnd(), - L"Button", defaultDPI); + HTHEME hTheme = OpenThemeDataForDpiFunc + ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), + L"Button", defaultDPI) + : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), + L"Button"); + if(hTheme) { DTRACE_PRINTLN("Loaded Theme data.\n"); CloseThemeDataFunc(hTheme); @@ -246,11 +254,13 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme JNU_ThrowOutOfMemoryError(env, 0); return 0; } + // We need to open the Theme on a Window that will stick around. // The best one for that purpose is the Toolkit window. - HTHEME htheme = OpenThemeDataForDpiFunc( - AwtToolkit::GetInstance().GetHWnd(), - str, dpi); + HTHEME htheme = OpenThemeDataForDpiFunc + ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi) + : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str); + JNU_ReleaseStringPlatformChars(env, widget, str); return (jlong) htheme; } @@ -430,9 +440,14 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground rect.left = 0; rect.top = 0; - rect.bottom = rectBottom; - rect.right = rectRight; + if (OpenThemeDataForDpiFunc) { + rect.bottom = rectBottom; + rect.right = rectRight; + } else { + rect.bottom = h; + rect.right = w; + } ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h); HRESULT hres = DrawThemeBackgroundFunc(hTheme, memDC, part, state, &rect, NULL); @@ -455,6 +470,28 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground ReleaseDC(NULL,defaultDC); } +static void rescale(SIZE *size) { + static int dpiX = -1; + static int dpiY = -1; + + if (dpiX == -1 || dpiY == -1) { + HWND hWnd = ::GetDesktopWindow(); + HDC hDC = ::GetDC(hWnd); + dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX); + dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY); + ::ReleaseDC(hWnd, hDC); + } + + if (dpiX !=0 && dpiX != defaultDPI) { + float invScaleX = (float) defaultDPI / dpiX; + size->cx = (int) round(size->cx * invScaleX); + } + if (dpiY != 0 && dpiY != defaultDPI) { + float invScaleY = (float) defaultDPI / dpiY; + size->cy = (int) round(size->cy * invScaleY); + } +} + jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) { if (env->EnsureLocalCapacity(2) < 0) { return NULL; @@ -746,6 +783,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize CHECK_NULL_RETURN(dimMID, NULL); } + if (!OpenThemeDataForDpiFunc) { + rescale(&size); + } + jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy); if (safe_ExceptionOccurred(env)) { env->ExceptionDescribe(); diff --git a/src/java.management/share/classes/sun/management/ThreadImpl.java b/src/java.management/share/classes/sun/management/ThreadImpl.java index 7eb67e99bc8be..1f37b2da567fd 100644 --- a/src/java.management/share/classes/sun/management/ThreadImpl.java +++ b/src/java.management/share/classes/sun/management/ThreadImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -267,7 +267,7 @@ protected long[] getThreadCpuTime(long[] ids) { int length = ids.length; long[] times = new long[length]; - java.util.Arrays.fill(times, -1); + Arrays.fill(times, -1); if (verified) { if (length == 1) { @@ -306,7 +306,7 @@ protected long[] getThreadUserTime(long[] ids) { int length = ids.length; long[] times = new long[length]; - java.util.Arrays.fill(times, -1); + Arrays.fill(times, -1); if (verified) { if (length == 1) { @@ -390,7 +390,7 @@ protected long[] getThreadAllocatedBytes(long[] ids) { boolean verified = verifyThreadAllocatedMemory(ids); long[] sizes = new long[ids.length]; - java.util.Arrays.fill(sizes, -1); + Arrays.fill(sizes, -1); if (verified) { getThreadAllocatedMemory1(ids, sizes); diff --git a/src/java.sql/share/classes/java/sql/Timestamp.java b/src/java.sql/share/classes/java/sql/Timestamp.java index dc347ab02ffaa..8fb85f73c7e4b 100644 --- a/src/java.sql/share/classes/java/sql/Timestamp.java +++ b/src/java.sql/share/classes/java/sql/Timestamp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, 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 @@ -542,7 +542,7 @@ public LocalDateTime toLocalDateTime() { */ public static Timestamp from(Instant instant) { try { - Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND); + Timestamp stamp = new Timestamp(Math.multiplyExact(instant.getEpochSecond(), MILLIS_PER_SECOND)); stamp.nanos = instant.getNano(); return stamp; } catch (ArithmeticException ex) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index da21fb4a511b6..c8d032109a02e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -46,7 +46,7 @@ * @author K Venugopal * @author Sunitha Reddy * - * @LastModified: Nov 2023 + * @LastModified: Jan 2024 */ public class PropertyManager { @@ -184,6 +184,9 @@ public boolean containsProperty(String property) { * @return the value of a property */ public Object getProperty(String property) { + if (XMLInputFactory.SUPPORT_DTD.equals(property)) { + return fSecurityManager.is(XMLSecurityManager.Limit.STAX_SUPPORT_DTD); + } /** * Check to see if the property is managed by the security manager * */ diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java index ff4e047d4ca99..614bd2fdc999a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -79,7 +79,7 @@ * @author Arnaud Le Hors, IBM * @author Andy Clark, IBM * - * @LastModified: July 2023 + * @LastModified: Jan 2024 */ @SuppressWarnings("deprecation") public abstract class AbstractSAXParser @@ -1831,6 +1831,11 @@ else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) { } */ + // Handle properties managed by XMLSecurityManager + if (featureId.equals(XMLSecurityManager.DISALLOW_DTD)) { + return securityManager.is(XMLSecurityManager.Limit.XERCES_DISALLOW_DTD); + } + return fConfiguration.getFeature(featureId); } catch (XMLConfigurationException e) { diff --git a/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java b/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java index 2cee1fc2489d1..47ef2e437c993 100644 --- a/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java +++ b/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java @@ -95,7 +95,7 @@ public XMLStreamException(String msg, Throwable th) { public XMLStreamException(String msg, Location location, Throwable th) { super("ParseError at [row,col]:["+location.getLineNumber()+","+ location.getColumnNumber()+"]\n"+ - "Message: "+msg); + "Message: "+msg, th); nested = th; this.location = location; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 0dd32fd8eca52..f6ce19fac06e5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -506,7 +506,7 @@ public void visitMethodDef(JCMethodDecl tree) { public void visitApply(JCMethodInvocation invoke) { // Get method symbol - MethodSymbol sym = (MethodSymbol)TreeInfo.symbolFor(invoke.meth); + Symbol sym = TreeInfo.symbolFor(invoke.meth); // Recurse on method expression scan(invoke.meth); @@ -530,7 +530,7 @@ public void visitApply(JCMethodInvocation invoke) { invoke(invoke, sym, invoke.args, receiverRefs); } - private void invoke(JCTree site, MethodSymbol sym, List args, RefSet receiverRefs) { + private void invoke(JCTree site, Symbol sym, List args, RefSet receiverRefs) { // Skip if ignoring warnings for a constructor invoked via 'this()' if (suppressed.contains(sym)) @@ -810,6 +810,10 @@ public void visitSelect(JCFieldAccess tree) { @Override public void visitReference(JCMemberReference tree) { + if (tree.type.isErroneous()) { + //error recovery - ignore erroneous member references + return ; + } // Scan target expression and extract 'this' references, if any scan(tree.expr); diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java index ad32c9aef4d60..4e352bf495011 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -636,7 +636,7 @@ public String engineGetCertificateAlias(Certificate cert) { if (entry.certChain != null && entry.certChain.length > 0 && entry.certChain[0].equals(cert)) { - return entry.getAlias(); + return mapEntry.getKey(); } } diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 index 6d1c5cd008d79..f0e14a9dbd2e5 100644 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ b/src/jdk.jcmd/share/man/jcmd.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2012, 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 @@ -164,6 +164,23 @@ The following \f[I]options\f[R] must be specified using either \f[V]-all\f[R]: (Optional) Show help for all commands (BOOLEAN, false) . .RE .TP +\f[V]Compiler.CodeHeap_Analytics\f[R] [\f[I]function\f[R]] [\f[I]granularity\f[R]] +Print CodeHeap analytics +.RS +.PP +Impact: Low: Depends on code heap size and content. +Holds CodeCache_lock during analysis step, usually sub-second duration. +.PP +\f[I]arguments\f[R]: +.PP +\f[I]function\f[R]: (Optional) Function to be performed (aggregate, +UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames, +discard (STRING, all) +.PP +\f[I]granularity\f[R]: (Optional) Detail level - smaller value -> more +detail (INT, 4096) +.RE +.TP \f[V]Compiler.codecache\f[R] Prints code cache layout and bounds. .RS @@ -178,58 +195,71 @@ Prints all compiled methods in code cache that are alive. Impact: Medium .RE .TP -\f[V]Compiler.perfmap\f[R] [\f[I]arguments\f[R]] (Linux only) -Write map file for Linux perf tool. +\f[V]Compiler.directives_add\f[R] \f[I]arguments\f[R] +Adds compiler directives from a file. .RS .PP Impact: Low .PP \f[I]arguments\f[R]: -.IP \[bu] 2 -\f[V]filename\f[R]: (Optional) Name of the map file (STRING, no default -value) .PP -If \f[V]filename\f[R] is not specified, a default file name is chosen -using the pid of the target JVM process. -For example, if the pid is \f[V]12345\f[R], then the default -\f[V]filename\f[R] will be \f[V]/tmp/perf-12345.map\f[R]. +\f[I]filename\f[R]: The name of the directives file (STRING, no default +value) .RE .TP -\f[V]Compiler.queue\f[R] -Prints methods queued for compilation. +\f[V]Compiler.directives_clear\f[R] +Remove all compiler directives. .RS .PP Impact: Low .RE .TP -\f[V]Compiler.directives_add *filename* *arguments*\f[R] -Adds compiler directives from a file. +\f[V]Compiler.directives_print\f[R] +Prints all active compiler directives. .RS .PP Impact: Low -.PP -\f[I]arguments\f[R]: -.PP -\f[I]filename\f[R]: The name of the directives file (STRING, no default -value) .RE .TP -\f[V]Compiler.directives_clear\f[R] -Remove all compiler directives. +\f[V]Compiler.directives_remove\f[R] +Remove latest added compiler directive. .RS .PP Impact: Low .RE .TP -\f[V]Compiler.directives_print\f[R] -Prints all active compiler directives. +\f[V]Compiler.memory\f[R] [\f[I]options\f[R]] +Print compilation footprint +.RS +.PP +Impact: Medium: Pause time depends on number of compiled methods +.PP +\f[B]Note:\f[R] +.PP +The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or +\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false) +.IP \[bu] 2 +\f[V]-s\f[R]: (Optional) Minimum memory size (MEMORY SIZE, 0) +.RE +.TP +\f[V]Compiler.perfmap\f[R] [\f[I]arguments\f[R]] (Linux only) +Write map file for Linux perf tool. .RS .PP Impact: Low +.PP +\f[I]arguments\f[R]: +.PP +\f[I]filename\f[R]: (Optional) The name of the map file (STRING, no +default value) .RE .TP -\f[V]Compiler.directives_remove\f[R] -Remove latest added compiler directive. +\f[V]Compiler.queue\f[R] +Prints methods queued for compilation. .RS .PP Impact: Low @@ -291,6 +321,12 @@ gzipped format using the given compression level. .IP \[bu] 2 \f[V]-overwrite\f[R]: (Optional) If specified, the dump file will be overwritten if it exists (BOOLEAN, false) +.IP \[bu] 2 +\f[V]-parallel\f[R]: (Optional) Number of parallel threads to use for +heap dump. +The VM will try to use the specified number of threads, but might use +fewer. +(INT, 1) .PP \f[I]arguments\f[R]: .IP \[bu] 2 @@ -354,6 +390,11 @@ If no parameters are entered, the current settings are displayed. .PP \f[I]options\f[R]: .IP \[bu] 2 +\f[V]dumppath\f[R]: (Optional) Path to the location where a recording +file is written in case the VM runs into a critical error, such as a +system crash. +(STRING, The default location is the current directory) +.IP \[bu] 2 \f[V]globalbuffercount\f[R]: (Optional) Number of global buffers. This option is a legacy option: change the \f[V]memorysize\f[R] parameter to alter the number of global buffers. @@ -651,7 +692,7 @@ Impact: Low .RE .TP \f[V]JVMTI.data_dump\f[R] -Signals the JVM to do a data-dump request for JVMTI. +Signal the JVM to do a data-dump request for JVMTI. .RS .PP Impact: High @@ -767,8 +808,45 @@ Stops the remote management agent. Impact: Low --- no impact .RE .TP +\f[V]System.dump_map\f[R] [\f[I]options\f[R]] (Linux only) +Dumps an annotated process memory map to an output file. +.RS +.PP +Impact: Low +.PP +\f[B]Note:\f[R] +.PP +The following \f[I]options\f[R] must be specified using either +\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false) +.IP \[bu] 2 +\f[V]-F\f[R]: (Optional) File path (STRING, +\[dq]vm_memory_map_.txt\[dq]) +.RE +.TP +\f[V]System.map\f[R] [\f[I]options\f[R]] (Linux only) +Prints an annotated process memory map of the VM process. +.RS +.PP +Impact: Low +.PP +\f[B]Note:\f[R] +.PP +The following \f[I]options\f[R] must be specified using either +\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false) +.RE +.TP \f[V]System.native_heap_info\f[R] (Linux only) -Prints information about native heap usage through malloc_info(3). +Attempts to output information regarding native heap usage through +malloc_info(3). +If unsuccessful outputs \[dq]Error: \[dq] and a reason. .RS .PP Impact: Low @@ -781,6 +859,31 @@ Attempts to free up memory by trimming the C-heap. Impact: Low .RE .TP +\f[V]Thread.dump_to_file\f[R] [\f[I]options\f[R]] \f[I]filepath\f[R] +Dump threads, with stack traces, to a file in plain text or JSON format. +.RS +.PP +Impact: Medium: Depends on the number of threads. +.PP +\f[B]Note:\f[R] +.PP +The following \f[I]options\f[R] must be specified using either +\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]-overwrite\f[R]: (Optional) May overwrite existing file (BOOLEAN, +false) +.IP \[bu] 2 +\f[V]-format\f[R]: (Optional) Output format (\[dq]plain\[dq] or +\[dq]json\[dq]) (STRING, plain) +.PP +\f[I]arguments\f[R]: +.IP \[bu] 2 +\f[V]filepath\f[R]: The file path to the output file (STRING, no default +value) +.RE +.TP \f[V]Thread.print\f[R] [\f[I]options\f[R]] Prints all threads with stacktraces. .RS @@ -802,7 +905,7 @@ false) .RE .TP \f[V]VM.cds\f[R] [\f[I]arguments\f[R]] -Dumps a static or dynamic shared archive that includes all currently +Dump a static or dynamic shared archive that includes all currently loaded classes. .RS .PP @@ -828,78 +931,98 @@ If \f[V]dynamic_dump\f[R] is specified, the target JVM must be started with the JVM option \f[V]-XX:+RecordDynamicDumpInfo\f[R]. .RE .TP -\f[V]VM.classloaders\f[R] [\f[I]options\f[R]] -Prints classloader hierarchy. +\f[V]VM.class_hierarchy\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]] +Print a list of all loaded classes, indented to show the class +hierarchy. +The name of each class is followed by the ClassLoaderData* of its +ClassLoader, or \[dq]null\[dq] if it is loaded by the bootstrap class +loader. .RS .PP -Impact: Medium --- Depends on number of class loaders and classes -loaded. +Impact: Medium --- depends on the number of loaded classes. +.PP +\f[B]Note:\f[R] .PP The following \f[I]options\f[R] must be specified using either \f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. .PP \f[I]options\f[R]: .IP \[bu] 2 -\f[V]show-classes\f[R]: (Optional) Print loaded classes. +\f[V]-i\f[R]: (Optional) Inherited interfaces should be printed. (BOOLEAN, false) .IP \[bu] 2 -\f[V]verbose\f[R]: (Optional) Print detailed information. +\f[V]-s\f[R]: (Optional) If a classname is specified, print its +subclasses in addition to its superclasses. +Without this option only the superclasses will be printed. (BOOLEAN, false) +.PP +\f[I]arguments\f[R]: .IP \[bu] 2 -\f[V]fold\f[R]: (Optional) Show loaders of the same name and class as -one. -(BOOLEAN, true) +\f[I]classname\f[R]: (Optional) The name of the class whose hierarchy +should be printed. +If not specified, all class hierarchies are printed. +(STRING, no default value) +.RE +.TP +\f[V]VM.classes\f[R] [\f[I]options\f[R]] +Print all loaded classes +.RS +.PP +Impact: Medium: Depends on number of loaded classes. +.PP +The following \f[I]options\f[R] must be specified using either +\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]-verbose\f[R]: (Optional) Dump the detailed content of a Java +class. +Some classes are annotated with flags: \f[V]F\f[R] = has, or inherits, a +non-empty finalize method, \f[V]f\f[R] = has final method, \f[V]W\f[R] = +methods rewritten, \f[V]C\f[R] = marked with \f[V]\[at]Contended\f[R] +annotation, \f[V]R\f[R] = has been redefined, \f[V]S\f[R] = is shared +class (BOOLEAN, false) .RE .TP \f[V]VM.classloader_stats\f[R] -Prints statistics about all ClassLoaders. +Print statistics about all ClassLoaders. .RS .PP Impact: Low .RE .TP -\f[V]VM.class_hierarchy\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]] -Prints a list of all loaded classes, indented to show the class -hierarchy. -The name of each class is followed by the ClassLoaderData* of its -ClassLoader, or \[dq]null\[dq] if it is loaded by the bootstrap class -loader. +\f[V]VM.classloaders\f[R] [\f[I]options\f[R]] +Prints classloader hierarchy. .RS .PP -Impact: Medium --- depends on the number of loaded classes. -.PP -\f[B]Note:\f[R] +Impact: Medium --- Depends on number of class loaders and classes +loaded. .PP The following \f[I]options\f[R] must be specified using either \f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. .PP \f[I]options\f[R]: .IP \[bu] 2 -\f[V]-i\f[R]: (Optional) Inherited interfaces should be printed. +\f[V]show-classes\f[R]: (Optional) Print loaded classes. (BOOLEAN, false) .IP \[bu] 2 -\f[V]-s\f[R]: (Optional) If a classname is specified, print its -subclasses in addition to its superclasses. -Without this option only the superclasses will be printed. +\f[V]verbose\f[R]: (Optional) Print detailed information. (BOOLEAN, false) -.PP -\f[I]arguments\f[R]: .IP \[bu] 2 -\f[I]classname\f[R]: (Optional) The name of the class whose hierarchy -should be printed. -If not specified, all class hierarchies are printed. -(STRING, no default value) +\f[V]fold\f[R]: (Optional) Show loaders of the same name and class as +one. +(BOOLEAN, true) .RE .TP \f[V]VM.command_line\f[R] -Prints the command line used to start this VM instance. +Print the command line used to start this VM instance. .RS .PP Impact: Low .RE .TP \f[V]VM.dynlibs\f[R] -Prints the loaded dynamic libraries. +Print loaded dynamic libraries. .RS .PP Impact: Low @@ -928,8 +1051,25 @@ If omitted, all events are printed. (STRING, no default value) .RE .TP +\f[V]VM.flags\f[R] [\f[I]options\f[R]] +Print the VM flag options and their current values. +.RS +.PP +Impact: Low +.PP +\f[B]Note:\f[R] +.PP +The following \f[I]options\f[R] must be specified using either +\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]-all\f[R]: (Optional) Prints all flags supported by the VM +(BOOLEAN, false). +.RE +.TP \f[V]VM.info\f[R] -Prints information about the JVM environment and status. +Print information about the JVM environment and status. .RS .PP Impact: Low @@ -974,23 +1114,6 @@ configuration. (BOOLEAN, no default value) .RE .TP -\f[V]VM.flags\f[R] [\f[I]options\f[R]] -Prints the VM flag options and their current values. -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-all\f[R]: (Optional) Prints all flags supported by the VM -(BOOLEAN, false). -.RE -.TP \f[V]VM.metaspace\f[R] [\f[I]options\f[R]] Prints the statistics for the metaspace .RS @@ -1025,6 +1148,10 @@ classes for each loader. space. (BOOLEAN, false) .IP \[bu] 2 +\f[V]chunkfreelist\f[R]: (Optional) Shows details about global chunk +free lists (ChunkManager). +(BOOLEAN, false) +.IP \[bu] 2 \f[V]scale\f[R]: (Optional) Memory usage in which to scale. Valid values are: 1, KB, MB or GB (fixed scale) or \[dq]dynamic\[dq] for a dynamically chosen scale. @@ -1032,7 +1159,7 @@ a dynamically chosen scale. .RE .TP \f[V]VM.native_memory\f[R] [\f[I]options\f[R]] -Prints native memory usage +Print native memory usage .RS .PP Impact: Medium @@ -1074,16 +1201,8 @@ purpose. (STRING, KB) .RE .TP -\f[V]VM.print_touched_methods\f[R] -Prints all methods that have ever been touched during the lifetime of -this JVM. -.RS -.PP -Impact: Medium --- depends on Java content. -.RE -.TP \f[V]VM.set_flag\f[R] [\f[I]arguments\f[R]] -Sets the VM flag option by using the provided value. +Sets VM flag option using the provided value. .RS .PP Impact: Low @@ -1098,7 +1217,7 @@ no default value) .RE .TP \f[V]VM.stringtable\f[R] [\f[I]options\f[R]] -Dumps the string table. +Dump string table. .RS .PP Impact: Medium --- depends on the Java content. @@ -1115,7 +1234,7 @@ table (BOOLEAN, false) .RE .TP \f[V]VM.symboltable\f[R] [\f[I]options\f[R]] -Dumps the symbol table. +Dump symbol table. .RS .PP Impact: Medium --- depends on the Java content. @@ -1131,6 +1250,13 @@ The following \f[I]options\f[R] must be specified using either table (BOOLEAN, false) .RE .TP +\f[V]VM.system_properties\f[R] +Print system properties. +.RS +.PP +Impact: Low +.RE +.TP \f[V]VM.systemdictionary\f[R] Prints the statistics for dictionary hashtable sizes and bucket length. .RS @@ -1148,15 +1274,8 @@ The following \f[I]options\f[R] must be specified using either for all class loaders (BOOLEAN, false) . .RE .TP -\f[V]VM.system_properties\f[R] -Prints the system properties. -.RS -.PP -Impact: Low -.RE -.TP \f[V]VM.uptime\f[R] [\f[I]options\f[R]] -Prints the VM uptime. +Print VM uptime. .RS .PP Impact: Low @@ -1173,7 +1292,7 @@ The following \f[I]options\f[R] must be specified using either .RE .TP \f[V]VM.version\f[R] -Prints JVM version information. +Print JVM version information. .RS .PP Impact: Low diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.c b/src/jdk.jdwp.agent/share/native/libjdwp/util.c index 6ac15d3de6e78..0bb7c8837d851 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -1073,23 +1073,6 @@ debugMonitorWait(jrawMonitorID monitor) } } -void -debugMonitorTimedWait(jrawMonitorID monitor, jlong millis) -{ - jvmtiError error; - error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait) - (gdata->jvmti, monitor, millis); - if (error == JVMTI_ERROR_INTERRUPT) { - /* See comment above */ - handleInterrupt(); - error = JVMTI_ERROR_NONE; - } - error = ignore_vm_death(error); - if (error != JVMTI_ERROR_NONE) { - EXIT_ERROR(error, "on raw monitor timed wait"); - } -} - void debugMonitorNotify(jrawMonitorID monitor) { diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.h b/src/jdk.jdwp.agent/share/native/libjdwp/util.h index 7e3ff7047e93c..c5b8a2b5f519a 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.h +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -354,7 +354,6 @@ jrawMonitorID debugMonitorCreate(char *name); void debugMonitorEnter(jrawMonitorID theLock); void debugMonitorExit(jrawMonitorID theLock); void debugMonitorWait(jrawMonitorID theLock); -void debugMonitorTimedWait(jrawMonitorID theLock, jlong millis); void debugMonitorNotify(jrawMonitorID theLock); void debugMonitorNotifyAll(jrawMonitorID theLock); void debugMonitorDestroy(jrawMonitorID theLock); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java index 141cf1a932b06..8d51cb1de6f17 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java @@ -63,11 +63,7 @@ private void groupTasksIntoBatches(List tasks) { } for (PeriodicTask task : activeSortedTasks(tasks)) { if (task.isSchedulable()) { - Batch batch = task.getBatch(); - // If new task, or period has changed, find new batch - if (batch == null) { - batch = findBatch(task.getPeriod()); - } + Batch batch = findBatch(task.getPeriod(), task.getBatch()); batch.add(task); } } @@ -89,7 +85,7 @@ private List activeSortedTasks(List unsorted) { return tasks; } - private Batch findBatch(long period) { + private Batch findBatch(long period, Batch oldBatch) { // All events with a period less than 1000 ms // get their own unique batch. The rationale for // this is to avoid a scenario where a user (mistakenly) specifies @@ -102,7 +98,7 @@ private Batch findBatch(long period) { return batch; } } - Batch batch = new Batch(period); + Batch batch = oldBatch != null ? oldBatch : new Batch(period); batches.add(batch); return batch; } diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 6f165ec1144b6..1924ccd11f86b 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -2573,7 +2573,10 @@ private void initDataPos() throws IOException { pos = -pos + locpos; byte[] buf = new byte[LOCHDR]; if (readNBytesAt(buf, 0, buf.length, pos) != LOCHDR) { - throw new ZipException("invalid loc " + pos + " for entry reading"); + throw new ZipException("invalid LOC " + pos + " for entry reading"); + } + if (LOCSIG(buf) != LOCSIG) { + throw new ZipException("invalid LOC header (bad signature)"); } pos += LOCHDR + LOCNAM(buf) + LOCEXT(buf); } diff --git a/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp b/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp index e07e073974fce..752aef02d5a52 100644 --- a/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp +++ b/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp @@ -239,7 +239,7 @@ static void run_test(BufferNode::Allocator* allocator, CompletedList* cbl) { } TEST_VM(BufferNodeAllocatorTest, stress_free_list_allocator) { - const size_t buffer_capacity = DEFAULT_CACHE_LINE_SIZE / sizeof(void*); + const size_t buffer_capacity = DEFAULT_PADDING_SIZE / sizeof(void*); BufferNode::Allocator allocator("Test Allocator", buffer_capacity); CompletedList completed; run_test(&allocator, &completed); diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 6e01458b34897..484aad97b8c12 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 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 @@ -72,8 +72,6 @@ compiler/vectorapi/VectorLogicalOpIdentityTest.java 8302459 linux-x64,windows-x6 compiler/jvmci/TestUncaughtErrorInCompileMethod.java 8309073 generic-all -compiler/codecache/CheckLargePages.java 8319795 linux-x64 - compiler/floatingpoint/TestSubnormalFloat.java 8317810 generic-i586 compiler/floatingpoint/TestSubnormalDouble.java 8317810 generic-i586 @@ -85,6 +83,11 @@ gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all +gc/TestAllocHumongousFragment.java#adaptive 8298781 generic-all +gc/TestAllocHumongousFragment.java#aggressive 8298781 generic-all +gc/TestAllocHumongousFragment.java#iu-aggressive 8298781 generic-all +gc/TestAllocHumongousFragment.java#g1 8298781 generic-all +gc/TestAllocHumongousFragment.java#static 8298781 generic-all gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all gc/stress/gclocker/TestGCLockerWithSerial.java 8180622 generic-all @@ -104,6 +107,7 @@ runtime/os/TestTracePageSizes.java#G1 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#Parallel 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#Serial 8267460 linux-aarch64 runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433 macosx-x64 +runtime/CompressedOops/CompressedClassPointers.java 8322943 aix-ppc64 runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/ErrorHandling/TestDwarf.java#checkDecoder 8305489 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le @@ -137,6 +141,8 @@ serviceability/attach/ConcAttachTest.java 8290043 linux-all serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStressTest.java 8315980 linux-all,windows-x64 +serviceability/HeapDump/FullGCHeapDumpLimitTest.java 8322989 generic-all + ############################################################################# # :hotspot_misc diff --git a/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java b/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java index ff639a69bd937..3944b78bc2764 100644 --- a/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java +++ b/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java @@ -57,6 +57,17 @@ * */ +/** + * @test + * @bug 8322781 + * @requires vm.debug + * @summary Test flag with c1 value numbering + * + * @run main/othervm -XX:+PrintValueNumbering -XX:+Verbose -XX:-UseLocalValueNumbering + * -Xcomp -XX:TieredStopAtLevel=1 + * compiler.arguments.TestC1Globals + */ + package compiler.arguments; public class TestC1Globals { diff --git a/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java b/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java index c417cc6624884..47025572428ca 100644 --- a/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java +++ b/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java @@ -48,7 +48,7 @@ public static void main(String args[]) throws Throwable { } static void checkCompileThresholdScaling(double value, boolean fail) throws Throwable { - OutputAnalyzer out = ProcessTools.executeTestJvm("-XX:CompileThresholdScaling=" + value, "--version"); + OutputAnalyzer out = ProcessTools.executeTestJava("-XX:CompileThresholdScaling=" + value, "--version"); out.shouldHaveExitValue(0); String output = out.getOutput(); diff --git a/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java b/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java index 854ccd907c98f..3d62aa4d2717a 100644 --- a/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java +++ b/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws Exception { options.add("-XX:+PrintC1Statistics"); options.add("--version"); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.shouldHaveExitValue(0).shouldContain("C1 Runtime statistics"); } diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java index 8fc1fa0580ddd..9975fd7511c86 100644 --- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java +++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java @@ -44,7 +44,7 @@ public void run() throws Throwable { } private List executeApplication() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( "-Xbatch", "-XX:-TieredCompilation", "-XX:+PrintCompilation", diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index 6ad45edd26b3a..dcb8dff8f7d37 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -105,9 +105,9 @@ static void test(int i) { static { try { - CLIENT_VM_AVAILABLE = ProcessTools.executeTestJvm(CLIENT_VM_OPTION, VERSION_OPTION) + CLIENT_VM_AVAILABLE = ProcessTools.executeTestJava(CLIENT_VM_OPTION, VERSION_OPTION) .getOutput().contains("Client"); - SERVER_VM_AVAILABLE = ProcessTools.executeTestJvm(SERVER_VM_OPTION, VERSION_OPTION) + SERVER_VM_AVAILABLE = ProcessTools.executeTestJava(SERVER_VM_OPTION, VERSION_OPTION) .getOutput().contains("Server"); } catch(Throwable t) { throw new Error("Initialization failed: " + t, t); diff --git a/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java b/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java index 5b6274681f799..ee37b7a5164d4 100644 --- a/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java +++ b/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java @@ -44,35 +44,83 @@ import java.util.List; public class CheckLargePages { - private final static WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private final static long LP_1G = 1024 * 1024 * 1024; + private final static boolean LARGE_PAGES_ENABLED; + private final static long LARGE_PAGE_SIZE; + static { + WhiteBox whiteBox = WhiteBox.getWhiteBox(); + LARGE_PAGES_ENABLED = whiteBox.getBooleanVMFlag("UseLargePages"); + LARGE_PAGE_SIZE = (whiteBox.getBooleanVMFlag("UseLargePages")) ? whiteBox.getVMLargePageSize() : 0; + } + + private static boolean isLargePageSizeEqual(long size) { + return LARGE_PAGE_SIZE == size; + } + + private static void testSegmented2GbCodeCacheWith1GbPage() throws Exception { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:+UseLargePages", + "-XX:+SegmentedCodeCache", + "-XX:InitialCodeCacheSize=2g", + "-XX:ReservedCodeCacheSize=2g", + "-XX:LargePageSizeInBytes=1g", + "-Xlog:pagesize=info", + "-version"); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + out.shouldMatch("Code cache size too small for \\S* pages\\. Reverting to smaller page size \\((\\S*)\\)\\."); + out.shouldHaveExitValue(0); + // Parse page sizes to find next biggest page + String sizes = out.firstMatch("Usable page sizes:([^.]+)", 1); + List sizeList = Arrays.stream(sizes.trim().split("\\s*,\\s*")).map(CheckLargePages::parseMemoryString) + .sorted().toList(); + final int smallerPageSizeIndex = sizeList.indexOf(LARGE_PAGE_SIZE) - 1; + Asserts.assertGreaterThanOrEqual(smallerPageSizeIndex, 0); + final long smallerPageSize = sizeList.get(smallerPageSizeIndex); + // Retrieve reverted page size from code cache warning + String revertedSizeString = out.firstMatch( + "Code cache size too small for (\\S*) pages. Reverting to smaller page size \\((\\S*)\\)\\.", 2); + Asserts.assertEquals(parseMemoryString(revertedSizeString), smallerPageSize); + } + + private static void testDefaultCodeCacheWith1GbLargePages() throws Exception { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:+UseLargePages", + "-XX:LargePageSizeInBytes=1g", + "-XX:+PrintCodeCache", + "-version"); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + out.shouldHaveExitValue(0); + out.shouldContain("CodeHeap 'non-nmethods'"); + out.shouldContain("CodeHeap 'profiled nmethods'"); + out.shouldContain("CodeHeap 'non-profiled nmethods'"); + } + + private static void testNonSegmented1GbCodeCacheWith1GbLargePages() throws Exception { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:+UseLargePages", + "-XX:LargePageSizeInBytes=1g", + "-XX:ReservedCodeCacheSize=1g", + "-XX:InitialCodeCacheSize=1g", + "-XX:+PrintCodeCache", + "-Xlog:pagesize=info", + "-version"); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + out.shouldHaveExitValue(0); + out.shouldNotContain("CodeHeap 'non-nmethods'"); + out.shouldNotContain("CodeHeap 'profiled nmethods'"); + out.shouldNotContain("CodeHeap 'non-profiled nmethods'"); + out.shouldContain("UseLargePages=1, UseTransparentHugePages=0"); + out.shouldMatch("CodeCache: min=1[gG] max=1[gG] base=[^ ]+ size=1[gG] page_size=1[gG]"); + } public static void main(String[] args) throws Exception { - final boolean largePages = WHITE_BOX.getBooleanVMFlag("UseLargePages"); - final long largePageSize = WHITE_BOX.getVMLargePageSize(); - if (largePages && (largePageSize == 1024 * 1024 * 1024)) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseLargePages", - "-XX:+SegmentedCodeCache", - "-XX:InitialCodeCacheSize=2g", - "-XX:ReservedCodeCacheSize=2g", - "-XX:LargePageSizeInBytes=1g", - "-Xlog:pagesize=info", - "-version"); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); - out.shouldMatch("Code cache size too small for \\S* pages\\. Reverting to smaller page size \\((\\S*)\\)\\."); - out.shouldHaveExitValue(0); - // Parse page sizes to find next biggest page - String sizes = out.firstMatch("Usable page sizes:([^.]+)", 1); - List sizeList = Arrays.stream(sizes.trim().split("\\s*,\\s*")).map(CheckLargePages::parseMemoryString).sorted().toList(); - final int smallerPageSizeIndex = sizeList.indexOf(largePageSize) - 1; - Asserts.assertGreaterThanOrEqual(smallerPageSizeIndex, 0); - final long smallerPageSize = sizeList.get(smallerPageSizeIndex); - // Retrieve reverted page size from code cache warning - String revertedSizeString = out.firstMatch("Code cache size too small for (\\S*) pages. Reverting to smaller page size \\((\\S*)\\)\\.", 2); - Asserts.assertEquals(parseMemoryString(revertedSizeString), smallerPageSize); + if (isLargePageSizeEqual(LP_1G)) { + testSegmented2GbCodeCacheWith1GbPage(); + testDefaultCodeCacheWith1GbLargePages(); + testNonSegmented1GbCodeCacheWith1GbLargePages(); } else { - System.out.println("1GB large pages not supported: UseLargePages=" + largePages + - (largePages ? ", largePageSize=" + largePageSize : "") + ". Skipping"); + System.out.println("1GB large pages not supported: UseLargePages=" + LARGE_PAGES_ENABLED + + (LARGE_PAGES_ENABLED ? ", largePageSize=" + LARGE_PAGE_SIZE : "") + ". Skipping"); } } diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java index 5cf86794524b7..a6e16a317b038 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java @@ -39,7 +39,7 @@ public class MemLimitTest { static void do_test(String option, boolean expectSuccess, int expectedValue) throws Exception { - OutputAnalyzer output = ProcessTools.executeTestJvm("-Xmx64m", "-XX:CompileCommand=" + option, "-version"); + OutputAnalyzer output = ProcessTools.executeTestJava("-Xmx64m", "-XX:CompileCommand=" + option, "-version"); if (expectSuccess) { output.shouldHaveExitValue(0); output.shouldNotContain("error occurred"); diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java index 2b6208652d372..e54ce7592e195 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java @@ -38,22 +38,22 @@ public class MemStatTest { public static void main(String[] args) throws Exception { // default => collect - ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*", "-version") .shouldHaveExitValue(0) .shouldNotContain("CompileCommand: An error occurred during parsing") .shouldContain("CompileCommand: MemStat *.* uintx MemStat = 1"); // should be registered // collect explicit - ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*,collect", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*,collect", "-version") .shouldHaveExitValue(0) .shouldNotContain("CompileCommand: An error occurred during parsing") .shouldContain("CompileCommand: MemStat *.* uintx MemStat = 1"); // should be registered // print explicit - ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*,print", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*,print", "-version") .shouldHaveExitValue(0) .shouldNotContain("CompileCommand: An error occurred during parsing") .shouldContain("CompileCommand: MemStat *.* uintx MemStat = 2"); // invalid suboption - ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*,invalid", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*,invalid", "-version") .shouldNotHaveExitValue(0) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Value cannot be read for option 'MemStat'") diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java index 171caf685e202..7e9878f32b255 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java @@ -37,13 +37,13 @@ public class OptionTest { public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_getClass", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_getClass", "-version") .shouldHaveExitValue(1) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Did not specify any method name") .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_getClass", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_getClass", "-version") .shouldHaveExitValue(1) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Did not specify any method name") @@ -51,36 +51,36 @@ public static void main(String[] args) throws Exception { // corner case: // ccstrlist could be a valid method name, so it is accepted in the well-formed case. - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_getClass", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_getClass", "-version") .shouldContain("CompileCommand: ControlIntrinsic *.ccstrlist const char* ControlIntrinsic") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_getClass", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_getClass", "-version") .shouldContain("CompileCommand: ControlIntrinsic *.* const char* ControlIntrinsic") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,class,PrintIntrinsics", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,class,PrintIntrinsics", "-version") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); // corner case: // PrintIntrinsics could be a valid method name, so it is accepted in the well-formed case. - ProcessTools.executeTestJvm("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version") .shouldContain("CompileCommand: PrintIntrinsics class.PrintIntrinsics bool PrintIntrinsics = true") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); // corner case: // _dontinline_* is a valid method pattern, so it should be accepted - ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*::dontinline_*", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*::dontinline_*", "-version") .shouldContain("CompileCommand: dontinline *.dontinline_* bool dontinline = true") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*.dontinline", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*.dontinline", "-version") .shouldContain("CompileCommand: dontinline *.dontinline bool dontinline = true") .shouldHaveExitValue(0) .shouldNotContain("Error: Did not specify any method name") diff --git a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java index 6db9a99586296..d337266dd50d9 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java @@ -121,7 +121,7 @@ private static List getRandomDescriptors( protected static OutputAnalyzer execute(String fileName) { OutputAnalyzer output; try { - output = ProcessTools.executeTestJvm( + output = ProcessTools.executeTestJava( "-XX:+UnlockDiagnosticVMOptions", "-XX:CompilerDirectivesLimit=1000", "-XX:CompilerDirectivesFile=" + fileName, diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java index 0111d1e90a1f6..799fabf95090c 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java @@ -101,7 +101,7 @@ public List execute() { vmInputArgs.length + vmOptions.size()); System.arraycopy(vmOptions.toArray(), 0, cmds, vmInputArgs.length, vmOptions.size()); - output = ProcessTools.executeTestJvm(cmds); + output = ProcessTools.executeTestJava(cmds); } catch (Throwable thr) { throw new Error("Execution failed: " + thr.getMessage(), thr); } diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java index 4c56daebfb888..ac3a6d9a8c6b1 100644 --- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java @@ -72,7 +72,7 @@ private boolean isTieredLevelGreaterThan(int level) { * @throws Throwable */ private void testUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, true))); final String errorMessage = "Case testUseAES failed"; @@ -103,7 +103,7 @@ private void testUseAES() throws Throwable { */ private void testUseAESUseSSE2() throws Throwable { if (Platform.isX86() || Platform.isX64()) { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES_INTRINSICS, true), prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2))); @@ -132,7 +132,7 @@ private void testUseAESUseSSE2() throws Throwable { */ private void testNoUseAESUseSSE2() throws Throwable { if (Platform.isX86() || Platform.isX64()) { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, false), prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2))); @@ -158,7 +158,7 @@ private void testNoUseAESUseSSE2() throws Throwable { * @throws Throwable */ private void testNoUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, false))); final String errorMessage = "Case testNoUseAES failed"; @@ -180,7 +180,7 @@ private void testNoUseAES() throws Throwable { * @throws Throwable */ private void testNoUseAESIntrinsic() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES_INTRINSICS, false))); final String errorMessage = "Case testNoUseAESIntrinsic failed"; diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java index 03016ea3dd6ac..fdc8f63f9e0f4 100644 --- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java @@ -65,7 +65,7 @@ protected void runTestCases() throws Throwable { * @throws Throwable */ private void testUseAESIntrinsics() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( AESIntrinsicsBase.prepareArguments(prepareBooleanFlag( AESIntrinsicsBase.USE_AES_INTRINSICS, true))); final String errorMessage = "Case testUseAESIntrinsics failed"; @@ -89,7 +89,7 @@ private void testUseAESIntrinsics() throws Throwable { * @throws Throwable */ private void testUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( AESIntrinsicsBase.prepareArguments(prepareBooleanFlag (AESIntrinsicsBase.USE_AES, true))); final String errorMessage = "Case testUseAES failed"; diff --git a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java index bbd518c67565f..3678691b21860 100644 --- a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java +++ b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java @@ -43,7 +43,7 @@ public class TestMembarDependencies { public static void main(String args[]) throws Exception { if (args.length == 0) { // For debugging, add "-XX:+TraceOptoPipelining" - OutputAnalyzer oa = ProcessTools.executeTestJvm("-XX:+IgnoreUnrecognizedVMOptions", + OutputAnalyzer oa = ProcessTools.executeTestJava("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-TieredCompilation", "-XX:-BackgroundCompilation", "-XX:+PrintOpto", "-XX:CompileCommand=compileonly,compiler.membars.TestMembarDependencies::test*", "-XX:CompileCommand=dontinline,compiler.membars.TestMembarDependencies::test_m1", diff --git a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java index 5d2651c328541..0d3c9569c3379 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java +++ b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -46,10 +46,13 @@ import java.util.Base64; import java.util.Base64.Decoder; import java.util.Base64.Encoder; +import java.util.HexFormat; import java.util.Objects; import java.util.Random; import java.util.Arrays; +import static java.lang.String.format; + import compiler.whitebox.CompilerWhiteBoxTest; import jdk.test.whitebox.code.Compiler; import jtreg.SkippedException; @@ -69,6 +72,8 @@ public static void main(String[] args) throws Exception { warmup(); + length_checks(); + test0(FileType.ASCII, Base64Type.BASIC, Base64.getEncoder(), Base64.getDecoder(),"plain.txt", "baseEncode.txt", iters); test0(FileType.ASCII, Base64Type.URLSAFE, Base64.getUrlEncoder(), Base64.getUrlDecoder(),"plain.txt", "urlEncode.txt", iters); test0(FileType.ASCII, Base64Type.MIME, Base64.getMimeEncoder(), Base64.getMimeDecoder(),"plain.txt", "mimeEncode.txt", iters); @@ -302,4 +307,118 @@ private static final byte getBadBase64Char(Base64Type b64Type) { throw new InternalError("Internal test error: getBadBase64Char called with unknown Base64Type value"); } } + + static final int POSITIONS = 30_000; + static final int BASE_LENGTH = 256; + static final HexFormat HEX_FORMAT = HexFormat.of().withUpperCase().withDelimiter(" "); + + static int[] plainOffsets = new int[POSITIONS + 1]; + static byte[] plainBytes; + static int[] base64Offsets = new int[POSITIONS + 1]; + static byte[] base64Bytes; + + static { + // Set up ByteBuffer with characters to be encoded + int plainLength = 0; + for (int i = 0; i < plainOffsets.length; i++) { + plainOffsets[i] = plainLength; + int positionLength = (BASE_LENGTH + i) % 2048; + plainLength += positionLength; + } + // Put one of each possible byte value into ByteBuffer + plainBytes = new byte[plainLength]; + for (int i = 0; i < plainBytes.length; i++) { + plainBytes[i] = (byte) i; + } + + // Grab various slices of the ByteBuffer and encode them + ByteBuffer plainBuffer = ByteBuffer.wrap(plainBytes); + int base64Length = 0; + for (int i = 0; i < POSITIONS; i++) { + base64Offsets[i] = base64Length; + int offset = plainOffsets[i]; + int length = plainOffsets[i + 1] - offset; + ByteBuffer plainSlice = plainBuffer.slice(offset, length); + base64Length += Base64.getEncoder().encode(plainSlice).remaining(); + } + + // Decode the slices created above and ensure lengths match + base64Offsets[base64Offsets.length - 1] = base64Length; + base64Bytes = new byte[base64Length]; + for (int i = 0; i < POSITIONS; i++) { + int plainOffset = plainOffsets[i]; + ByteBuffer plainSlice = plainBuffer.slice(plainOffset, plainOffsets[i + 1] - plainOffset); + ByteBuffer encodedBytes = Base64.getEncoder().encode(plainSlice); + int base64Offset = base64Offsets[i]; + int expectedLength = base64Offsets[i + 1] - base64Offset; + if (expectedLength != encodedBytes.remaining()) { + throw new IllegalStateException(format("Unexpected length: %s <> %s", encodedBytes.remaining(), expectedLength)); + } + encodedBytes.get(base64Bytes, base64Offset, expectedLength); + } + } + + public static void length_checks() { + decodeAndCheck(); + encodeDecode(); + System.out.println("Test complete, no invalid decodes detected"); + } + + // Use ByteBuffer to cause decode() to use the base + offset form of decode + // Checks for bug reported in JDK-8321599 where padding characters appear + // within the beginning of the ByteBuffer *before* the offset. This caused + // the decoded string length to be off by 1 or 2 bytes. + static void decodeAndCheck() { + for (int i = 0; i < POSITIONS; i++) { + ByteBuffer encodedBytes = base64BytesAtPosition(i); + ByteBuffer decodedBytes = Base64.getDecoder().decode(encodedBytes); + + if (!decodedBytes.equals(plainBytesAtPosition(i))) { + String base64String = base64StringAtPosition(i); + String plainHexString = plainHexStringAtPosition(i); + String decodedHexString = HEX_FORMAT.formatHex(decodedBytes.array(), decodedBytes.arrayOffset() + decodedBytes.position(), decodedBytes.arrayOffset() + decodedBytes.limit()); + throw new IllegalStateException(format("Mismatch for %s\n\nExpected:\n%s\n\nActual:\n%s", base64String, plainHexString, decodedHexString)); + } + } + } + + // Encode strings of lengths 1-1K, decode, and ensure length and contents correct. + // This checks that padding characters are properly handled by decode. + static void encodeDecode() { + String allAs = "A(=)".repeat(128); + for (int i = 1; i <= 512; i++) { + String encStr = Base64.getEncoder().encodeToString(allAs.substring(0, i).getBytes()); + String decStr = new String(Base64.getDecoder().decode(encStr)); + + if ((decStr.length() != allAs.substring(0, i).length()) || + (!Objects.equals(decStr, allAs.substring(0, i))) + ) { + throw new IllegalStateException(format("Mismatch: Expected: %s\n Actual: %s\n", allAs.substring(0, i), decStr)); + } + } + } + + static ByteBuffer plainBytesAtPosition(int position) { + int offset = plainOffsets[position]; + int length = plainOffsets[position + 1] - offset; + return ByteBuffer.wrap(plainBytes, offset, length); + } + + static String plainHexStringAtPosition(int position) { + int offset = plainOffsets[position]; + int length = plainOffsets[position + 1] - offset; + return HEX_FORMAT.formatHex(plainBytes, offset, offset + length); + } + + static String base64StringAtPosition(int position) { + int offset = base64Offsets[position]; + int length = base64Offsets[position + 1] - offset; + return new String(base64Bytes, offset, length, StandardCharsets.UTF_8); + } + + static ByteBuffer base64BytesAtPosition(int position) { + int offset = base64Offsets[position]; + int length = base64Offsets[position + 1] - offset; + return ByteBuffer.wrap(base64Bytes, offset, length); + } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java index 4060bacbfbaf9..159e471e3fcef 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java +++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java @@ -146,7 +146,7 @@ public static OutputAnalyzer runTest(Class expr, new Integer(iterations).toString() }); - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(vmOpts); + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(vmOpts); outputAnalyzer.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java index f15d4bec39840..cb362b3bbfbbf 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java @@ -112,7 +112,7 @@ private void prepareVMFlags(Class testClass, List additionalFlags) { private void start() { try { // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. - oa = ProcessTools.executeTestJvm(cmds); + oa = ProcessTools.executeTestJava(cmds); } catch (Exception e) { throw new TestRunException("Failed to execute TestFramework flag VM", e); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java index 2c63bbe95895c..04f8096d96917 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java @@ -149,7 +149,7 @@ private void start() { ProcessBuilder process = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); try { // Calls 'main' of TestVM to run all specified tests with commands 'cmds'. - // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and + // Use executeProcess instead of executeTestJava as we have already added the JTreg VM and // Java options in prepareTestVMFlags(). oa = ProcessTools.executeProcess(process); } catch (Exception e) { diff --git a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java index a971c947ff466..effbbbe46bd28 100644 --- a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java +++ b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java @@ -59,9 +59,10 @@ public static void main (String args[]) { private static void check(boolean enabled) { OutputAnalyzer oa; try { - oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", - "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", - "-XX:+WhiteBoxAPI", + oa = ProcessTools.executeTestJava( + "-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", + "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", + "-XX:+WhiteBoxAPI", "-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0", "-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod", UseCountedLoopSafepoints.class.getName()); diff --git a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java index 48bd723a13ede..9e8ac6b013a06 100644 --- a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java +++ b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java @@ -38,7 +38,7 @@ public class CheckLoopStripMining { public static void main(String args[]) throws Exception { - ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", + ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions", "-XX:+SafepointTimeout", "-XX:+SafepointALot", "-XX:+AbortVMOnSafepointTimeout", @@ -54,7 +54,7 @@ public static void main(String args[]) throws Exception { .shouldHaveExitValue(0) .stdoutShouldContain("sum: 715827882"); - ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", + ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions", "-XX:+SafepointTimeout", "-XX:+SafepointALot", "-XX:+AbortVMOnSafepointTimeout", diff --git a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java index 13e36e049d1dc..d87f68efeee41 100644 --- a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java +++ b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java @@ -81,7 +81,7 @@ private void runTest(String cmdPhases, List expectedPhases, String logFi options.add("-XX:CompileCommand=PrintIdealPhase," + getTestClass() + "::test," + cmdPhases); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); if (valid) { oa.shouldHaveExitValue(0) .shouldContain("CompileCommand: PrintIdealPhase compiler/oracle/PrintIdealPhaseTest$TestMain.test const char* PrintIdealPhase = '"+cmdPhases.replace(',', ' ')+"'") diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java b/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java index b3be2c69820c9..d9f9aa3f7d4e4 100644 --- a/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java +++ b/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java @@ -105,7 +105,7 @@ private static void test(String include, String exclude) throws Exception { } options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java b/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java index 1fb102acb07e5..358a5a0a6b35e 100644 --- a/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java +++ b/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java @@ -56,7 +56,7 @@ private static void test(String include, String exclude) throws Exception { options.add("-XX:CompileCommand=PrintCompilation," + getTestMethod(include)); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.shouldHaveExitValue(0) .shouldContain(getTestMethod(include)) diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java b/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java index 3d68f10723436..c0a99863fbf24 100644 --- a/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java +++ b/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java @@ -55,7 +55,7 @@ private static void test(String include, String exclude) throws Exception { options.add("-XX:CompileCommand=MemStat," + getTestMethod(include) + ",print"); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); // We expect two printouts for "PrintMemStat". A line at compilation time, and a line in a summary report // that is printed when we exit. Both use the typical ::name format but use / as separator and also diff --git a/test/hotspot/jtreg/compiler/print/PrintCompilation.java b/test/hotspot/jtreg/compiler/print/PrintCompilation.java index c04b2bf5206da..3b3db304cefd2 100644 --- a/test/hotspot/jtreg/compiler/print/PrintCompilation.java +++ b/test/hotspot/jtreg/compiler/print/PrintCompilation.java @@ -47,7 +47,7 @@ public static void main(String[] args) throws Exception { options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::*"); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.shouldHaveExitValue(0) .shouldContain(getTestMethod("method1")) diff --git a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java index df221959bb54d..3daf12df87989 100644 --- a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java +++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java @@ -261,7 +261,7 @@ static void run(TestConstantsInError test) throws Exception { c1Args.addAll(List.of("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1", "-XX:+TracePatching")); c1Args.addAll(commonArgs); - OutputAnalyzer outputC1 = ProcessTools.executeTestJvm(c1Args) + OutputAnalyzer outputC1 = ProcessTools.executeTestJava(c1Args) .shouldHaveExitValue(0); test.process(outputC1, true); @@ -270,7 +270,7 @@ static void run(TestConstantsInError test) throws Exception { c2Args.add("-XX:-TieredCompilation"); c2Args.addAll(commonArgs); - OutputAnalyzer outputC2 = ProcessTools.executeTestJvm(c2Args) + OutputAnalyzer outputC2 = ProcessTools.executeTestJava(c2Args) .shouldHaveExitValue(0); test.process(outputC2, false); diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java index eb25472370f92..4f9f8ca3bd22e 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java +++ b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java @@ -37,43 +37,43 @@ public class TestVectorErgonomics { public static void main(String[] args) throws Throwable { - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorReboxing=true"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorAggressiveReboxing=true"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:-EnableVectorReboxing", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:-EnableVectorReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:-EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:-EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:-EnableVectorSupport", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:-EnableVectorSupport", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:-EnableVectorSupport", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:-EnableVectorSupport", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", - "-XX:-EnableVectorSupport", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + "-XX:-EnableVectorSupport", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") diff --git a/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java b/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java index bec7c4858f5a9..edb63f88af279 100644 --- a/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java +++ b/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java @@ -45,6 +45,6 @@ private static void testInstantiationFails(String classname) throws Exception { public static void main(String[] args) throws Exception { testInstantiationFails("jdk.internal.vm.FillerObject"); - testInstantiationFails("jdk.internal.vm.FillerArray"); + testInstantiationFails("jdk.internal.vm.FillerElement"); } } diff --git a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java index a61e7545522d1..3d8f31db864d5 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java @@ -42,36 +42,36 @@ public class TestSoftMaxHeapSizeFlag { public static void main(String args[]) throws Exception { // Test default value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx) .shouldHaveExitValue(0); // Test setting small value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + Xms, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + Xms, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xms) .shouldHaveExitValue(0); // Test setting middle value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + betweenXmsAndXmx) .shouldHaveExitValue(0); // Test setting largest value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + Xmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + Xmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx) .shouldHaveExitValue(0); // Test setting a too large value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + greaterThanXmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + greaterThanXmx, + "-XX:+PrintFlagsFinal", "-version") .shouldContain("SoftMaxHeapSize must be less than or equal to the maximum heap size") .shouldHaveExitValue(1); } diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java index a93232dd82e01..a962efba4602e 100644 --- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java +++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java @@ -129,7 +129,7 @@ private static void runTest(int heapSize, int sleepTime, boolean isIhopAdaptive) } private static OutputAnalyzer executeTest(List options) throws Throwable, RuntimeException { - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); if (out.getExitValue() != 0) { System.out.println(out.getOutput()); throw new RuntimeException("AppIHOP failed with exit code" + out.getExitValue()); diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java index c84374fa359c0..7f5259a0855b3 100644 --- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java +++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java @@ -129,7 +129,7 @@ private static void runTest(int ihop, long pctToFill, long heapSize, boolean exp Collections.addAll(options, COMMON_OPTIONS); options.add(AppIHOP.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); if (out.getExitValue() != 0) { System.out.println(out.getOutput()); diff --git a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java index befa34dea65d6..eb008f04e521c 100644 --- a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java +++ b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java @@ -63,7 +63,7 @@ public static void main(String[] args) throws Throwable { } private static void startVM(List options) throws Throwable, RuntimeException { - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); out.shouldNotContain("pure virtual method called"); diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java index ecceca21f2b81..4e18e29d1550e 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java @@ -108,7 +108,7 @@ private static void runTest(int wastePct, int plabSize, int parGCThreads, int he "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB", "-XX:MaxHeapSize=" + heapSize + "m"); testOptions.add(AppPLABEvacuationFailure.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions); + OutputAnalyzer out = ProcessTools.executeTestJava(testOptions); appPlabEvacFailureOutput = out.getOutput(); if (out.getExitValue() != 0) { diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java index 785e07f8df52d..f0549623789b5 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java @@ -117,7 +117,7 @@ public static void main(String[] args) throws Throwable { testCase.print(System.out); List options = PLABUtils.prepareOptions(testCase.toOptions()); options.add(AppPLABPromotion.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); PLABUtils.commonCheck(out); output = out.getOutput(); checkResults(testCase); diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java index 0c9ebb12e8234..82246d790f457 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java @@ -87,7 +87,7 @@ public static void main(String[] args) throws Throwable { testCase.print(System.out); List options = PLABUtils.prepareOptions(testCase.toOptions()); options.add(AppPLABResize.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); PLABUtils.commonCheck(out); checkResults(out.getOutput(), testCase); } diff --git a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java index d18548abdfe18..e819501aca34a 100644 --- a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java +++ b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java @@ -169,7 +169,7 @@ public static void main(String args[]) throws Exception { finalArgs.addAll(Arrays.asList(args)); // GC and other options obtained from test framework. - OutputAnalyzer output = ProcessTools.executeTestJvm(finalArgs); + OutputAnalyzer output = ProcessTools.executeTestJava(finalArgs); output.shouldHaveExitValue(0); //System.out.println("------------- begin stdout ----------------"); //System.out.println(output.getStdout()); diff --git a/test/hotspot/jtreg/gc/x/TestHighUsage.java b/test/hotspot/jtreg/gc/x/TestHighUsage.java index 370d80318006a..32b0af19e4b79 100644 --- a/test/hotspot/jtreg/gc/x/TestHighUsage.java +++ b/test/hotspot/jtreg/gc/x/TestHighUsage.java @@ -85,15 +85,15 @@ public static void main(String[] args) throws Exception { } public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:+UseZGC", - "-XX:-ZGenerational", - "-XX:-ZProactive", - "-Xms128M", - "-Xmx128M", - "-XX:ParallelGCThreads=1", - "-XX:ConcGCThreads=1", - "-Xlog:gc,gc+start", - Test.class.getName()) + ProcessTools.executeTestJava("-XX:+UseZGC", + "-XX:-ZGenerational", + "-XX:-ZProactive", + "-Xms128M", + "-Xmx128M", + "-XX:ParallelGCThreads=1", + "-XX:ConcGCThreads=1", + "-Xlog:gc,gc+start", + Test.class.getName()) .shouldNotContain("Allocation Stall") .shouldContain("High Usage") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java index 3f26461643a6c..c32027f82b0f9 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java @@ -54,8 +54,8 @@ public static void main(String[] args) throws Throwable { // and don't terminate abruptly due to stack overflow error @Test public void testNativeExceptionReporting() throws Exception { - OutputAnalyzer output = ProcessTools.executeTestJvm( - // executeTestJvm doesn't seem to forward 'java.library.path' + OutputAnalyzer output = ProcessTools.executeTestJava( + // executeTestJava doesn't seem to forward 'java.library.path' "-Djava.library.path=" + System.getProperty("java.library.path"), Crasher.class.getName()); diff --git a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java index 356064d79a486..deb2a000d3d52 100644 --- a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java +++ b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java @@ -46,11 +46,11 @@ public static void main(String[] args) throws Exception { // Start a java process with this property set, and check that: // 1) The process failed and // 2) The error message was correct. - ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + tooLongPath, - "TestSunBootLibraryPath", - "'Do-Nothing'") - .shouldNotHaveExitValue(0) - .stdoutShouldContain(expectedErrorMessage); + ProcessTools.executeTestJava("-Dsun.boot.library.path=" + tooLongPath, + "TestSunBootLibraryPath", + "'Do-Nothing'") + .shouldNotHaveExitValue(0) + .stdoutShouldContain(expectedErrorMessage); } else if (!args[0].equals("Do-Nothing")) { // Fail, to prevent accidental args from causing accidental test passing. throw new IllegalArgumentException("Test was launched with an invalid argument."); diff --git a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java index 30b1ebe252aa8..68dc6b2e1a7e9 100644 --- a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java +++ b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java @@ -66,7 +66,7 @@ public static void main(String args[]) { private static void startVM(String... options) throws Throwable { // Combine VM flags given from command-line and your additional options - OutputAnalyzer output = ProcessTools.executeTestJvm(options); + OutputAnalyzer output = ProcessTools.executeTestJava(options); output.shouldContain("- ShutdownTest -"); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java index eecc218a71aa3..53de474d9cd41 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java @@ -306,7 +306,7 @@ public static void runWithJarPath(String... extraRuntimeArgs) throws Exception { .shouldNotContain(OPTIMIZE_ENABLED) .shouldNotContain(OPTIMIZE_DISABLED); }); - tty("10. run with CDS on, with main/test jars on classpath also with -Xbootclasspath/a: should not pass"); + tty("10. run with CDS on, with main/test jars on classpath also with -Xbootclasspath/a: should pass"); TestCommon.run("-Xlog:cds", "-cp", mainJar.toString() + PATH_SEPARATOR + testJar.toString(), "-Xbootclasspath/a:", ".", @@ -314,9 +314,51 @@ public static void runWithJarPath(String... extraRuntimeArgs) throws Exception { .assertAbnormalExit(out -> { out.shouldNotContain(CLASS_FOUND_MESSAGE) .shouldNotContain(CLASS_NOT_FOUND_MESSAGE) - .shouldContain(OPTIMIZE_DISABLED) .shouldNotContain(OPTIMIZE_ENABLED) .shouldContain(MAP_FAILED); }); + + // Dump an archive with -Xbootclasspath/a + output = TestCommon.createArchive( + testJar.toString(), + appClasses, + "-Xbootclasspath/a:" + mainJar.toString()); + TestCommon.checkDump(output); + tty("11. run with CDS on, with test jar on classpath and with main jar on -Xbootclasspath/a: should pass"); + TestCommon.run("-Xlog:cds", + "-cp", testJar.toString(), + "-Xbootclasspath/a:" + mainJar.toString(), + MAIN_CLASS) + .assertNormalExit(out -> { + out.shouldNotContain(CLASS_FOUND_MESSAGE) + .shouldNotContain(CLASS_NOT_FOUND_MESSAGE) + .shouldContain(OPTIMIZE_ENABLED); + }); + tty("12. run with CDS on, with main jar on classpath and with test jar on -Xbootclasspath/a: should not pass due to class paths mismatch"); + TestCommon.run("-Xlog:cds", + "-cp", mainJar.toString(), + "-Xbootclasspath/a:" + testJar.toString(), + MAIN_CLASS) + .assertAbnormalExit(out -> { + out.shouldNotContain(CLASS_FOUND_MESSAGE) + .shouldNotContain(CLASS_NOT_FOUND_MESSAGE) + .shouldNotContain(OPTIMIZE_ENABLED) + .shouldContain(MAP_FAILED); + }); + // Dump an archive with only -Xbootclasspath/a + output = TestCommon.createArchive( + null, + appClasses, + "-Xbootclasspath/a:" + mainJar.toString()); + TestCommon.checkDump(output); + tty("13. run with CDS on, with the same -Xbootclasspath/a as dump time and adding a -cp with test.jar: should pass"); + TestCommon.run("-Xlog:cds,class+load", + "-cp", testJar.toString(), + "-Xbootclasspath/a:" + mainJar.toString(), + MAIN_CLASS) + .assertNormalExit(out -> { + out.shouldMatch(MAIN_FROM_CDS) + .shouldContain(OPTIMIZE_ENABLED); + }); } } diff --git a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java index f7d50fd7fe6bf..71d984d3a638c 100644 --- a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java +++ b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java @@ -47,7 +47,8 @@ public String[] getTests() { // CDS should not be disabled -- these critical classes cannot be replaced because // JvmtiExport::early_class_hook_env() is false. - "-subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph", + "-subgraph java/lang/module/Configuration java.lang.module.Configuration", + "-subgraph java/lang/ModuleLayer java.lang.ModuleLayer", "-subgraph java/lang/Integer java.lang.Integer$IntegerCache", // Tests for archived full module graph. We cannot use whitebox, which requires appending to bootclasspath. diff --git a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java index 06db9c07c73da..4f59af310bf52 100644 --- a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java +++ b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java @@ -42,7 +42,7 @@ public static void main(String... args) throws Exception { Path patches = Paths.get(System.getProperty("test.classes"), "patches", "java.base"); String syspaths = System.getProperty("sun.boot.library.path") + File.pathSeparator + System.getProperty("java.library.path"); - ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + syspaths, + ProcessTools.executeTestJava("-Dsun.boot.library.path=" + syspaths, "--patch-module", "java.base=" + patches.toString(), "BootLoaderTest") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java index 4f90838c10705..7b0a4cc46bf77 100644 --- a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java +++ b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java @@ -43,10 +43,10 @@ public final class FindClassUtf8 { public static void main(String... args) throws Exception { if (args.length == 1) { // run java -Xcheck:jni FindClassUtf8 and check that the -Xcheck:jni message comes out. - ProcessTools.executeTestJvm("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "-Xcheck:jni", - "-XX:-CreateCoredumpOnCrash", - "FindClassUtf8") + ProcessTools.executeTestJava("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "-Xcheck:jni", + "-XX:-CreateCoredumpOnCrash", + "FindClassUtf8") .shouldContain("JNI class name is not a valid UTF8 string") .shouldNotHaveExitValue(0); // you get a core dump from -Xcheck:jni failures } else { diff --git a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java index a54eaedbad4b6..82d834c869cc1 100644 --- a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java +++ b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java @@ -61,13 +61,13 @@ public static void main(String[] args) throws Exception { String jlp = "-Djava.library.path=" + Utils.TEST_NATIVE_PATH; // First run will terminate via DestroyJavaVM - OutputAnalyzer output = ProcessTools.executeTestJvm(jlp, main); + OutputAnalyzer output = ProcessTools.executeTestJava(jlp, main); output.shouldNotContain("Unexpected"); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); // Second run will terminate via System.exit() - output = ProcessTools.executeTestJvm(jlp, main, "doExit"); + output = ProcessTools.executeTestJava(jlp, main, "doExit"); output.shouldNotContain("Unexpected"); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java index e731bab63744c..3c6efeb9a2ddd 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java @@ -205,9 +205,9 @@ public static void main(String[] args) throws Throwable { } // launch and check output - checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestCheckedJniExceptionCheck")); + checkOuputForCorrectWarnings(ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestCheckedJniExceptionCheck")); } } diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java index 6395e3b9f0b30..6bc09b8a03451 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java @@ -45,7 +45,7 @@ public static void main(String[] args) throws Throwable { if (args == null || args.length == 0) { test(); } else { - // Uses executeProcess() instead of executeTestJvm() to avoid passing options + // Uses executeProcess() instead of executeTestJava() to avoid passing options // that might generate output on stderr (which should be empty for this test). ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xcheck:jni", diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java index a7b8d945eecc8..d336097b8bda1 100644 --- a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java +++ b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java @@ -51,19 +51,19 @@ public class TestNativeStack { public static void main(String[] args) throws Throwable { // case 1: Trigger a JNI warning with Xcheck:jni OutputAnalyzer oa = - ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestNativeStack$Main"); + ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main"); oa.shouldHaveExitValue(0); oa.shouldContain("WARNING in native method"); oa.shouldContain("thread_start"); oa.reportDiagnosticSummary(); // Case 2: Trigger a JNI FatalError call - oa = ProcessTools.executeTestJvm("-XX:-CreateCoredumpOnCrash", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestNativeStack$Main", - "error"); + oa = ProcessTools.executeTestJava("-XX:-CreateCoredumpOnCrash", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main", + "error"); oa.shouldNotHaveExitValue(0); oa.shouldContain("FATAL ERROR in native method"); oa.shouldContain("thread_start"); diff --git a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java index e22c75a6a449b..e3d043ee4af76 100644 --- a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java +++ b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java @@ -65,17 +65,17 @@ public static void main(String[] args) throws Exception { String cp = Utils.TEST_CLASS_PATH; String libp = Utils.TEST_NATIVE_PATH; - OutputAnalyzer output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp, - Tester.class.getName()); + OutputAnalyzer output = ProcessTools.executeTestJava("-Djava.library.path=" + libp, + Tester.class.getName()); output.shouldContain(warning); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); // If we run everything from the "boot" loader there should be no warning - output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp, - "-Xbootclasspath/a:" + cp, - "-Dsun.boot.library.path=" + libp, - Tester.class.getName()); + output = ProcessTools.executeTestJava("-Djava.library.path=" + libp, + "-Xbootclasspath/a:" + cp, + "-Dsun.boot.library.path=" + libp, + Tester.class.getName()); output.shouldNotContain(warning); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java b/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java index e4ad27b46e5db..a94d9af4c27a5 100644 --- a/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java +++ b/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java @@ -350,7 +350,7 @@ public RangeWithPageSize(String start, String end, String pageSize, String thpEl this.start = Long.parseUnsignedLong(start, 16); this.end = Long.parseUnsignedLong(end, 16); this.pageSize = Long.parseLong(pageSize); - this.thpEligible = Integer.parseInt(thpEligible) == 1; + this.thpEligible = thpEligible == null ? false : (Integer.parseInt(thpEligible) == 1); vmFlagHG = false; vmFlagHT = false; @@ -365,12 +365,11 @@ public RangeWithPageSize(String start, String end, String pageSize, String thpEl } } - // When the THP policy is 'always' instead of 'madvise, the vmFlagHG property is false. - // Check the THPeligible property instead. - isTHP = !vmFlagHT && this.thpEligible; + // When the THP policy is 'always' instead of 'madvise, the vmFlagHG property is false, + // therefore also check thpEligible. If this is still causing problems in the future, + // we might have to check the AnonHugePages field. - // vmFlagHG should imply isTHP - assert !vmFlagHG || isTHP; + isTHP = vmFlagHG || this.thpEligible; } public long getPageSize() { diff --git a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java index 4c54273c8c727..a62d61166fc0b 100644 --- a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java +++ b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java @@ -58,7 +58,7 @@ public static void main(String[] args) throws Exception { subargs.addAll(List.of("-Xlog:gc,gc+start,stringtable*=trace", "-Xmx1g")); subargs.add(Tester.class.getName()); subargs.addAll(Arrays.asList(args)); - OutputAnalyzer output = ProcessTools.executeTestJvm(subargs); + OutputAnalyzer output = ProcessTools.executeTestJava(subargs); output.shouldHaveExitValue(0); checkOutput(output); } diff --git a/test/hotspot/jtreg/sanity/BasicVMTest.java b/test/hotspot/jtreg/sanity/BasicVMTest.java index a128cdfea379b..47773d63df42e 100644 --- a/test/hotspot/jtreg/sanity/BasicVMTest.java +++ b/test/hotspot/jtreg/sanity/BasicVMTest.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { "-X", "-help"); for (String flag : flags) { - ProcessTools.executeTestJvm(flag) + ProcessTools.executeTestJava(flag) .shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/serviceability/HeapDump/FullGCHeapDumpLimitTest.java b/test/hotspot/jtreg/serviceability/HeapDump/FullGCHeapDumpLimitTest.java new file mode 100644 index 0000000000000..cf5481ddf2b93 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/HeapDump/FullGCHeapDumpLimitTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, Alibaba Group Holding Limited. 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 Test of option -XX:FullGCHeapDumpLimit + * @library /test/lib + * @run main/othervm -XX:+UseSerialGC -XX:+HeapDumpBeforeFullGC -XX:+HeapDumpAfterFullGC -XX:HeapDumpPath=test.hprof -XX:FullGCHeapDumpLimit=1 FullGCHeapDumpLimitTest + */ + +import java.io.File; + +import jdk.test.lib.Asserts; + +public class FullGCHeapDumpLimitTest { + + public static void main(String[] args) throws Exception { + System.gc(); + Asserts.assertTrue(new File("test.hprof").exists()); + Asserts.assertFalse(new File("test.hprof.1").exists()); + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java index feacea07aab25..48c9ad1328e17 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java @@ -60,7 +60,7 @@ public class TestLambdaFormRetransformation { public static void main(String args[]) throws Throwable { Path agent = TestLambdaFormRetransformation.buildAgent(); - OutputAnalyzer oa = ProcessTools.executeTestJvm("-javaagent:" + + OutputAnalyzer oa = ProcessTools.executeTestJava("-javaagent:" + agent.toAbsolutePath().toString(), "-version"); oa.shouldHaveExitValue(ExitCode.OK.value); } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java index 2e36e33ce837b..4bcd2a4458872 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java @@ -79,7 +79,7 @@ private static void buildJar(String jarName) throws Throwable { } private static void launchTest() throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-javaagent:" + testClasses + "UnresolvedClassAgent.jar", "-Dtest.classes=" + testClasses, "UnresolvedClassAgent"); diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java index 17c17b9b1f5c5..4ee1d1a0bfcae 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java @@ -25,20 +25,22 @@ * @test id=default * @bug 8312498 * @summary Basic test for JVMTI GetThreadState with virtual threads + * @library /test/lib * @run junit/othervm/native GetThreadStateTest */ /* * @test id=no-vmcontinuations * @requires vm.continuations + * @library /test/lib * @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations GetThreadStateTest */ import java.util.StringJoiner; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; +import jdk.test.lib.thread.VThreadPinner; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -75,10 +77,10 @@ void testTerminated() throws Exception { */ @Test void testRunnable() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - latch.countDown(); + started.set(true); // spin until done while (!done.get()) { @@ -87,7 +89,7 @@ void testRunnable() throws Exception { }); try { // wait for thread to start execution - latch.await(); + awaitTrue(started); // thread should be runnable int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE; @@ -107,17 +109,17 @@ void testRunnable() throws Exception { */ @Test void testMonitorEnter() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); Object lock = new Object(); var thread = Thread.ofVirtual().unstarted(() -> { - latch.countDown(); + started.set(true); synchronized (lock) { } }); try { synchronized (lock) { // start thread and wait for it to start execution thread.start(); - latch.await(); + awaitTrue(started); // thread should block on monitor enter int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; @@ -137,19 +139,19 @@ void testMonitorEnter() throws Exception { */ @Test void testObjectWait() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); Object lock = new Object(); var thread = Thread.ofVirtual().start(() -> { synchronized (lock) { - latch.countDown(); + started.set(true); try { lock.wait(); } catch (InterruptedException e) { } } }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should wait int expected = JVMTI_THREAD_STATE_ALIVE | @@ -179,19 +181,19 @@ void testObjectWait() throws Exception { */ @Test void testObjectWaitMillis() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); Object lock = new Object(); var thread = Thread.ofVirtual().start(() -> { synchronized (lock) { - latch.countDown(); + started.set(true); try { lock.wait(Long.MAX_VALUE); } catch (InterruptedException e) { } } }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should wait int expected = JVMTI_THREAD_STATE_ALIVE | @@ -221,17 +223,17 @@ void testObjectWaitMillis() throws Exception { */ @Test void testPark() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - latch.countDown(); + started.set(true); while (!done.get()) { LockSupport.park(); } }); try { // wait for thread to start execution - latch.await(); + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -251,17 +253,17 @@ void testPark() throws Exception { */ @Test void testParkNanos() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - latch.countDown(); + started.set(true); while (!done.get()) { LockSupport.parkNanos(Long.MAX_VALUE); } }); try { // wait for thread to start execution - latch.await(); + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -281,20 +283,19 @@ void testParkNanos() throws Exception { */ @Test void testParkWhenPinned() throws Exception { - var latch = new CountDownLatch(1); - Object lock = new Object(); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { - latch.countDown(); + VThreadPinner.runPinned(() -> { + started.set(true); while (!done.get()) { LockSupport.park(); } - } + }); }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -314,20 +315,19 @@ void testParkWhenPinned() throws Exception { */ @Test void testParkNanosWhenPinned() throws Exception { - var latch = new CountDownLatch(1); - Object lock = new Object(); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { - latch.countDown(); + VThreadPinner.runPinned(() -> { + started.set(true); while (!done.get()) { LockSupport.parkNanos(Long.MAX_VALUE); } - } + }); }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -342,6 +342,15 @@ void testParkNanosWhenPinned() throws Exception { } } + /** + * Waits for the boolean value to become true. + */ + private static void awaitTrue(AtomicBoolean ref) throws Exception { + while (!ref.get()) { + Thread.sleep(20); + } + } + /** * Asserts that the given thread has the expected JVMTI state. */ diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java index 9d8bb71cbc503..4824569871230 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java @@ -53,7 +53,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:agentonunload001=-waittime=5", nsk.jvmti.Agent_OnUnload.agentonunload001.class.getName()); oa.shouldHaveExitValue(95); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java index 9f0281533421a..964283d2b013f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java @@ -38,13 +38,13 @@ public static void main(String[] args) throws Exception { .skip(3) .collect(Collectors.joining(" ")); - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:" + libName + "=-waittime=5 setVerboseMode=yes", className); oa.shouldHaveExitValue(95); oa.stdoutShouldContain(phrase); - oa = ProcessTools.executeTestJvm( + oa = ProcessTools.executeTestJava( "-agentlib:" + libName + "=-waittime=5 setVerboseMode=no", "-verbose:" + verboseType, className); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java index 2aae25104fece..3d474c4e14913 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java @@ -47,7 +47,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:ma02t001=-waittime=5", "-agentlib:ma02t001a=-waittime=5", nsk.jvmti.scenarios.multienv.MA02.ma02t001.class.getName()); diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDPropertiesTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDPropertiesTest.java new file mode 100644 index 0000000000000..14215004937c3 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDPropertiesTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 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. + */ + +package common.dtd; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLInputFactory; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.xml.sax.XMLReader; + +/* + * @test + * @bug 8322214 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @run testng common.dtd.DTDPropertiesTest + * @summary Verifies the getProperty function on DTD properties works the same + * as before the property 'jdk.xml.dtd.support' was introduced. + */ +public class DTDPropertiesTest { + // Xerces Property + public static final String DISALLOW_DTD = "http://apache.org/xml/features/disallow-doctype-decl"; + + /* + * DataProvider for verifying Xerces' disallow-DTD feature + * Fields: property name, setting (null indicates not specified), expected + */ + @DataProvider(name = "XercesProperty") + public Object[][] getXercesProperty() throws Exception { + return new Object[][] { + { DISALLOW_DTD, null, false}, + { DISALLOW_DTD, true, true}, + { DISALLOW_DTD, false, false}, + }; + } + + /* + * DataProvider for verifying StAX's supportDTD feature + * Fields: property name, setting (null indicates not specified), expected + */ + @DataProvider(name = "StAXProperty") + public Object[][] getStAXProperty() throws Exception { + return new Object[][] { + { XMLInputFactory.SUPPORT_DTD, null, true}, + { XMLInputFactory.SUPPORT_DTD, true, true}, + { XMLInputFactory.SUPPORT_DTD, false, false}, + }; + } + + /** + * Verifies the disallow DTD feature with SAX. + * + * @param name the name of the property + * @param setting the setting of the property, null means not specified + * @param expected the expected value + * @throws Exception if the test fails + */ + @Test(dataProvider = "XercesProperty") + public void testSAX(String name, Boolean setting, Boolean expected) throws Exception { + SAXParserFactory spf = SAXParserFactory.newDefaultInstance(); + if (setting != null) { + spf.setFeature(name, setting); + } + Assert.assertEquals((Boolean)spf.getFeature(name), expected); + System.out.println(spf.getFeature(name)); + + + SAXParser saxParser = spf.newSAXParser(); + XMLReader reader = saxParser.getXMLReader(); + Assert.assertEquals((Boolean)reader.getFeature(name), expected); + System.out.println(reader.getFeature(name)); + } + + /** + * Verifies the disallow DTD feature with DOM. + * + * @param name the name of the property + * @param setting the setting of the property, null means not specified + * @param expected the expected value + * @throws Exception if the test fails + */ + @Test(dataProvider = "XercesProperty") + public void testDOM(String name, Boolean setting, Boolean expected) throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); + if (setting != null) { + dbf.setFeature(name, setting); + } + Assert.assertEquals((Boolean)dbf.getFeature(name), expected); + System.out.println(dbf.getFeature(name)); + } + + /** + * Verifies the StAX's supportDTD feature. + * + * @param name the name of the property + * @param setting the setting of the property, null means not specified + * @param expected the expected value + * @throws Exception if the test fails + */ + @Test(dataProvider = "StAXProperty") + public void testStAX(String name, Boolean setting, Boolean expected) throws Exception { + XMLInputFactory xif = XMLInputFactory.newInstance(); + if (setting != null) { + xif.setProperty(name, setting); + } + Assert.assertEquals((Boolean)xif.getProperty(name), expected); + System.out.println((Boolean)xif.getProperty(name)); + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/stream/XMLStreamExceptionTest/ExceptionCauseTest.java b/test/jaxp/javax/xml/jaxp/unittest/stream/XMLStreamExceptionTest/ExceptionCauseTest.java new file mode 100644 index 0000000000000..e32527621f83c --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/stream/XMLStreamExceptionTest/ExceptionCauseTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023, 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 stream.XMLStreamExceptionTest; + +import java.io.IOException; + +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + +import org.testng.Assert; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +/* + * @test + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @run testng/othervm -DrunSecMngr=true -Djava.security.manager=allow stream.XMLStreamExceptionTest.ExceptionCauseTest + * @run testng/othervm stream.XMLStreamExceptionTest.ExceptionCauseTest + * @summary Test XMLStreamException constructor initializes chained exception + */ +@Listeners({jaxp.library.BasePolicy.class}) +public class ExceptionCauseTest { + + @Test + public void testExceptionCause() { + + // Create exception with cause + Throwable cause = new Throwable("cause"); + Location location = new Location() { + public int getLineNumber() { return 0; } + public int getColumnNumber() { return 0; } + public int getCharacterOffset() { return 0; } + public String getPublicId() { return null; } + public String getSystemId() { return null; } + }; + XMLStreamException e = new XMLStreamException("message", location, cause); + + // Verify cause + Assert.assertSame(e.getCause(), cause, "XMLStreamException has the wrong cause"); + } +} diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 94a020585e475..b2354126c06bd 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 diff --git a/test/jdk/com/sun/jdi/BadAgentPath.java b/test/jdk/com/sun/jdi/BadAgentPath.java index 68f28701cdc83..3ef0adadc84cf 100644 --- a/test/jdk/com/sun/jdi/BadAgentPath.java +++ b/test/jdk/com/sun/jdi/BadAgentPath.java @@ -38,7 +38,7 @@ public class BadAgentPath { public static void main(String[] args) throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm("-agentpath:/badAgent/agent", "-version"); + OutputAnalyzer output = ProcessTools.executeTestJava("-agentpath:/badAgent/agent", "-version"); output.shouldContain("Could not find agent library /badAgent/agent"); } } diff --git a/test/jdk/com/sun/jdi/DoubleAgentTest.java b/test/jdk/com/sun/jdi/DoubleAgentTest.java index 99ec6091aafea..ea2a109ed9b5f 100644 --- a/test/jdk/com/sun/jdi/DoubleAgentTest.java +++ b/test/jdk/com/sun/jdi/DoubleAgentTest.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws Throwable { String jdwpOption = "-agentlib:jdwp=transport=dt_socket" + ",server=y" + ",suspend=n" + ",address=*:0"; - OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath", + OutputAnalyzer output = ProcessTools.executeTestJava("-classpath", TEST_CLASSES, jdwpOption, // Notice jdwpOption specified twice jdwpOption, diff --git a/test/jdk/com/sun/jdi/OnJcmdTest.java b/test/jdk/com/sun/jdi/OnJcmdTest.java index 6cc417497c676..c7f93e6fb3167 100644 --- a/test/jdk/com/sun/jdi/OnJcmdTest.java +++ b/test/jdk/com/sun/jdi/OnJcmdTest.java @@ -51,12 +51,12 @@ private static String getListenerAddress() throws Exception { public static void main(String[] args) throws Throwable { // First check if we get the expected errors. - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y"); output.shouldContain("Can only use onjcmd with server=y"); output.shouldHaveExitValue(1); - output = ProcessTools.executeTestJvm( + output = ProcessTools.executeTestJava( "-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y,onthrow=a,launch=a"); output.shouldContain("Cannot combine onjcmd and launch suboptions"); output.shouldHaveExitValue(1); diff --git a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java index 98b32063c74b2..31e717a63d0d3 100644 --- a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java +++ b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java @@ -38,7 +38,7 @@ public class SuspendNoFlagTest { "test.classes", "."); public static void main(String[] args) throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath", + OutputAnalyzer output = ProcessTools.executeTestJava("-classpath", TEST_CLASSES, "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n", "HelloWorld"); diff --git a/test/jdk/com/sun/tools/attach/BasicTests.java b/test/jdk/com/sun/tools/attach/BasicTests.java index ff1849984d4db..833d7022ce893 100644 --- a/test/jdk/com/sun/tools/attach/BasicTests.java +++ b/test/jdk/com/sun/tools/attach/BasicTests.java @@ -101,7 +101,7 @@ private static void runTests(long pid) throws Throwable { testClassDir + "Agent.jar", testClassDir + "BadAgent.jar", testClassDir + "RedefineAgent.jar" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/PermissionTest.java b/test/jdk/com/sun/tools/attach/PermissionTest.java index 3a4128a94724d..bf9473b0c8c3b 100644 --- a/test/jdk/com/sun/tools/attach/PermissionTest.java +++ b/test/jdk/com/sun/tools/attach/PermissionTest.java @@ -86,7 +86,7 @@ private static void runTests(long pid) throws Throwable { "PermissionTest$TestMain", Long.toString(pid), "true" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); // Use a policy that will allow attach. @@ -98,7 +98,7 @@ private static void runTests(long pid) throws Throwable { "PermissionTest$TestMain", Long.toString(pid), "false" }; - output = ProcessTools.executeTestJvm(args); + output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/ProviderTest.java b/test/jdk/com/sun/tools/attach/ProviderTest.java index 5359d4241db03..e006bfd6b6d57 100644 --- a/test/jdk/com/sun/tools/attach/ProviderTest.java +++ b/test/jdk/com/sun/tools/attach/ProviderTest.java @@ -79,7 +79,7 @@ private static void runTests() throws Throwable { "-classpath", classpath, "ProviderTest$TestMain" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/TempDirTest.java b/test/jdk/com/sun/tools/attach/TempDirTest.java index 2d932ffcf0e87..b9ce4acb14155 100644 --- a/test/jdk/com/sun/tools/attach/TempDirTest.java +++ b/test/jdk/com/sun/tools/attach/TempDirTest.java @@ -140,7 +140,7 @@ private static void launchTests(long pid, Path clientTmpDir) throws Throwable { classpath, "TempDirTest$TestMain", Long.toString(pid) }); - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/java/io/BufferedInputStream/TransferToTrusted.java b/test/jdk/java/io/BufferedInputStream/TransferToTrusted.java new file mode 100644 index 0000000000000..c0bd7b53af819 --- /dev/null +++ b/test/jdk/java/io/BufferedInputStream/TransferToTrusted.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023, 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. + */ + +import java.io.*; +import java.util.Arrays; +import java.util.Objects; +import java.util.Random; + +/* + * @test + * @bug 8320971 + * @summary Verify BufferedInputStream.buf is used directly by + * BufferedInputStream.implTransferTo() only when its OutputStream + * parameter is trusted + * @key randomness + * @run main/othervm --add-opens=java.base/java.io=ALL-UNNAMED TransferToTrusted + */ +public class TransferToTrusted { + + private static final Random RND = new Random(System.nanoTime()); + + private static final class UntrustedOutputStream extends OutputStream { + + UntrustedOutputStream() { + super(); + } + + @Override + public void write(byte[] b, int off, int len) { + Objects.checkFromIndexSize(off, len, b.length); + byte[] tmp = new byte[len]; + RND.nextBytes(tmp); + System.arraycopy(tmp, 0, b, off, len); + } + + @Override + public void write(int b) throws IOException { + write(new byte[]{(byte) b}); + } + } + + public static void main(String[] args) throws Exception { + final int length = 128; + byte[] buf = new byte[length]; + RND.nextBytes(buf); + + var outputStreams = new OutputStream[]{ + new ByteArrayOutputStream(), + new FileOutputStream(File.createTempFile(TransferToTrusted.class.getName(), null)), + new PipedOutputStream(new PipedInputStream(length)), + new UntrustedOutputStream() + }; + + for (var out : outputStreams) { + System.err.println("out: " + out.getClass().getName()); + + var bis = new BufferedInputStream(new ByteArrayInputStream(buf.clone())); + try (out; bis) { + bis.read();//need this to fill the BIS.buf in + bis.transferTo(out); + var internalBuffer = bis.getClass().getDeclaredField("buf"); + internalBuffer.setAccessible(true); + if (!Arrays.equals(buf, Arrays.copyOf((byte[]) internalBuffer.get(bis), length))) { + throw new RuntimeException("Internal buffer was modified"); + } + } + } + } +} diff --git a/test/jdk/java/io/File/TempDirDoesNotExist.java b/test/jdk/java/io/File/TempDirDoesNotExist.java index bb59f6f9aeb72..f1c69f5865468 100644 --- a/test/jdk/java/io/File/TempDirDoesNotExist.java +++ b/test/jdk/java/io/File/TempDirDoesNotExist.java @@ -124,21 +124,21 @@ public static Stream counterSource() { @ParameterizedTest @MethodSource("tempDirSource") public void existingMessage(List options) throws Exception { - ProcessTools.executeTestJvm(options).shouldContain(WARNING) + ProcessTools.executeTestJava(options).shouldContain(WARNING) .shouldHaveExitValue(0); } @ParameterizedTest @MethodSource("noTempDirSource") public void nonexistentMessage(List options) throws Exception { - ProcessTools.executeTestJvm(options).shouldNotContain(WARNING) + ProcessTools.executeTestJava(options).shouldNotContain(WARNING) .shouldHaveExitValue(0); } @ParameterizedTest @MethodSource("counterSource") public void messageCounter(List options) throws Exception { - OutputAnalyzer originalOutput = ProcessTools.executeTestJvm(options); + OutputAnalyzer originalOutput = ProcessTools.executeTestJava(options); long count = originalOutput.asLines().stream().filter( line -> line.equalsIgnoreCase(WARNING)).count(); assertEquals(1, count, diff --git a/test/jdk/java/io/FilePermission/MergeName.java b/test/jdk/java/io/FilePermission/MergeName.java index c2eff765f2d1e..715b98512097d 100644 --- a/test/jdk/java/io/FilePermission/MergeName.java +++ b/test/jdk/java/io/FilePermission/MergeName.java @@ -81,7 +81,7 @@ private static void test(String file, String... actions) throws Exception { } content.add("};"); Files.write(Paths.get(file), content); - ProcessTools.executeTestJvm("-Djava.security.manager", + ProcessTools.executeTestJava("-Djava.security.manager", "-Djava.security.policy=" + file, "MergeName", "x", diff --git a/test/jdk/java/io/FilePermission/ReadFileOnPath.java b/test/jdk/java/io/FilePermission/ReadFileOnPath.java index acc66dac6abda..06e2c6c435ae0 100644 --- a/test/jdk/java/io/FilePermission/ReadFileOnPath.java +++ b/test/jdk/java/io/FilePermission/ReadFileOnPath.java @@ -87,7 +87,7 @@ static void test(String... args) throws Exception { cmds.addAll(List.of( "x", "modules/m", "modules/m/base", "modules/m/p/child", "-", "child", "/base", "../base")); - ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()])) + ProcessTools.executeTestJava(cmds.toArray(new String[cmds.size()])) .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/io/SequenceInputStream/TransferTo.java b/test/jdk/java/io/SequenceInputStream/TransferTo.java index a39d2c1e0136b..4c8ff71a4f3cc 100644 --- a/test/jdk/java/io/SequenceInputStream/TransferTo.java +++ b/test/jdk/java/io/SequenceInputStream/TransferTo.java @@ -24,6 +24,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.IOException; import java.io.OutputStream; import java.io.SequenceInputStream; import java.util.Arrays; @@ -39,6 +40,7 @@ import static java.lang.String.format; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertThrows; import static org.testng.Assert.assertTrue; @@ -126,6 +128,49 @@ public void testStreamContents() throws Exception { outputStreamProvider, createRandomBytes(4096, 0), 0, 4096); } + /* + * Special case: Assert subsequent input stream is read when preceding stream already was MAX_VALUE long. + * Note: Not testing actual content as it requires multiple GBs of memory and long time. + */ + @Test + public void testHugeStream() throws Exception { + InputStream is1 = repeat(0, Long.MAX_VALUE); + InputStream is2 = repeat(0, 1); + assertNotEquals(is1.available(), 0); + assertNotEquals(is2.available(), 0); + SequenceInputStream sis = new SequenceInputStream(is1, is2); + OutputStream nos = OutputStream.nullOutputStream(); + sis.transferTo(nos); + assertEquals(is1.available(), 0); + assertEquals(is2.available(), 0); + } + + /* + * Produces an input stream that returns b count times. + * Builds a dysfunctional mock that solely implements + * available() and transferTo() particually, + * but fails with any other operation. + */ + private static InputStream repeat(int b, long count) { + return new InputStream() { + private long pos; + @Override + public int available() throws IOException { + return (int) Math.min(count - pos, Integer.MAX_VALUE); + } + @Override + public int read() throws IOException { + throw new UnsupportedOperationException(); + } + @Override + public long transferTo(OutputStream os) throws IOException { + // skipping actual writing to os to spare time + pos += count; + return count; + } + }; + } + /* * Asserts that the transferred content is correct, i.e., compares the bytes * actually transferred to those expected. The position of the input and diff --git a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java index 08342caeb75d1..b25dcda7841a2 100644 --- a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java +++ b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java @@ -239,7 +239,7 @@ private void execute(String[] args, String status, String msg) throws Exception if (s.contains(" ")) { throw new RuntimeException("No spaces in args");} return !s.isEmpty(); }).toArray(String[]::new); - String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + String out = ProcessTools.executeTestJava(safeArgs).getOutput(); // Handle response. if ("PASS".equals(status) && out.contains(msg)) { System.out.println("PASS: Expected Result: " + msg); diff --git a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java index 6b2dc7b4dbfe7..36d3878fb41d5 100644 --- a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java +++ b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java @@ -61,7 +61,7 @@ public void testShutdownHooks() throws Exception { // Run in a new process in order to evaluate shutdown hook results String[] testCommand = new String[] {"-classpath", TEST_CLASSES, ShutdownHooksProcess.class.getName()}; - ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0); + ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0); String errorMsg = "File exists despite shutdown hook has been run"; assertFalse(Files.exists(TEST_FILE.toPath()), errorMsg); diff --git a/test/jdk/java/lang/ScopedValue/StressStackOverflow.java b/test/jdk/java/lang/ScopedValue/StressStackOverflow.java index a1254c7fef792..863ad189c3577 100644 --- a/test/jdk/java/lang/ScopedValue/StressStackOverflow.java +++ b/test/jdk/java/lang/ScopedValue/StressStackOverflow.java @@ -66,7 +66,7 @@ static class TestFailureException extends RuntimeException { TestFailureException(String s) { super(s); } } - static final long DURATION_IN_NANOS = Duration.ofMinutes(2).toNanos(); + static final long DURATION_IN_NANOS = Duration.ofMinutes(1).toNanos(); // Test the ScopedValue recovery mechanism for stack overflows. We implement both Callable // and Runnable interfaces. Which one gets tested depends on the constructor argument. diff --git a/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java b/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java index 2d1f3c64f60cc..d78066fb4170e 100644 --- a/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java +++ b/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java @@ -29,7 +29,7 @@ /** * @test - * @bug 8302323 + * @bug 8302323 8322512 * @summary Test StringBuffer.repeat sanity tests * @run testng/othervm -XX:-CompactStrings StringBufferRepeat * @run testng/othervm -XX:+CompactStrings StringBufferRepeat @@ -129,6 +129,19 @@ public void sanity() { expected = "\u0000\u0000\u0000\u0000\u0000\u0000\u0020\u0020\u0020\u0020\u0020\u0020\u2461\u2462\u2462\u2462\u2462\u2462\udbff\udfff\udbff\udfff\udbff\udfff\udbff\udfff\udbff\udfff\udbff\udfff"; assertEquals(expected, sb.toString()); + // toStringCache + + sb.setLength(0); + sb.toString(); + sb.repeat('*', 5); + expected = "*****"; + assertEquals(sb.toString(), expected); + sb.setLength(0); + sb.toString(); + sb.repeat("*", 5); + assertEquals(sb.toString(), expected); + + } public void exceptions() { diff --git a/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java b/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java index a94a5de3ce0d6..d1d5e72204f0f 100644 --- a/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java +++ b/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java @@ -40,7 +40,6 @@ import java.lang.management.LockInfo; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicBoolean; @@ -55,38 +54,53 @@ class CarrierThreadWaits { void testCarrierThreadWaiting() throws Exception { try (ForkJoinPool pool = new ForkJoinPool(1)) { var carrierRef = new AtomicReference(); + var vthreadRef = new AtomicReference(); + Executor scheduler = task -> { pool.submit(() -> { - carrierRef.set(Thread.currentThread()); + Thread carrier = Thread.currentThread(); + carrierRef.set(carrier); + Thread vthread = vthreadRef.get(); + + System.err.format("%s run task (%s) ...%n", carrier, vthread); task.run(); + System.err.format("%s task done (%s)%n", carrier, vthread); }); }; // start a virtual thread that spins and remains mounted until "done" - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler); - Thread vthread = builder.start(() -> { - latch.countDown(); + Thread vthread = builder.unstarted(() -> { + started.set(true); while (!done.get()) { Thread.onSpinWait(); } }); - - // wait for virtual thread to execute - latch.await(); + vthreadRef.set(vthread); + vthread.start(); try { - long carrierId = carrierRef.get().threadId(); + // wait for virtual thread to start + while (!started.get()) { + Thread.sleep(10); + } + + Thread carrier = carrierRef.get(); + + long carrierId = carrier.threadId(); long vthreadId = vthread.threadId(); // carrier thread should be on WAITING on virtual thread ThreadInfo ti = ManagementFactory.getThreadMXBean().getThreadInfo(carrierId); - assertTrue(ti.getThreadState() == Thread.State.WAITING); - assertEquals(vthread.getClass().getName(), ti.getLockInfo().getClassName()); - assertTrue(ti.getLockInfo().getIdentityHashCode() == System.identityHashCode(vthread)); - assertTrue(ti.getLockOwnerId() == vthreadId); - + Thread.State state = ti.getThreadState(); + LockInfo lockInfo = ti.getLockInfo(); + assertEquals(Thread.State.WAITING, state); + assertNotNull(lockInfo); + assertEquals(vthread.getClass().getName(), lockInfo.getClassName()); + assertEquals(System.identityHashCode(vthread), lockInfo.getIdentityHashCode()); + assertEquals(vthreadId, ti.getLockOwnerId()); } finally { done.set(true); } diff --git a/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java b/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java index 4cf7deecb3607..38760eb52a8f0 100644 --- a/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java +++ b/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java @@ -29,35 +29,34 @@ */ import java.io.IOException; -import java.nio.channels.ClosedSelectorException; -import java.nio.channels.Selector; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; public class GetStackTraceWhenRunnable { public static void main(String[] args) throws Exception { - try (Selector sel = Selector.open()) { - // start thread1 and wait for it to park - Thread thread1 = Thread.startVirtualThread(LockSupport::park); - while (thread1.getState() != Thread.State.WAITING) { - Thread.sleep(20); - } + // start thread1 and wait for it to park + Thread thread1 = Thread.startVirtualThread(LockSupport::park); + while (thread1.getState() != Thread.State.WAITING) { + Thread.sleep(20); + } - // start thread2 to pin the carrier thread - CountDownLatch latch = new CountDownLatch(1); - Thread thread2 = Thread.startVirtualThread(() -> { - latch.countDown(); - try { - sel.select(); - } catch (ClosedSelectorException e) { - // expected - } catch (IOException ioe) { - ioe.printStackTrace(); - } - }); - latch.await(); // wait for thread2 to run + // start thread2 to pin the carrier thread + var started = new AtomicBoolean(); + var done = new AtomicBoolean(); + Thread thread2 = Thread.startVirtualThread(() -> { + started.set(true); + while (!done.get()) { + Thread.onSpinWait(); + } + }); + try { + // wait for thread2 to start + while (!started.get()) { + Thread.sleep(10); + } // unpark thread1 and check that it is "stuck" in the runnable state // (the carrier thread is pinned, no other virtual thread can run) @@ -73,6 +72,10 @@ public static void main(String[] args) throws Exception { for (StackTraceElement e : stack) { System.out.println(e); } + } finally { + done.set(true); + thread2.join(); + thread1.join(); } } diff --git a/test/jdk/java/lang/Thread/virtual/JfrEvents.java b/test/jdk/java/lang/Thread/virtual/JfrEvents.java index 0cdd6a529d135..282a8959fe879 100644 --- a/test/jdk/java/lang/Thread/virtual/JfrEvents.java +++ b/test/jdk/java/lang/Thread/virtual/JfrEvents.java @@ -26,12 +26,12 @@ * @summary Basic test for JFR jdk.VirtualThreadXXX events * @requires vm.continuations * @modules jdk.jfr java.base/java.lang:+open - * @run junit/othervm JfrEvents + * @library /test/lib + * @run junit/othervm --enable-native-access=ALL-UNNAMED JfrEvents */ import java.io.IOException; import java.nio.file.Path; -import java.time.Duration; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; @@ -39,20 +39,27 @@ import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; +import java.util.function.Consumer; import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.jfr.EventType; import jdk.jfr.Recording; import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordingFile; +import jdk.test.lib.thread.VThreadPinner; +import jdk.test.lib.thread.VThreadRunner.ThrowingRunnable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.*; class JfrEvents { - private static final Object lock = new Object(); /** * Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events. @@ -85,45 +92,90 @@ void testVirtualThreadStartAndEnd() throws Exception { } } + /** + * Arguments for testVirtualThreadPinned to test jdk.VirtualThreadPinned event. + * [0] label/description + * [1] the operation to park/wait + * [2] the Thread.State when parked/waiting + * [3] the action to unpark/notify the thread + */ + static Stream pinnedCases() { + Object lock = new Object(); + + // park with native frame on stack + var finish1 = new AtomicBoolean(); + var parkWhenPinned = Arguments.of( + "LockSupport.park when pinned", + (ThrowingRunnable) () -> { + VThreadPinner.runPinned(() -> { + while (!finish1.get()) { + LockSupport.park(); + } + }); + }, + Thread.State.WAITING, + (Consumer) t -> { + finish1.set(true); + LockSupport.unpark(t); + } + ); + + // timed park with native frame on stack + var finish2 = new AtomicBoolean(); + var timedParkWhenPinned = Arguments.of( + "LockSupport.parkNanos when pinned", + (ThrowingRunnable) () -> { + VThreadPinner.runPinned(() -> { + while (!finish2.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + }); + }, + Thread.State.TIMED_WAITING, + (Consumer) t -> { + finish2.set(true); + LockSupport.unpark(t); + } + ); + + return Stream.of(parkWhenPinned, timedParkWhenPinned); + } + /** * Test jdk.VirtualThreadPinned event. */ - @Test - void testVirtualThreadPinned() throws Exception { - Runnable[] parkers = new Runnable[] { - () -> LockSupport.park(), - () -> LockSupport.parkNanos(Duration.ofDays(1).toNanos()) - }; + @ParameterizedTest + @MethodSource("pinnedCases") + void testVirtualThreadPinned(String label, + ThrowingRunnable parker, + Thread.State expectedState, + Consumer unparker) throws Exception { try (Recording recording = new Recording()) { recording.enable("jdk.VirtualThreadPinned"); recording.start(); - try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { - for (Runnable parker : parkers) { - // execute parking task in virtual thread - var threadRef = new AtomicReference(); - executor.submit(() -> { - threadRef.set(Thread.currentThread()); - synchronized (lock) { - parker.run(); // should pin carrier - } - }); - - // wait for the task to start and the virtual thread to park - Thread thread; - while ((thread = threadRef.get()) == null) { - Thread.sleep(10); - } + try { + var exception = new AtomicReference(); + var thread = Thread.ofVirtual().start(() -> { try { - Thread.State state = thread.getState(); - while (state != Thread.State.WAITING && state != Thread.State.TIMED_WAITING) { - Thread.sleep(10); - state = thread.getState(); - } - } finally { - LockSupport.unpark(thread); + parker.run(); + } catch (Throwable e) { + exception.set(e); + } + }); + try { + // wait for thread to park/wait + Thread.State state = thread.getState(); + while (state != expectedState) { + assertTrue(state != Thread.State.TERMINATED, thread.toString()); + Thread.sleep(10); + state = thread.getState(); } + } finally { + unparker.accept(thread); + thread.join(); + assertNull(exception.get()); } } finally { recording.stop(); @@ -132,9 +184,9 @@ void testVirtualThreadPinned() throws Exception { Map events = sumEvents(recording); System.err.println(events); - // should have a pinned event for each park + // should have at least one pinned event int pinnedCount = events.getOrDefault("jdk.VirtualThreadPinned", 0); - assertEquals(parkers.length, pinnedCount); + assertTrue(pinnedCount >= 1, "Expected one or more events"); } } diff --git a/test/jdk/java/lang/Thread/virtual/WaitNotify.java b/test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java similarity index 81% rename from test/jdk/java/lang/Thread/virtual/WaitNotify.java rename to test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java index bc7b36b39bec6..1320cc8f15f3f 100644 --- a/test/jdk/java/lang/Thread/virtual/WaitNotify.java +++ b/test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java @@ -24,8 +24,9 @@ /** * @test * @summary Test virtual threads using Object.wait/notifyAll + * @modules java.base/java.lang:+open * @library /test/lib - * @run junit WaitNotify + * @run junit MonitorWaitNotify */ import java.util.concurrent.Semaphore; @@ -34,7 +35,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -class WaitNotify { +class MonitorWaitNotify { /** * Test virtual thread waits, notified by platform thread. @@ -84,24 +85,31 @@ void testWaitNotify2() throws Exception { */ @Test void testWaitNotify3() throws Exception { - var lock = new Object(); - var ready = new Semaphore(0); - var thread1 = Thread.ofVirtual().start(() -> { - synchronized (lock) { - ready.release(); - try { - lock.wait(); - } catch (InterruptedException e) { } - } - }); - var thread2 = Thread.ofVirtual().start(() -> { - ready.acquireUninterruptibly(); - synchronized (lock) { - lock.notifyAll(); - } - }); - thread1.join(); - thread2.join(); + // need at least two carrier threads due to pinning + int previousParallelism = VThreadRunner.ensureParallelism(2); + try { + var lock = new Object(); + var ready = new Semaphore(0); + var thread1 = Thread.ofVirtual().start(() -> { + synchronized (lock) { + ready.release(); + try { + lock.wait(); + } catch (InterruptedException e) { } + } + }); + var thread2 = Thread.ofVirtual().start(() -> { + ready.acquireUninterruptibly(); + synchronized (lock) { + lock.notifyAll(); + } + }); + thread1.join(); + thread2.join(); + } finally { + // restore + VThreadRunner.setParallelism(previousParallelism); + } } /** diff --git a/test/jdk/java/lang/Thread/virtual/StackTraces.java b/test/jdk/java/lang/Thread/virtual/StackTraces.java index fb5c40dc4e9b4..cb1877090fecd 100644 --- a/test/jdk/java/lang/Thread/virtual/StackTraces.java +++ b/test/jdk/java/lang/Thread/virtual/StackTraces.java @@ -23,7 +23,7 @@ /** * @test - * @summary Test stack traces in exceptions and stack frames waslked by the StackWalker + * @summary Test stack traces in exceptions and stack frames walked by the StackWalker * API do not include the carrier stack frames * @requires vm.continuations * @modules java.management diff --git a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java index 3371b5bc9e755..b1ccb21910acf 100644 --- a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java +++ b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java @@ -27,7 +27,7 @@ * @summary Test Thread API with virtual threads * @modules java.base/java.lang:+open * @library /test/lib - * @run junit ThreadAPI + * @run junit/othervm --enable-native-access=ALL-UNNAMED ThreadAPI */ /* @@ -35,7 +35,8 @@ * @requires vm.continuations * @modules java.base/java.lang:+open * @library /test/lib - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations ThreadAPI + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations + * --enable-native-access=ALL-UNNAMED ThreadAPI */ import java.time.Duration; @@ -61,6 +62,7 @@ import java.nio.channels.Selector; import jdk.test.lib.thread.VThreadRunner; +import jdk.test.lib.thread.VThreadPinner; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; @@ -697,11 +699,11 @@ void testJoin32() throws Exception { void testJoin33() throws Exception { AtomicBoolean done = new AtomicBoolean(); Thread thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { + VThreadPinner.runPinned(() -> { while (!done.get()) { LockSupport.parkNanos(Duration.ofMillis(20).toNanos()); } - } + }); }); try { assertFalse(thread.join(Duration.ofMillis(100))); @@ -1078,7 +1080,7 @@ void testSetDaemon2() throws Exception { } /** - * Test Thread.yield releases thread when not pinned. + * Test Thread.yield releases carrier thread. */ @Test void testYield1() throws Exception { @@ -1106,7 +1108,7 @@ void testYield1() throws Exception { } /** - * Test Thread.yield when thread is pinned. + * Test Thread.yield when thread is pinned by native frame. */ @Test void testYield2() throws Exception { @@ -1121,10 +1123,10 @@ void testYield2() throws Exception { list.add("B"); }); child.start(); - synchronized (lock) { + VThreadPinner.runPinned(() -> { Thread.yield(); // pinned so will be a no-op list.add("A"); - } + }); try { child.join(); } catch (InterruptedException e) { } }); thread.start(); @@ -1134,7 +1136,7 @@ void testYield2() throws Exception { } /** - * Test that Thread.yield does not consume the thread's parking permit. + * Test Thread.yield does not consume the thread's parking permit. */ @Test void testYield3() throws Exception { @@ -1147,7 +1149,7 @@ void testYield3() throws Exception { } /** - * Test that Thread.yield does not make available the thread's parking permit. + * Test Thread.yield does not make available the thread's parking permit. */ @Test void testYield4() throws Exception { @@ -1348,11 +1350,9 @@ void testSleep7() throws Exception { */ @Test void testSleep8() throws Exception { - VThreadRunner.run(() -> { + VThreadPinner.runPinned(() -> { long start = millisTime(); - synchronized (lock) { - Thread.sleep(1000); - } + Thread.sleep(1000); expectDuration(start, /*min*/900, /*max*/20_000); }); } @@ -1366,9 +1366,9 @@ void testSleep9() throws Exception { Thread me = Thread.currentThread(); me.interrupt(); try { - synchronized (lock) { + VThreadPinner.runPinned(() -> { Thread.sleep(2000); - } + }); fail("sleep not interrupted"); } catch (InterruptedException e) { // expected @@ -1386,9 +1386,9 @@ void testSleep10() throws Exception { Thread t = Thread.currentThread(); scheduleInterrupt(t, 100); try { - synchronized (lock) { + VThreadPinner.runPinned(() -> { Thread.sleep(20 * 1000); - } + }); fail("sleep not interrupted"); } catch (InterruptedException e) { // interrupt status should be cleared @@ -1521,8 +1521,7 @@ void testContextClassLoader5() throws Exception { @Test void testUncaughtExceptionHandler1() throws Exception { class FooException extends RuntimeException { } - var exception = new AtomicReference(); - Thread.UncaughtExceptionHandler handler = (thread, exc) -> exception.set(exc); + var handler = new CapturingUHE(); Thread thread = Thread.ofVirtual().start(() -> { Thread me = Thread.currentThread(); assertTrue(me.getUncaughtExceptionHandler() == me.getThreadGroup()); @@ -1531,7 +1530,8 @@ class FooException extends RuntimeException { } throw new FooException(); }); thread.join(); - assertTrue(exception.get() instanceof FooException); + assertInstanceOf(FooException.class, handler.exception()); + assertEquals(thread, handler.thread()); assertNull(thread.getUncaughtExceptionHandler()); } @@ -1541,8 +1541,7 @@ class FooException extends RuntimeException { } @Test void testUncaughtExceptionHandler2() throws Exception { class FooException extends RuntimeException { } - var exception = new AtomicReference(); - Thread.UncaughtExceptionHandler handler = (thread, exc) -> exception.set(exc); + var handler = new CapturingUHE(); Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(handler); Thread thread; @@ -1553,25 +1552,61 @@ class FooException extends RuntimeException { } }); thread.join(); } finally { - Thread.setDefaultUncaughtExceptionHandler(savedHandler); + Thread.setDefaultUncaughtExceptionHandler(savedHandler); // restore } - assertTrue(exception.get() instanceof FooException); + assertInstanceOf(FooException.class, handler.exception()); + assertEquals(thread, handler.thread()); assertNull(thread.getUncaughtExceptionHandler()); } /** - * Test no UncaughtExceptionHandler set. + * Test Thread and default UncaughtExceptionHandler set. */ @Test void testUncaughtExceptionHandler3() throws Exception { class FooException extends RuntimeException { } - Thread thread = Thread.ofVirtual().start(() -> { - throw new FooException(); - }); - thread.join(); + var defaultHandler = new CapturingUHE(); + var threadHandler = new CapturingUHE(); + Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(defaultHandler); + Thread thread; + try { + thread = Thread.ofVirtual().start(() -> { + Thread me = Thread.currentThread(); + assertTrue(me.getUncaughtExceptionHandler() == me.getThreadGroup()); + me.setUncaughtExceptionHandler(threadHandler); + assertTrue(me.getUncaughtExceptionHandler() == threadHandler); + throw new FooException(); + }); + thread.join(); + } finally { + Thread.setDefaultUncaughtExceptionHandler(savedHandler); // restore + } + assertInstanceOf(FooException.class, threadHandler.exception()); + assertNull(defaultHandler.exception()); + assertEquals(thread, threadHandler.thread()); assertNull(thread.getUncaughtExceptionHandler()); } + /** + * Test no Thread or default UncaughtExceptionHandler set. + */ + @Test + void testUncaughtExceptionHandler4() throws Exception { + Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(null); + try { + class FooException extends RuntimeException { } + Thread thread = Thread.ofVirtual().start(() -> { + throw new FooException(); + }); + thread.join(); + assertNull(thread.getUncaughtExceptionHandler()); + } finally { + Thread.setDefaultUncaughtExceptionHandler(savedHandler); + } + } + /** * Test Thread::threadId and getId. */ @@ -2006,10 +2041,76 @@ void testGetStackTrace5() throws Exception { } /** - * Test Thread::getStackTrace on terminated thread. + * Test Thread::getStackTrace on timed-parked thread. */ @Test void testGetStackTrace6() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + LockSupport.parkNanos(Long.MAX_VALUE); + }); + await(thread, Thread.State.TIMED_WAITING); + try { + StackTraceElement[] stack = thread.getStackTrace(); + assertTrue(contains(stack, "LockSupport.parkNanos")); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getStackTrace on parked thread that is pinned. + */ + @Test + void testGetStackTrace7() throws Exception { + AtomicBoolean done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + VThreadPinner.runPinned(() -> { + while (!done.get()) { + LockSupport.park(); + } + }); + }); + await(thread, Thread.State.WAITING); + try { + StackTraceElement[] stack = thread.getStackTrace(); + assertTrue(contains(stack, "LockSupport.park")); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getStackTrace on timed-parked thread that is pinned. + */ + @Test + void testGetStackTrace8() throws Exception { + AtomicBoolean done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + VThreadPinner.runPinned(() -> { + while (!done.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + }); + }); + await(thread, Thread.State.TIMED_WAITING); + try { + StackTraceElement[] stack = thread.getStackTrace(); + assertTrue(contains(stack, "LockSupport.parkNanos")); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getStackTrace on terminated thread. + */ + @Test + void testGetStackTrace9() throws Exception { var thread = Thread.ofVirtual().start(() -> { }); thread.join(); StackTraceElement[] stack = thread.getStackTrace(); @@ -2176,7 +2277,7 @@ void testEnumerate1() throws Exception { ThreadGroup vgroup = Thread.currentThread().getThreadGroup(); Thread[] threads = new Thread[100]; int n = vgroup.enumerate(threads, /*recurse*/false); - assertTrue(n == 0); + assertFalse(Arrays.stream(threads, 0, n).anyMatch(Thread::isVirtual)); }); } @@ -2289,6 +2390,33 @@ void testToString4() throws Exception { assertTrue(thread.toString().contains("fred")); } + /** + * Thread.UncaughtExceptionHandler that captures the first exception thrown. + */ + private static class CapturingUHE implements Thread.UncaughtExceptionHandler { + Thread thread; + Throwable exception; + @Override + public void uncaughtException(Thread t, Throwable e) { + synchronized (this) { + if (thread == null) { + this.thread = t; + this.exception = e; + } + } + } + Thread thread() { + synchronized (this) { + return thread; + } + } + Throwable exception() { + synchronized (this) { + return exception; + } + } + } + /** * Waits for the given thread to reach a given state. */ diff --git a/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java b/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java index a4bccd47265ed..1ae73b280cb13 100644 --- a/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java +++ b/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java @@ -25,15 +25,18 @@ * @test * @summary Test parking when pinned and emitting the JFR VirtualThreadPinnedEvent throws * @modules java.base/jdk.internal.event + * @library /test/lib * @compile/module=java.base jdk/internal/event/VirtualThreadPinnedEvent.java - * @run junit VirtualThreadPinnedEventThrows + * @run junit/othervm --enable-native-access=ALL-UNNAMED VirtualThreadPinnedEventThrows */ import java.lang.ref.Reference; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; import jdk.internal.event.VirtualThreadPinnedEvent; +import jdk.test.lib.thread.VThreadPinner; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -82,29 +85,31 @@ void testVirtualThreadPinnedEventCommitThrows() throws Exception { * Test parking a virtual thread when pinned. */ private void testParkWhenPinned() throws Exception { - Object lock = new Object(); + var exception = new AtomicReference(); + var done = new AtomicBoolean(); + Thread thread = Thread.startVirtualThread(() -> { + try { + VThreadPinner.runPinned(() -> { + while (!done.get()) { + LockSupport.park(); + } + }); + } catch (Throwable e) { + exception.set(e); + } + }); try { - var completed = new AtomicBoolean(); - Thread thread = Thread.startVirtualThread(() -> { - synchronized (lock) { - LockSupport.park(); - completed.set(true); - } - }); - // wait for thread to park Thread.State state; while ((state = thread.getState()) != Thread.State.WAITING) { assertTrue(state != Thread.State.TERMINATED); Thread.sleep(10); } - - // unpark and check that thread completed without exception + } finally { + done.set(true); LockSupport.unpark(thread); thread.join(); - assertTrue(completed.get()); - } finally { - Reference.reachabilityFence(lock); } + assertNull(exception.get()); } } diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java new file mode 100644 index 0000000000000..1790ef5eeac5b --- /dev/null +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023, 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 8322818 + * @summary Stress test Thread.getStackTrace on a virtual thread that is pinned + * @requires vm.debug != true + * @run main GetStackTraceALotWhenPinned 25000 + */ + +/* + * @test + * @requires vm.debug == true + * @run main/timeout=300 GetStackTraceALotWhenPinned 10000 + */ + +import java.time.Instant; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.LockSupport; + +public class GetStackTraceALotWhenPinned { + + public static void main(String[] args) throws Exception { + var counter = new AtomicInteger(Integer.parseInt(args[0])); + + // Start a virtual thread that loops doing Thread.yield and parking while pinned. + // This loop creates the conditions for the main thread to sample the stack trace + // as it transitions from being unmounted to parking while pinned. + var thread = Thread.startVirtualThread(() -> { + boolean timed = false; + while (counter.decrementAndGet() > 0) { + Thread.yield(); + synchronized (GetStackTraceALotWhenPinned.class) { + if (timed) { + LockSupport.parkNanos(Long.MAX_VALUE); + } else { + LockSupport.park(); + } + } + timed = !timed; + } + }); + + long lastTimestamp = System.currentTimeMillis(); + while (thread.isAlive()) { + thread.getStackTrace(); + LockSupport.unpark(thread); + long currentTime = System.currentTimeMillis(); + if ((currentTime - lastTimestamp) > 500) { + System.out.format("%s %d remaining ...%n", Instant.now(), counter.get()); + lastTimestamp = currentTime; + } + } + } +} diff --git a/test/jdk/java/lang/Thread/virtual/stress/PinALot.java b/test/jdk/java/lang/Thread/virtual/stress/PinALot.java index 7bfce95b5c20a..a420ebb330e7b 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/PinALot.java +++ b/test/jdk/java/lang/Thread/virtual/stress/PinALot.java @@ -25,13 +25,15 @@ * @test * @summary Stress test timed park when pinned * @requires vm.debug != true - * @run main PinALot 500000 + * @library /test/lib + * @run main/othervm --enable-native-access=ALL-UNNAMED PinALot 500000 */ /* * @test * @requires vm.debug == true - * @run main/othervm/timeout=300 PinALot 200000 + * @library /test/lib + * @run main/othervm/timeout=300 --enable-native-access=ALL-UNNAMED PinALot 200000 */ import java.time.Duration; @@ -39,9 +41,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; -public class PinALot { +import jdk.test.lib.thread.VThreadPinner; - static final Object lock = new Object(); +public class PinALot { public static void main(String[] args) throws Exception { int iterations = 1_000_000; @@ -53,11 +55,11 @@ public static void main(String[] args) throws Exception { AtomicInteger count = new AtomicInteger(); Thread thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { + VThreadPinner.runPinned(() -> { while (count.incrementAndGet() < ITERATIONS) { LockSupport.parkNanos(1); } - } + }); }); boolean terminated; diff --git a/test/jdk/java/lang/Thread/virtual/stress/Skynet.java b/test/jdk/java/lang/Thread/virtual/stress/Skynet.java index fb4adbb25f234..ee45fc827b005 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/Skynet.java +++ b/test/jdk/java/lang/Thread/virtual/stress/Skynet.java @@ -26,7 +26,7 @@ * @summary Stress test virtual threads with a variation of the Skynet 1M benchmark * @requires vm.continuations * @requires !vm.debug | vm.gc != "Z" - * @run main/othervm/timeout=300 -Xmx1g Skynet + * @run main/othervm/timeout=300 -Xmx1500m Skynet */ /* @@ -35,7 +35,7 @@ * @requires vm.gc.ZSinglegen * @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions * -XX:+UseZGC -XX:-ZGenerational - * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1g Skynet + * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1500m Skynet */ /* @@ -44,7 +44,7 @@ * @requires vm.gc.ZGenerational * @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions * -XX:+UseZGC -XX:+ZGenerational - * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1g Skynet + * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1500m Skynet */ import java.util.concurrent.BlockingQueue; diff --git a/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java b/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java index 630a1ef88b813..de8b48ec22d98 100644 --- a/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java +++ b/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -411,9 +411,7 @@ public void testInterruptDuringSelect() throws Exception { // select(Consumer, timeout) try (Selector sel = Selector.open()) { scheduleInterrupt(Thread.currentThread(), 1, SECONDS); - long start = System.currentTimeMillis(); int n = sel.select(k -> assertTrue(false), 60*1000); - long duration = System.currentTimeMillis() - start; assertTrue(n == 0); assertTrue(Thread.currentThread().isInterrupted()); assertTrue(sel.isOpen()); diff --git a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java index 8fdd787863927..fdbe44fb03c58 100644 --- a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java +++ b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java @@ -94,7 +94,7 @@ public static void main(String args[]) throws Throwable { "-Djava.security.manager", "-Djava.security.policy=" + POL, "ExtensiblePolicyTest_orig$TestMain"}; - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); } catch (Exception ex) { System.out.println("ExtensiblePolicyWithJarTest Failed"); } diff --git a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java index c93337d73d0c3..cd06cc15691b0 100644 --- a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java +++ b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java @@ -121,7 +121,7 @@ public static void main(String args[]) throws Throwable { System.out.println("Test Case 1"); //copy policy file into current directory String[] cmd = constructCMD("first.jar", POLICY1, "false", "true"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); //test case 2, test with both.jar //setIO permission granted to code that was signed by first signer @@ -131,7 +131,7 @@ public static void main(String args[]) throws Throwable { //Expect no AccessControlException System.out.println("Test Case 2"); cmd = constructCMD("both.jar", POLICY1, "false", "false"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); //test case 3 //setIO permission granted to code that was signed by first signer @@ -141,7 +141,7 @@ public static void main(String args[]) throws Throwable { //Expect AccessControlException for setFactory permission System.out.println("Test Case 3"); cmd = constructCMD("both.jar", POLICY2, "false", "true"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); } diff --git a/test/jdk/java/security/Provider/SecurityProviderModularTest.java b/test/jdk/java/security/Provider/SecurityProviderModularTest.java index c475d59337057..5bcf9a73301a7 100644 --- a/test/jdk/java/security/Provider/SecurityProviderModularTest.java +++ b/test/jdk/java/security/Provider/SecurityProviderModularTest.java @@ -255,7 +255,7 @@ private void execute(String args, String msgKey) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + String out = ProcessTools.executeTestJava(safeArgs).getOutput(); // Handle response. if ((msgKey != null && out.contains(MSG_MAP.get(msgKey)))) { System.out.printf("PASS: Expected Result: %s.%n", diff --git a/test/jdk/java/security/Security/signedfirst/DynStatic.java b/test/jdk/java/security/Security/signedfirst/DynStatic.java index 5256564064b34..59e30de54623f 100644 --- a/test/jdk/java/security/Security/signedfirst/DynStatic.java +++ b/test/jdk/java/security/Security/signedfirst/DynStatic.java @@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception { CompilerUtils.compile(DYN_SRC, TEST_CLASSES, "-classpath", "exp.jar"); // Run the DynSignedProvFirst test program - ProcessTools.executeTestJvm("-classpath", + ProcessTools.executeTestJava("-classpath", TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", "DynSignedProvFirst") .shouldContain("test passed"); @@ -87,7 +87,7 @@ public static void main(String[] args) throws Exception { CompilerUtils.compile(STATIC_SRC, TEST_CLASSES, "-classpath", "exp.jar"); // Run the StaticSignedProvFirst test program - ProcessTools.executeTestJvm("-classpath", + ProcessTools.executeTestJava("-classpath", TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", "-Djava.security.properties=file:" + STATIC_PROPS, "StaticSignedProvFirst") diff --git a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java index 69fe8effe70aa..83c2d85f6e444 100644 --- a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java +++ b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java @@ -100,7 +100,7 @@ public static void main(String[] args) throws Throwable { testRun.add(classPath); testRun.add(TestSPISigned.class.getSimpleName()); testRun.add("run-test"); - OutputAnalyzer out = ProcessTools.executeTestJvm(testRun); + OutputAnalyzer out = ProcessTools.executeTestJava(testRun); out.shouldHaveExitValue(0); out.shouldContain("DEBUG: Getting xx language"); } diff --git a/test/jdk/java/sql/testng/test/sql/TimestampTests.java b/test/jdk/java/sql/testng/test/sql/TimestampTests.java index 7766b5a2b4c69..fefe3276d47a1 100644 --- a/test/jdk/java/sql/testng/test/sql/TimestampTests.java +++ b/test/jdk/java/sql/testng/test/sql/TimestampTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ -642,6 +642,31 @@ public void test52(long value, String ts) { assertEquals(ts1.toString(), ts, "ts1.toString() != ts"); } + @Test + public void test53() { + // The latest Instant that can be converted to a Timestamp. + Instant instant1 = Instant.ofEpochSecond(Long.MAX_VALUE / 1000, 999_999_999); + assertEquals(Timestamp.from(instant1).toInstant(), instant1); + + // One nanosecond more, and converting it gets an overflow. + Instant instant2 = instant1.plusNanos(1); + expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant2)); + + // The earliest Instant that can be converted to a Timestamp. + Instant instant3 = Instant.ofEpochSecond(Long.MIN_VALUE / 1000, 0); + assertEquals(Timestamp.from(instant3).toInstant(), instant3); + + // One nanosecond less, and converting it gets an overflow. + Instant instant4 = instant3.minusNanos(1); + expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant4)); + + // The latest possible Instant will certainly overflow. + expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MAX)); + + // The earliest possible Instant will certainly overflow. + expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MIN)); + } + /* * DataProvider used to provide Timestamps which are not valid and are used * to validate that an IllegalArgumentException will be thrown from the diff --git a/test/jdk/java/time/test/java/time/format/TestUTCParse.java b/test/jdk/java/time/test/java/time/format/TestUTCParse.java index 6da94f04f0413..c1766b4703070 100644 --- a/test/jdk/java/time/test/java/time/format/TestUTCParse.java +++ b/test/jdk/java/time/test/java/time/format/TestUTCParse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -23,7 +23,7 @@ /* * @test * @modules jdk.localedata - * @bug 8303440 8317979 + * @bug 8303440 8317979 8322647 * @summary Test parsing "UTC-XX:XX" text works correctly */ package test.java.time.format; @@ -43,8 +43,8 @@ public class TestUTCParse { static { - // Assuming CLDR's SHORT name for "America/Juneau" - // produces "UTC\u212209:00" + // Assuming CLDR's SHORT name for "America/Manaus" + // produces "UTC\u221204:00" System.setProperty("java.locale.providers", "CLDR"); } @@ -60,9 +60,9 @@ public Object[][] utcZoneIdStrings() { @Test public void testUTCShortNameRoundTrip() { var fmt = DateTimeFormatter.ofPattern("z", Locale.FRANCE); - var zdt = ZonedDateTime.of(2023, 3, 3, 0, 0, 0, 0, ZoneId.of("America/Juneau")); + var zdt = ZonedDateTime.of(2023, 3, 3, 0, 0, 0, 0, ZoneId.of("America/Manaus")); var formatted = fmt.format(zdt); - assertEquals(formatted, "UTC\u221209:00"); + assertEquals(formatted, "UTC\u221204:00"); assertEquals(fmt.parse(formatted).query(TemporalQueries.zoneId()), zdt.getZone()); } diff --git a/test/jdk/java/util/Currency/PropertiesTestRun.java b/test/jdk/java/util/Currency/PropertiesTestRun.java index 6f2ea28a90d3a..baec22f3e86f6 100644 --- a/test/jdk/java/util/Currency/PropertiesTestRun.java +++ b/test/jdk/java/util/Currency/PropertiesTestRun.java @@ -116,7 +116,7 @@ private static Stream PropertiesTestMethods() { // Launch a PropertiesTest method using the TEST JDK private static void executeTestJDKMethod(String... params) throws Throwable { - int exitStatus = ProcessTools.executeTestJvm(params).getExitValue(); + int exitStatus = ProcessTools.executeTestJava(params).getExitValue(); if (exitStatus != 0) { fail("Process started with: " + Arrays.toString(params) + " failed"); } @@ -126,7 +126,7 @@ private static void executeTestJDKMethod(String... params) throws Throwable { private static void executeWritableJDKMethod(String... params) throws Throwable { // Need to include WritableJDK javapath, TEST JDK classpath String[] allParams = new String[3+params.length+Utils.getTestJavaOpts().length]; - // We don't use executeTestJvm() because we want to point to separate JDK java path + // We don't use executeTestJava() because we want to point to separate JDK java path allParams[0] = WRITABLE_JDK_JAVA_PATH; allParams[1] = "-cp"; allParams[2] = System.getProperty("java.class.path"); diff --git a/test/jdk/java/util/Locale/UseOldISOCodesTest.java b/test/jdk/java/util/Locale/UseOldISOCodesTest.java index b38537bceca3c..01f997a743d7d 100644 --- a/test/jdk/java/util/Locale/UseOldISOCodesTest.java +++ b/test/jdk/java/util/Locale/UseOldISOCodesTest.java @@ -41,7 +41,7 @@ public class UseOldISOCodesTest { // Ensure java.locale.useOldISOCodes is only interpreted at runtime startup @Test public void staticInitializationTest() throws Exception { - ProcessTools.executeTestJvm("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner") + ProcessTools.executeTestJava("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner") .outputTo(System.out) .errorTo(System.err) .shouldHaveExitValue(0); diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION index c5483b485120a..f92096d49aafd 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION +++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION @@ -1 +1 @@ -tzdata2023c +tzdata2023d diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt index 07c5edbafee70..82bad17c55320 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt +++ b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt @@ -148,7 +148,6 @@ Link America/Puerto_Rico America/Tortola Link Pacific/Port_Moresby Antarctica/DumontDUrville Link Pacific/Auckland Antarctica/McMurdo Link Asia/Riyadh Antarctica/Syowa -Link Asia/Urumqi Antarctica/Vostok Link Europe/Berlin Arctic/Longyearbyen Link Asia/Riyadh Asia/Aden Link Asia/Qatar Asia/Bahrain diff --git a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java index 51ecae932d17b..1f772f4811aaa 100644 --- a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java +++ b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Throwable { } public static void run(String testName) throws Exception { - ProcessTools.executeTestJvm("-Djava.util.prefs.userRoot=.", testName) + ProcessTools.executeTestJava("-Djava.util.prefs.userRoot=.", testName) .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(0); diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index 08d896a124a2a..2dac7643de2a7 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -160,7 +160,7 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { } // Check java -jar - OutputAnalyzer a = ProcessTools.executeTestJvm("-jar", zipFile.getName()); + OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); a.stdoutShouldMatch("\\AMain\\Z"); a.stderrShouldMatch("\\A\\Z"); diff --git a/test/jdk/java/util/zip/ZipCoding.java b/test/jdk/java/util/zip/ZipCoding.java index 852522b9a6a58..14a0e96f17440 100644 --- a/test/jdk/java/util/zip/ZipCoding.java +++ b/test/jdk/java/util/zip/ZipCoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,111 +23,185 @@ /** * @test - * @bug 4244499 4532049 4700978 4820807 4980042 + * @bug 4244499 4532049 4700978 4820807 4980042 7009069 8322802 * @summary Test ZipInputStream, ZipOutputStream and ZipFile with non-UTF8 encoding * @modules jdk.charsets + * @run junit ZipCoding */ +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import java.io.*; import java.nio.charset.*; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.*; +import java.util.stream.Stream; import java.util.zip.*; +import static org.junit.jupiter.api.Assertions.*; + public class ZipCoding { - public static void main(String[] args) throws Exception { + // The data to write to ZIP entries in this test + private static byte[] ENTRY_DATA = "German Umlaut \u00fc in entry data" + .getBytes(StandardCharsets.ISO_8859_1); + + /** + * Provide arguments used for parameterized tests + * @return a stream of argument lists + */ + public static Stream charsetsAndNames() { + // Arguments are: Write charset, read charset, entry name, comment + return Stream.of( + // MS code page 932 for the Japanese language + Arguments.of("MS932", "MS932", + "\u4e00\u4e01", + "\uff67\uff68\uff69\uff6a\uff6b\uff6c"), - test("MS932", - "\u4e00\u4e01", "\uff67\uff68\uff69\uff6a\uff6b\uff6c"); + // Code page for the IBM PC + Arguments.of("ibm437", "ibm437", + "\u00e4\u00fc", + "German Umlaut \u00fc in comment"), - test("ibm437", - "\u00e4\u00fc", "German Umlaut \u00fc in comment"); + // UTF-8 with Japanese characters + Arguments.of("utf-8", "utf-8", + "\u4e00\u4e01", + "\uff67\uff68\uff69\uff6a\uff6b\uff6c"), - test("utf-8", - "\u4e00\u4e01", "\uff67\uff68\uff69\uff6a\uff6b\uff6c"); + // UTF-8 with characters in the Latin1 range + Arguments.of("utf-8", "utf-8", + "\u00e4\u00fc", + "German Umlaut \u00fc in comment"), - test("utf-8", - "\u00e4\u00fc", "German Umlaut \u00fc in comment"); + // UTF-8 with surrogate pairs + Arguments.of("utf-8", "utf-8", + "Surrogate\ud801\udc01", + "Surrogates \ud800\udc00 in comment"), - test("utf-8", - "Surrogate\ud801\udc01", "Surrogates \ud800\udc00 in comment"); + // ZipOutputStream sets the 'Language encoding flag' when writing using UTF-8 + // UTF-8 should be used for decoding, regardless of the opening charset + // UTF-8 with Japanese characters, opened with MS932 + Arguments.of("utf-8", "MS932", + "\u4e00\u4e01", + "\uff67\uff68\uff69\uff6a\uff6b\uff6c"), + + // UTF-8 with characters in latin1 range, opened with iso-8859-1 + Arguments.of("utf-8", "iso-8859-1", + "\u00e4\u00fc", + "German Umlaut \u00fc in comment"), + // UTF-8 with surrogate pairs, opened with MS932 + Arguments.of("utf-8", "MS932", + "Surrogate\ud801\udc01", + "Surrogates \ud800\udc00 in comment") + ); } - static void testZipInputStream(InputStream is, Charset cs, - String name, String comment, byte[] bb) - throws Exception - { - try (ZipInputStream zis = new ZipInputStream(is, cs)) { + /** + * Verify that ZipInputStream decodes entry names and comments + * using the charset provided to its constructor, or that it decodes + * using UTF-8 when the 'Language encoding flag' is set + * + * @param writeCharset the charset to use for ZipOutputStream when producing the ZIP + * @param readCharset the charset to use when opening the ZipInputStream + * @param name the entry name + * @param comment the entry comment (not read by ZipInputStream) + * + * @throws IOException if an unexpected IOException occurs + */ + @ParameterizedTest + @MethodSource("charsetsAndNames") + public void testZipInputStream(String writeCharset, + String readCharset, + String name, + String comment) throws IOException { + + byte[] zip = createZIP(writeCharset, name, comment); + + try (InputStream in = new ByteArrayInputStream(zip); + ZipInputStream zis = new ZipInputStream(in, Charset.forName(readCharset))) { ZipEntry e = zis.getNextEntry(); - if (e == null || ! name.equals(e.getName())) - throw new RuntimeException("ZipIS name doesn't match!"); - byte[] bBuf = new byte[bb.length << 1]; - int n = zis.read(bBuf, 0, bBuf.length); - if (n != bb.length || - !Arrays.equals(bb, Arrays.copyOf(bBuf, n))) { - throw new RuntimeException("ZipIS content doesn't match!"); - } + assertNotNull(e); + assertEquals(name, e.getName(), + "ZipInputStream.getNextEntry() returned unexpected entry name"); + assertNull(e.getComment()); // No comment in the LOC header + assertArrayEquals(ENTRY_DATA, zis.readAllBytes(), "Unexpected ZIP entry data"); } } - static void testZipFile(File f, Charset cs, - String name, String comment, byte[] bb) - throws Exception - { - try (ZipFile zf = new ZipFile(f, cs)) { + /** + * Verify that ZipFile decodes entry names and comments + * using the charset provided to its constructor, or that it decodes + * using UTF-8 when the 'Language encoding flag' is set + * + * @param writeCharset the charset to use for ZipOutputStream when producing the ZIP + * @param readCharset the charset to use when opening the ZipFile + * @param name the name of the entry + * @param comment the comment of the entry + * + * @throws IOException if an unexpected IOException occurs + */ + @ParameterizedTest + @MethodSource("charsetsAndNames") + public void testZipFile(String writeCharset, + String readCharset, + String name, + String comment) throws IOException { + + byte[] zip = createZIP(writeCharset, name, comment); + + Path f = Path.of("zfcoding.zip"); + Files.write(f, zip); + + try (ZipFile zf = new ZipFile(f.toFile(), Charset.forName(readCharset))) { + // Test using ZipFile.entries Enumeration zes = zf.entries(); ZipEntry e = (ZipEntry)zes.nextElement(); - if (! name.equals(e.getName()) || - ! comment.equals(e.getComment())) - throw new RuntimeException("ZipFile: name/comment doesn't match!"); - InputStream is = zf.getInputStream(e); - if (is == null) - throw new RuntimeException("ZipFile: getIS failed!"); - byte[] bBuf = new byte[bb.length << 1]; - int n = 0; - int nn =0; - while ((nn = is.read(bBuf, n, bBuf.length-n)) != -1) { - n += nn; - } - if (n != bb.length || - !Arrays.equals(bb, Arrays.copyOf(bBuf, n))) { - throw new RuntimeException("ZipFile content doesn't match!"); + assertNotNull(e); + assertEquals(name, e.getName(), "ZipFile.entries() returned unexpected entry name"); + assertEquals(comment, e.getComment(), "ZipFile.entries() returned unexpected entry comment"); + + // Test using ZipFile.getEntry + e = zf.getEntry(name); + assertNotNull(e, + String.format("Entry lookup failed on ZIP encoded with %s and opened with %s", + writeCharset, readCharset)); + assertEquals(name, e.getName(), "ZipFile.getEntry() returned unexpected entry name"); + assertEquals(comment, e.getComment(), "ZipFile.getEntry() returned unexpected entry comment"); + try (InputStream is = zf.getInputStream(e)) { + assertNotNull(is); + assertArrayEquals(ENTRY_DATA, is.readAllBytes(), "Unexpected ZIP entry data"); } } + + Files.deleteIfExists(f); } - static void test(String csn, String name, String comment) - throws Exception - { - byte[] bb = "This is the content of the zipfile".getBytes("ISO-8859-1"); - Charset cs = Charset.forName(csn); + /** + * Create a ZIP file containing an entry with the given name + * and comment, encoded using the given charset. + * Note that if the charset is UTF-8, ZipOutputStream will + * set the 'Language encoding flag' for the entry. + * + * @param charset the charset passed to the ZipOutputStream constructor + * @param name the name of the entry to add + * @param comment the comment of the entry to add + * @return a byte array containing the ZIP file + * + * @throws IOException if an unexpected IOException occurs + */ + private byte[] createZIP(String charset, String name, String comment) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ZipOutputStream zos = new ZipOutputStream(baos, cs)) { + try (ZipOutputStream zos = new ZipOutputStream(baos, Charset.forName(charset))) { ZipEntry e = new ZipEntry(name); e.setComment(comment); zos.putNextEntry(e); - zos.write(bb, 0, bb.length); + zos.write(ENTRY_DATA); zos.closeEntry(); } - ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray()); - testZipInputStream(bis, cs, name, comment, bb); - - if ("utf-8".equals(csn)) { - // USE_UTF8 should be set - bis.reset(); - testZipInputStream(bis, Charset.forName("MS932"), name, comment, bb); - } - - File f = new File(new File(System.getProperty("test.dir", ".")), - "zfcoding.zip"); - try (FileOutputStream fos = new FileOutputStream(f)) { - baos.writeTo(fos); - } - testZipFile(f, cs, name, comment, bb); - if ("utf-8".equals(csn)) { - testZipFile(f, Charset.forName("MS932"), name, comment, bb); - } - f.delete(); + return baos.toByteArray(); } } diff --git a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java index e0a987f8bdc31..cafc17accf8d4 100644 --- a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java +++ b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java @@ -42,7 +42,7 @@ public class DeleteTempJarTest { public static void main(String[] args) throws Exception { - String tmpFile = ProcessTools.executeTestJvm(DeleteTempJar.class.getName()) + String tmpFile = ProcessTools.executeTestJava(DeleteTempJar.class.getName()) .shouldHaveExitValue(0) .getStdout(); diff --git a/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java b/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java index 8cb1051a87c77..0f0b0725b7d43 100644 --- a/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java +++ b/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java @@ -25,6 +25,7 @@ * @bug 8317678 * @modules java.base/java.util.zip:open * @summary Fix up hashCode() for ZipFile.Source.Key + * @library /test/lib * @run junit/othervm ZipSourceCache */ @@ -34,6 +35,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.zip.*; +import jdk.test.lib.util.FileUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; @@ -62,7 +64,7 @@ public static void setup() throws Exception { @AfterAll public static void cleanup() throws IOException { - Files.deleteIfExists(Path.of(ZIPFILE_NAME)); + FileUtils.deleteFileIfExistsWithRetry(Path.of(ZIPFILE_NAME)); } /* diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java index 2b6bc0519bcc8..7869c10282a23 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java @@ -184,7 +184,7 @@ private void execute(String args) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs); // Handle response. if (out.getExitValue() != 0) { System.out.printf("OUTPUT: %s", out.getOutput()); diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java index 2f2c43d03c585..95d2541a190dc 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java @@ -168,7 +168,7 @@ private void execute(String args) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs); // Handle response. if (out.getExitValue() != 0) { System.out.printf("OUTPUT: %s", out.getOutput()); diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif deleted file mode 100644 index 3c12953f9a5f1..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif deleted file mode 100644 index a812a358b9d39..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif deleted file mode 100644 index 5559452e839af..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif b/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif deleted file mode 100644 index adefa4459d837..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif b/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif deleted file mode 100644 index 68bcf8bed1fa6..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif b/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif deleted file mode 100644 index 09e183eb531cd..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/SE1.gif b/test/jdk/javax/swing/AbstractButton/5049549/SE1.gif deleted file mode 100644 index d408843b33719..0000000000000 Binary files a/test/jdk/javax/swing/AbstractButton/5049549/SE1.gif and /dev/null differ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java b/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java index fd03f6e918d32..c24435eb18c38 100644 --- a/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java +++ b/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2023, 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,14 +21,10 @@ * questions. */ -/* @test - @bug 5049549 7132413 - @summary Tests that the proper icon is used for different states. - @library ../../regtesthelpers - @build Blocker - @run main/manual bug5049549 -*/ - +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.image.BufferedImage; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -39,17 +35,39 @@ import javax.swing.SwingUtilities; import javax.swing.UIManager; +/* + * @test + * @bug 5049549 7132413 + * @summary Tests that the proper icon is used for different states. + * @library ../../regtesthelpers + * @build Blocker + * @run main/manual bug5049549 + */ public class bug5049549 { - private static ImageIcon DE = new ImageIcon(bug5049549.class.getResource("DE1.gif")); - private static ImageIcon DI = new ImageIcon(bug5049549.class.getResource("DI1.gif")); - private static ImageIcon DS = new ImageIcon(bug5049549.class.getResource("DS1.gif")); - private static ImageIcon RO = new ImageIcon(bug5049549.class.getResource("RO1.gif")); - private static ImageIcon RS = new ImageIcon(bug5049549.class.getResource("RS1.gif")); - private static ImageIcon SE = new ImageIcon(bug5049549.class.getResource("SE1.gif")); - private static ImageIcon PR = new ImageIcon(bug5049549.class.getResource("PR1.gif")); - - private static Blocker blocker = new Blocker(); + private static final Icon DE = generateImage("DE"); + private static final Icon DI = generateImage("DI"); + private static final Icon DS = generateImage("DS"); + private static final Icon RO = generateImage("RO"); + private static final Icon RS = generateImage("RS"); + private static final Icon SE = generateImage("SE"); + private static final Icon PR = generateImage("PR"); + + private static final Blocker blocker = new Blocker(); + + private static Icon generateImage(String str) { + BufferedImage img = new BufferedImage(40, 30, + BufferedImage.TYPE_INT_RGB); + Graphics g = img.createGraphics(); + g.setColor(Color.WHITE); + g.fillRect(0, 0, img.getWidth(), img.getHeight()); + g.setColor(Color.RED); + Font font = new Font(Font.SANS_SERIF, Font.BOLD, 22); + g.setFont(font); + g.drawString(str, 5, 25); + g.dispose(); + return new ImageIcon(img); + } private static class KButton extends JButton { diff --git a/test/jdk/jdk/classfile/LimitsTest.java b/test/jdk/jdk/classfile/LimitsTest.java index b89a312a67fd9..d23a948fe9f80 100644 --- a/test/jdk/jdk/classfile/LimitsTest.java +++ b/test/jdk/jdk/classfile/LimitsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -23,6 +23,7 @@ /* * @test + * @bug 8320360 * @summary Testing ClassFile limits. * @run junit LimitsTest */ @@ -85,4 +86,10 @@ void testSupportedClassVersion() { var cf = ClassFile.of(); assertThrows(IllegalArgumentException.class, () -> cf.parse(cf.build(ClassDesc.of("ClassFromFuture"), cb -> cb.withVersion(ClassFile.latestMajorVersion() + 1, 0)))); } + + @Test + void testReadingOutOfBounds() { + assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE}), "reading magic only"); + assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE, 0, 0, 0, 0, 0, 2}), "reading invalid CP size"); + } } diff --git a/test/jdk/jdk/classfile/SignaturesTest.java b/test/jdk/jdk/classfile/SignaturesTest.java index 9f5fbe8adcae2..2c64bacee41ee 100644 --- a/test/jdk/jdk/classfile/SignaturesTest.java +++ b/test/jdk/jdk/classfile/SignaturesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -24,6 +24,7 @@ /* * @test * @summary Testing Signatures. + * @bug 8321540 * @run junit SignaturesTest */ import java.io.IOException; @@ -46,8 +47,11 @@ import java.lang.classfile.Attributes; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Assertions; import static helpers.ClassRecord.assertEqualsDeep; import static java.lang.constant.ConstantDescs.*; +import java.util.function.Consumer; +import java.util.function.Function; class SignaturesTest { @@ -186,4 +190,79 @@ void testClassSignatureClassDesc() throws IOException { assertEquals(Outer.Inner.class.describeConstable().orElseThrow(), innerSig.classDesc(), "ClassDesc derived from signature"); } + + @Test + void testBadTypeSignatures() { + """ + LObject + LObject;B + LIterable + LIterable<< + TBar + TBar + B + B;V + X + [LObject + [LIterable + [LIterable<< + [TBar + [TBar + [B + [X + LSet<+Kind<**>;>; + LSet;>; + ()V + """.lines().forEach(assertThrows(Signature::parseFrom)); + } + + @Test + void testBadClassSignatures() { + """ + Ljava/lang/Object;Ljava/lang/Iterable + LObject + LObject;B + LIterable + LIterable<< + TBar + TBar + B + B;V + X + LFoo.It;L + LFoo;LFoo;LBar; + >LFoo; + LFoo<+>; + ()V + """.lines().forEach(assertThrows(ClassSignature::parseFrom)); + } + + @Test + void testBadMethodSignatures() { + """ + LObject; + B + ()V^ + ()V^B + ()V^X + (LObject;) + (LObject)V + ()LIterable + ()LIterable<< + ()TBar + ()TBar;B + (TBar)V + (B)V + (X) + ()X + ()VB + ()LSet<+Kind<**>;>; + (LSet;>;)V + ()V + """.lines().forEach(assertThrows(MethodSignature::parseFrom)); + } + + private Consumer assertThrows(Function parser) { + return s -> Assertions.assertThrows(IllegalArgumentException.class, () -> parser.apply(s), s); + } } diff --git a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java index 02346414cd3f4..7651c92bf77b2 100644 --- a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java +++ b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java @@ -44,9 +44,9 @@ public class ExitOnThrow { public static void main(String[] args) throws Exception { if (args.length == 0) { - ProcessTools.executeTestJvm("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED", - "ExitOnThrow", - "-executeCleaner") + ProcessTools.executeTestJava("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED", + "ExitOnThrow", + "-executeCleaner") .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(1) diff --git a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java index 6b97613f4ab36..f5a32e0b45a6d 100644 --- a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java +++ b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java @@ -81,7 +81,7 @@ public static void main(String... args) throws Exception { c[1] = "-Djava.security.policy=" + escapeBackslashes(policy.toString()); c[2] = Test.class.getName(); c[3] = repository; - OutputAnalyzer oa = ProcessTools.executeTestJvm(c); + OutputAnalyzer oa = ProcessTools.executeTestJava(c); oa.shouldContain(SUCCESS); } } diff --git a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java index 5e08f45cb5550..ddbc120649762 100644 --- a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java +++ b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java @@ -283,7 +283,7 @@ private static void launchTest() throws Throwable { "-classpath", classpath, "-javaagent:" + testClassDir + "TestInstrumentation.jar", "jdk.jfr.event.io.TestInstrumentation$TestMain" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java index f1550e633eb4e..2ab6bad625982 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java @@ -57,7 +57,7 @@ public static void main(String[] args) throws Throwable { "-Dtest.jdk=" + System.getProperty("test.jdk"), TestProcess.class.getName() }; - OutputAnalyzer output = ProcessTools.executeTestJvm(arguments); + OutputAnalyzer output = ProcessTools.executeTestJava(arguments); output.shouldHaveExitValue(0); Optional p = Files.find(path, 99, (a,b) -> a.getFileName().toString().endsWith(".jfr")).findAny(); if (p.isEmpty()) { diff --git a/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java b/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java index 57287c6d8ee05..39701d073ab3f 100644 --- a/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java +++ b/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 8316141 + * @bug 8316141 8321802 * @summary test for correct detection and reporting of corrupted zip files * @run junit CorruptedZipFilesTest */ @@ -287,6 +287,16 @@ public void unsupportedCompressionMethod() throws IOException { assertZipException(".*unsupported compression method.*"); } + /* + * A ZipException is thrown when a LOC header has an unexpected signature + */ + @Test + public void invalidLOCSignature() throws IOException { + int existingSignature = buffer.getInt(locpos); + buffer.putInt(locpos, existingSignature +1); + assertZipException(".*bad signature.*"); + } + /* * Assert that opening a ZIP file and consuming the entry's * InputStream using the ZipFile API fails with a ZipException diff --git a/test/jdk/sun/security/mscapi/DupAlias.java b/test/jdk/sun/security/mscapi/DupAlias.java new file mode 100644 index 0000000000000..84c70cbbee232 --- /dev/null +++ b/test/jdk/sun/security/mscapi/DupAlias.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023, 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 jdk.test.lib.Asserts; +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.x509.X500Name; + +import java.security.KeyStore; +import java.security.MessageDigest; +import java.security.cert.X509Certificate; +import java.util.HexFormat; + +/** + * @test + * @bug 8187634 + * @requires os.family == "windows" + * @library /test/lib + * @modules java.base/sun.security.tools.keytool + * java.base/sun.security.x509 + * @summary getCertificateAlias should return correct alias + */ +public class DupAlias { + public static void main(String[] args) throws Exception { + + String nn = "8187634"; + String na = nn + "a"; + String nb = nn + "b"; + String n1 = nn + " (1)"; + + CertAndKeyGen g = new CertAndKeyGen("EC", "SHA256withECDSA"); + g.generate(-1); + X509Certificate a = g.getSelfCertificate(new X500Name("CN=" + na), 1000); + g.generate(-1); + X509Certificate b = g.getSelfCertificate(new X500Name("CN=" + nb), 1000); + + KeyStore ks = KeyStore.getInstance("Windows-MY-CURRENTUSER"); + try { + ks.load(null, null); + ks.deleteEntry(na); + ks.deleteEntry(nb); + ks.deleteEntry(nn); + ks.deleteEntry(n1); + ks.setCertificateEntry(na, a); + ks.setCertificateEntry(nb, b); + + ps(String.format(""" + $cert = Get-Item Cert:/CurrentUser/My/%s; + $cert.FriendlyName = %s; + $cert = Get-Item Cert:/CurrentUser/My/%s; + $cert.FriendlyName = %s; + """, thumbprint(a), nn, thumbprint(b), nn)); + + ks.load(null, null); + Asserts.assertFalse(ks.containsAlias(na)); + Asserts.assertFalse(ks.containsAlias(nb)); + Asserts.assertEquals(ks.getCertificateAlias(ks.getCertificate(nn)), nn); + Asserts.assertEquals(ks.getCertificateAlias(ks.getCertificate(n1)), n1); + } finally { + ks.deleteEntry(na); + ks.deleteEntry(nb); + ks.deleteEntry(nn); + ks.deleteEntry(n1); + } + } + + static void ps(String f) throws Exception { + ProcessBuilder pb = new ProcessBuilder("powershell", "-Command", f); + pb.inheritIO(); + if (pb.start().waitFor() != 0) { + throw new RuntimeException("Failed"); + } + } + + static String thumbprint(X509Certificate c) throws Exception { + return HexFormat.of().formatHex( + MessageDigest.getInstance("SHA-1").digest(c.getEncoded())); + } +} diff --git a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java index b5ca601c011d6..11a6a781e01d3 100644 --- a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java +++ b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java @@ -40,7 +40,7 @@ public class ReadConfInUTF16Env { public void testReadConfInUTF16Env() throws Exception { String[] testCommand = new String[] { "-Dfile.encoding=UTF-16", TestSunPKCS11Provider.class.getName()}; - ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0); + ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0); } static class TestSunPKCS11Provider { diff --git a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java index b9fb72b8faf0e..476dc95488495 100644 --- a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java +++ b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java @@ -231,7 +231,7 @@ static void testConstraint(String[] trustNames, String[] certNames, // Run client on another JVM so that its properties cannot be in conflict // with server's. - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( "-Dcert.dir=" + CERT_DIR, "-Djava.security.debug=certpath", "-classpath", diff --git a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java index 1ce50662f4647..7632fcf462f9a 100644 --- a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java +++ b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java @@ -93,7 +93,7 @@ public class DebugReportsOneExtraByte extends SSLEngineTemplate { public static void main(String args[]) throws Exception { if (args.length == 0) { - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-Dtest.src=" + System.getProperty("test.src"), "-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p"); output.shouldContain("WRITE: TLSv1 application_data, length = 8"); diff --git a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java index c614ca62f29a9..5cfa9c9a68008 100644 --- a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java +++ b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java @@ -50,7 +50,7 @@ public class LoggingFormatConsistency extends SSLSocketTemplate { public static void main(String[] args) throws Exception { if (args.length != 0) { // A non-empty set of arguments occurs when the "runTest" argument - // is passed to the test via ProcessTools::executeTestJvm. + // is passed to the test via ProcessTools::executeTestJava. // // This is done because an OutputAnalyzer is unable to read // the output of the current running JVM, and must therefore create @@ -71,7 +71,7 @@ public static void main(String[] args) throws Exception { System.out.println("TESTING " + expectedTLSVersion); var activeTLSProtocol = "-Djdk.tls.client.protocols=" + expectedTLSVersion; - var output = ProcessTools.executeTestJvm( + var output = ProcessTools.executeTestJava( testSrc, activeTLSProtocol, javaxNetDebug, diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java index 708b8f0d11bb8..a1c9cad22711a 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java @@ -49,7 +49,7 @@ public class IgnorableExceptionMessages extends SSLSocketTemplate { public static void main(String[] args) throws Exception { if (args.length > 0) { // A non-empty set of arguments occurs when the "runTest" argument - // is passed to the test via ProcessTools::executeTestJvm. + // is passed to the test via ProcessTools::executeTestJava. // // This is done because an OutputAnalyzer is unable to read // the output of the current running JVM, and must therefore create @@ -67,7 +67,7 @@ public static void main(String[] args) throws Exception { className, extraArgument); - OutputAnalyzer output = ProcessTools.executeTestJvm(jvmArgs); + OutputAnalyzer output = ProcessTools.executeTestJava(jvmArgs); if (output.getExitValue() != 0) { output.asLines().forEach(System.out::println); // No need to dump the output unless the test fails diff --git a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java index ccc4b4051470d..9c9a8590ac74c 100644 --- a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java +++ b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java @@ -120,7 +120,7 @@ public static void main(String[] args) throws Throwable { "-Djava.security.policy=" + TEST_SRC + File.separator + POLICY_FILE, "version.Main"}; - ProcessTools.executeTestJvm(cmd) + ProcessTools.executeTestJava(cmd) .shouldHaveExitValue(0) .shouldContain(VERSION_MESSAGE); } diff --git a/test/jdk/sun/security/util/Resources/early/EarlyResources.java b/test/jdk/sun/security/util/Resources/early/EarlyResources.java index 12da50e311f9e..3ee0a9f576c62 100644 --- a/test/jdk/sun/security/util/Resources/early/EarlyResources.java +++ b/test/jdk/sun/security/util/Resources/early/EarlyResources.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { String fs = File.separator; String policyPath = testSrc + fs + "malformed.policy"; - OutputAnalyzer out = ProcessTools.executeTestJvm( + OutputAnalyzer out = ProcessTools.executeTestJava( "-Djava.security.manager", "-Djava.security.policy=" + policyPath, "EarlyResources$TestMain"); diff --git a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java index eb56c087ad654..a468f6b1f1b03 100644 --- a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java +++ b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -23,9 +23,10 @@ /* * @test - * @bug 8181157 8202537 8234347 8236548 8261279 + * @bug 8181157 8202537 8234347 8236548 8261279 8322647 * @modules jdk.localedata - * @summary Checks CLDR time zone names are generated correctly at runtime + * @summary Checks CLDR time zone names are generated correctly at + * either build or runtime * @run testng/othervm -Djava.locale.providers=CLDR TimeZoneNamesTest */ @@ -45,8 +46,8 @@ @Test public class TimeZoneNamesTest { - @DataProvider(name="noResourceTZs") - Object[][] data() { + @DataProvider + Object[][] sampleTZs() { return new Object[][] { // tzid, locale, style, expected @@ -174,11 +175,49 @@ Object[][] data() { "UTC+03:00", "heure : Istanbul", "UTC+03:00"}, + + // Short names derived from TZDB at build time + {"Europe/Lisbon", Locale.US, "Western European Standard Time", + "WET", + "Western European Summer Time", + "WEST", + "Western European Time", + "WET"}, + {"Atlantic/Azores", Locale.US, "Azores Standard Time", + "GMT-01:00", + "Azores Summer Time", + "GMT", + "Azores Time", + "GMT-01:00"}, + {"Australia/Perth", Locale.US, "Australian Western Standard Time", + "AWST", + "Australian Western Daylight Time", + "AWDT", + "Western Australia Time", + "AWT"}, + {"Africa/Harare", Locale.US, "Central Africa Time", + "CAT", + "Harare Daylight Time", + "CAT", + "Harare Time", + "CAT"}, + {"Europe/Dublin", Locale.US, "Greenwich Mean Time", + "GMT", + "Irish Standard Time", + "IST", + "Dublin Time", + "GMT"}, + {"Pacific/Gambier", Locale.US, "Gambier Time", + "GMT-09:00", + "Gambier Daylight Time", + "GMT-09:00", + "Gambier Time", + "GMT-09:00"}, }; } - @Test(dataProvider="noResourceTZs") + @Test(dataProvider="sampleTZs") public void test_tzNames(String tzid, Locale locale, String lstd, String sstd, String ldst, String sdst, String lgen, String sgen) { // Standard time assertEquals(TimeZone.getTimeZone(tzid).getDisplayName(false, TimeZone.LONG, locale), lstd); @@ -197,16 +236,14 @@ public void test_tzNames(String tzid, Locale locale, String lstd, String sstd, S @Test public void test_getZoneStrings() { assertFalse( - Arrays.stream(Locale.getAvailableLocales()) + Locale.availableLocales() .limit(30) .peek(l -> System.out.println("Locale: " + l)) .map(l -> DateFormatSymbols.getInstance(l).getZoneStrings()) - .flatMap(zs -> Arrays.stream(zs)) + .flatMap(Arrays::stream) .peek(names -> System.out.println(" tz: " + names[0])) - .flatMap(names -> Arrays.stream(names)) - .filter(name -> Objects.isNull(name) || name.isEmpty()) - .findAny() - .isPresent(), + .flatMap(Arrays::stream) + .anyMatch(name -> Objects.isNull(name) || name.isEmpty()), "getZoneStrings() returned array containing non-empty string element(s)"); } } diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index 607575b291fca..2ab92a625d0e1 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8301580 + * @bug 8301580 8322159 * @summary Verify error recovery w.r.t. Attr * @library /tools/lib * @enablePreview @@ -87,4 +87,41 @@ class C { } } + @Test + public void testX() throws Exception { + String code = """ + public class C { + public C() { + Undefined.method(); + undefined1(); + Runnable r = this::undefined2; + overridable(this); //to verify ThisEscapeAnalyzer has been run + } + public void overridable(C c) {} + } + """; + Path curPath = Path.of("."); + List actual = new JavacTask(tb) + .options("-XDrawDiagnostics", "-XDdev", + "-XDshould-stop.at=FLOW", "-Xlint:this-escape") + .sources(code) + .outdir(curPath) + .run(Expect.FAIL) + .writeAll() + .getOutputLines(OutputKind.DIRECT); + + List expected = List.of( + "C.java:3:9: compiler.err.cant.resolve.location: kindname.variable, Undefined, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:4:9: compiler.err.cant.resolve.location.args: kindname.method, undefined1, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:5:22: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, undefined2, , , (compiler.misc.location: kindname.class, C, null))", + "C.java:6:20: compiler.warn.possible.this.escape", + "3 errors", + "1 warning" + ); + + if (!Objects.equals(actual, expected)) { + error("Expected: " + expected + ", but got: " + actual); + } + } + } diff --git a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java index ce57ebfe65f34..71e36bdc9c471 100644 --- a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java +++ b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java @@ -69,7 +69,7 @@ public static void main( String[] args) throws Throwable { jvmArgs.add(origFileName); int fileNameIndex = jvmArgs.size() - 1; String[] cmdLineArgs = jvmArgs.toArray(new String[jvmArgs.size()]); - ProcessTools.executeTestJvm(cmdLineArgs).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmdLineArgs).shouldHaveExitValue(0); String etalon = Utils.fileAsString(origFileName).trim(); cmdLineArgs[fileNameIndex] = seedOpt.name(); seedOpt.verify(etalon, cmdLineArgs); @@ -143,7 +143,7 @@ public void verify(String orig, String[] cmdLine) { String output; OutputAnalyzer oa; try { - oa = ProcessTools.executeTestJvm(cmdLine); + oa = ProcessTools.executeTestJava(cmdLine); } catch (Throwable t) { throw new Error("TESTBUG: Unexpedted exception during jvm execution.", t); } diff --git a/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java new file mode 100644 index 0000000000000..4331f9ab374f7 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023, 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 Unit test for ProcessTools.executeLimitedTestJava() + * @library /test/lib + * @run main/othervm -Dtest.java.opts=-XX:MaxMetaspaceSize=123456789 ProcessToolsExecuteLimitedTestJavaTest + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class ProcessToolsExecuteLimitedTestJavaTest { + public static void main(String[] args) throws Exception { + if (args.length > 0) { + // Do nothing. Just let the JVM log its output. + } else { + // In comparison to executeTestJava, executeLimitedTestJava should not add the + // -Dtest.java.opts flags. Check that it doesn't. + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintFlagsFinal", "-version"); + output.stdoutShouldNotMatch(".*MaxMetaspaceSize.* = 123456789.*"); + } + } +} diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index e316248fe8ee5..48a0b098d488c 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -108,6 +108,14 @@ public OutputAnalyzer(String stdout, String stderr, int exitValue) buffer = OutputBuffer.of(stdout, stderr, exitValue); } + /** + * Delegate waitFor to the OutputBuffer. This ensures that + * the progress and timestamps are logged correctly. + */ + public void waitFor() { + buffer.waitFor(); + } + /** * Verify that the stdout contents of output buffer is empty * diff --git a/test/lib/jdk/test/lib/process/OutputBuffer.java b/test/lib/jdk/test/lib/process/OutputBuffer.java index fba2a5f6dcf3f..f032591f3584c 100644 --- a/test/lib/jdk/test/lib/process/OutputBuffer.java +++ b/test/lib/jdk/test/lib/process/OutputBuffer.java @@ -44,6 +44,12 @@ public OutputBufferException(Throwable cause) { } } + /** + * Waits for a process to finish, if there is one assocated with + * this OutputBuffer. + */ + public void waitFor(); + /** * Returns the stdout result * @@ -67,6 +73,13 @@ default public List getStdoutAsList() { * @return stderr result */ public String getStderr(); + + + /** + * Returns the exit value + * + * @return exit value + */ public int getExitValue(); /** @@ -136,20 +149,12 @@ private LazyOutputBuffer(Process p, Charset cs) { } @Override - public String getStdout() { - return outTask.get(); - } - - @Override - public String getStderr() { - return errTask.get(); - } - - @Override - public int getExitValue() { + public void waitFor() { if (exitValue != null) { - return exitValue; + // Already waited for this process + return; } + try { logProgress("Waiting for completion"); boolean aborted = true; @@ -157,7 +162,6 @@ public int getExitValue() { exitValue = p.waitFor(); logProgress("Waiting for completion finished"); aborted = false; - return exitValue; } finally { if (aborted) { logProgress("Waiting for completion FAILED"); @@ -169,6 +173,22 @@ public int getExitValue() { } } + @Override + public String getStdout() { + return outTask.get(); + } + + @Override + public String getStderr() { + return errTask.get(); + } + + @Override + public int getExitValue() { + waitFor(); + return exitValue; + } + @Override public long pid() { return p.pid(); @@ -186,6 +206,11 @@ private EagerOutputBuffer(String stdout, String stderr, int exitValue) { this.exitValue = exitValue; } + @Override + public void waitFor() { + // Nothing to do since this buffer is not associated with a Process. + } + @Override public String getStdout() { return stdout; diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index db80a439f2b25..774af8e150dd6 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -608,43 +608,69 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(String... comma } /** - * Executes a test jvm process, waits for it to finish and returns + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns * the process output. * *

    The process is created using runtime flags set up by: * {@link #createTestJavaProcessBuilder(String...)}. The * jvm process will have exited before this method returns. * - * @param cmds User specified arguments. + * @param command User specified arguments. * @return The output from the process. */ - public static OutputAnalyzer executeTestJvm(List cmds) throws Exception { - return executeTestJvm(cmds.toArray(String[]::new)); + public static OutputAnalyzer executeTestJava(List command) throws Exception { + return executeTestJava(command.toArray(String[]::new)); } /** - * Executes a test jvm process, waits for it to finish and returns + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns * the process output. * *

    The process is created using runtime flags set up by: * {@link #createTestJavaProcessBuilder(String...)}. The * jvm process will have exited before this method returns. * - * @param cmds User specified arguments. + * @param command User specified arguments. * @return The output from the process. */ - public static OutputAnalyzer executeTestJvm(String... cmds) throws Exception { - ProcessBuilder pb = createTestJavaProcessBuilder(cmds); + public static OutputAnalyzer executeTestJava(String... command) throws Exception { + ProcessBuilder pb = createTestJavaProcessBuilder(command); return executeProcess(pb); } /** - * @param cmds User specified arguments. + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns + * the process output. + * + *

    The process is created using runtime flags set up by: + * {@link #createLimitedTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. + * + * @param command User specified arguments. * @return The output from the process. - * @see #executeTestJvm(String...) */ - public static OutputAnalyzer executeTestJava(String... cmds) throws Exception { - return executeTestJvm(cmds); + public static OutputAnalyzer executeLimitedTestJava(List command) throws Exception { + return executeLimitedTestJava(command.toArray(String[]::new)); + } + + /** + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns + * the process output. + * + *

    The process is created using runtime flags set up by: + * {@link #createLimitedTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. + * + * @param command User specified arguments. + * @return The output from the process. + */ + public static OutputAnalyzer executeLimitedTestJava(String... command) throws Exception { + ProcessBuilder pb = createLimitedTestJavaProcessBuilder(command); + return executeProcess(pb); } /** @@ -697,7 +723,10 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, } output = new OutputAnalyzer(p, cs); - p.waitFor(); + + // Wait for the process to finish. Call through the output + // analyzer to get correct logging and timestamps. + output.waitFor(); { // Dumping the process output to a separate file var fileName = String.format("pid-%d-output.log", p.pid()); diff --git a/test/lib/jdk/test/lib/thread/VThreadPinner.java b/test/lib/jdk/test/lib/thread/VThreadPinner.java new file mode 100644 index 0000000000000..25b06912fdf64 --- /dev/null +++ b/test/lib/jdk/test/lib/thread/VThreadPinner.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023, 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 jdk.test.lib.thread; + +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.nio.file.Path; +import java.time.Duration; +import java.util.concurrent.atomic.AtomicReference; +import jdk.test.lib.thread.VThreadRunner.ThrowingRunnable; + +/** + * Helper class to allow tests run a task in a virtual thread while pinning its carrier. + * + * It defines the {@code runPinned} method to run a task with a native frame on the stack. + */ +public class VThreadPinner { + private static final Path JAVA_LIBRARY_PATH = Path.of(System.getProperty("java.library.path")); + private static final Path LIB_PATH = JAVA_LIBRARY_PATH.resolve(System.mapLibraryName("VThreadPinner")); + + // method handle to call the native function + private static final MethodHandle INVOKER = invoker(); + + // function pointer to call + private static final MemorySegment UPCALL_STUB = upcallStub(); + + /** + * Thread local with the task to run. + */ + private static final ThreadLocal TASK_RUNNER = new ThreadLocal<>(); + + /** + * Runs a task, capturing any exception or error thrown. + */ + private static class TaskRunner implements Runnable { + private final ThrowingRunnable task; + private Throwable throwable; + + TaskRunner(ThrowingRunnable task) { + this.task = task; + } + + @Override + public void run() { + try { + task.run(); + } catch (Throwable ex) { + throwable = ex; + } + } + + Throwable exception() { + return throwable; + } + } + + /** + * Called by the native function to run the task stashed in the thread local. The + * task runs with the native frame on the stack. + */ + private static void callback() { + TASK_RUNNER.get().run(); + } + + /** + * Runs the given task on a virtual thread pinned to its carrier. If called from a + * virtual thread then it invokes the task directly. + */ + public static void runPinned(ThrowingRunnable task) throws X { + if (!Thread.currentThread().isVirtual()) { + VThreadRunner.run(() -> runPinned(task)); + return; + } + var runner = new TaskRunner(task); + TASK_RUNNER.set(runner); + try { + INVOKER.invoke(UPCALL_STUB); + } catch (Throwable e) { + throw new RuntimeException(e); + } finally { + TASK_RUNNER.remove(); + } + Throwable ex = runner.exception(); + if (ex != null) { + if (ex instanceof RuntimeException e) + throw e; + if (ex instanceof Error e) + throw e; + throw (X) ex; + } + } + + /** + * Returns a method handle to the native function void call(void *(*f)(void *)). + */ + @SuppressWarnings("restricted") + private static MethodHandle invoker() { + Linker abi = Linker.nativeLinker(); + try { + SymbolLookup lib = SymbolLookup.libraryLookup(LIB_PATH, Arena.global()); + MemorySegment symbol = lib.find("call").orElseThrow(); + FunctionDescriptor desc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS); + return abi.downcallHandle(symbol, desc); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + /** + * Returns an upcall stub to use as a function pointer to invoke the callback method. + */ + @SuppressWarnings("restricted") + private static MemorySegment upcallStub() { + Linker abi = Linker.nativeLinker(); + try { + MethodHandle callback = MethodHandles.lookup() + .findStatic(VThreadPinner.class, "callback", MethodType.methodType(void.class)); + return abi.upcallStub(callback, FunctionDescriptor.ofVoid(), Arena.global()); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } +} diff --git a/test/lib/jdk/test/lib/thread/VThreadRunner.java b/test/lib/jdk/test/lib/thread/VThreadRunner.java index 74158c89a1490..ba69496a0473b 100644 --- a/test/lib/jdk/test/lib/thread/VThreadRunner.java +++ b/test/lib/jdk/test/lib/thread/VThreadRunner.java @@ -29,7 +29,7 @@ import java.util.concurrent.atomic.AtomicReference; /** - * Helper class to support tests running tasks a in virtual thread. + * Helper class to support tests running tasks in a virtual thread. */ public class VThreadRunner { private VThreadRunner() { } @@ -41,38 +41,31 @@ private VThreadRunner() { } public static final int NO_INHERIT_THREAD_LOCALS = 1 << 2; /** - * Represents a task that does not return a result but may throw - * an exception. + * Represents a task that does not return a result but may throw an exception. */ @FunctionalInterface - public interface ThrowingRunnable { - /** - * Runs this operation. - */ - void run() throws Exception; + public interface ThrowingRunnable { + void run() throws X; } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param name thread name, can be null * @param characteristics thread characteristics * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(String name, - int characteristics, - ThrowingRunnable task) throws Exception { - AtomicReference exc = new AtomicReference<>(); - Runnable target = () -> { + public static void run(String name, + int characteristics, + ThrowingRunnable task) throws X { + var throwableRef = new AtomicReference(); + Runnable target = () -> { try { task.run(); - } catch (Error e) { - exc.set(new RuntimeException(e)); - } catch (Exception e) { - exc.set(e); + } catch (Throwable ex) { + throwableRef.set(ex); } }; @@ -84,54 +77,59 @@ public static void run(String name, Thread thread = builder.start(target); // wait for thread to terminate - while (thread.join(Duration.ofSeconds(10)) == false) { - System.out.println("-- " + thread + " --"); - for (StackTraceElement e : thread.getStackTrace()) { - System.out.println(" " + e); + try { + while (thread.join(Duration.ofSeconds(10)) == false) { + System.out.println("-- " + thread + " --"); + for (StackTraceElement e : thread.getStackTrace()) { + System.out.println(" " + e); + } } + } catch (InterruptedException e) { + throw new RuntimeException(e); } - Exception e = exc.get(); - if (e != null) { - throw e; + Throwable ex = throwableRef.get(); + if (ex != null) { + if (ex instanceof RuntimeException e) + throw e; + if (ex instanceof Error e) + throw e; + throw (X) ex; } } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param name thread name, can be null * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(String name, ThrowingRunnable task) throws Exception { + public static void run(String name, ThrowingRunnable task) throws X { run(name, 0, task); } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param characteristics thread characteristics * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(int characteristics, ThrowingRunnable task) throws Exception { + public static void run(int characteristics, ThrowingRunnable task) throws X { run(null, characteristics, task); } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(ThrowingRunnable task) throws Exception { + public static void run(ThrowingRunnable task) throws X { run(null, 0, task); } diff --git a/test/lib/jdk/test/lib/thread/libVThreadPinner.c b/test/lib/jdk/test/lib/thread/libVThreadPinner.c new file mode 100644 index 0000000000000..958e636e3db80 --- /dev/null +++ b/test/lib/jdk/test/lib/thread/libVThreadPinner.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023, 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 + +#ifdef _WIN64 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + +/* + * Call a function with the given function pointer. + */ +EXPORT void call(void *(*f)(void)) { + (*f)(); +} diff --git a/test/micro/org/openjdk/bench/java/security/SSLHandshake.java b/test/micro/org/openjdk/bench/java/security/SSLHandshake.java index 67e51e9532d27..62c4504558518 100644 --- a/test/micro/org/openjdk/bench/java/security/SSLHandshake.java +++ b/test/micro/org/openjdk/bench/java/security/SSLHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -80,11 +80,12 @@ public void init() throws Exception { KeyStore ks = TestCertificates.getKeyStore(); KeyStore ts = TestCertificates.getTrustStore(); - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, new char[0]); - TrustManagerFactory tmf = - TrustManagerFactory.getInstance("SunX509"); + TrustManagerFactory tmf = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ts); SSLContext sslCtx = SSLContext.getInstance(tlsVersion); diff --git a/test/micro/org/openjdk/bench/java/security/TestCertificates.java b/test/micro/org/openjdk/bench/java/security/TestCertificates.java index 50d8401c0708a..752f0442a9381 100644 --- a/test/micro/org/openjdk/bench/java/security/TestCertificates.java +++ b/test/micro/org/openjdk/bench/java/security/TestCertificates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -115,12 +115,12 @@ class TestCertificates { private TestCertificates() {} public static KeyStore getKeyStore() throws GeneralSecurityException, IOException { - KeyStore result = KeyStore.getInstance("JKS"); + KeyStore result = KeyStore.getInstance(KeyStore.getDefaultType()); result.load(null, null); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate serverCert = cf.generateCertificate( new ByteArrayInputStream( - TestCertificates.SERVER_CERT.getBytes(StandardCharsets.ISO_8859_1))); + SERVER_CERT.getBytes(StandardCharsets.ISO_8859_1))); Certificate caCert = cf.generateCertificate( new ByteArrayInputStream( CA_CERT.getBytes(StandardCharsets.ISO_8859_1))); @@ -135,7 +135,7 @@ public static KeyStore getKeyStore() throws GeneralSecurityException, IOExceptio } public static KeyStore getTrustStore() throws GeneralSecurityException, IOException { - KeyStore result = KeyStore.getInstance("JKS"); + KeyStore result = KeyStore.getInstance(KeyStore.getDefaultType()); result.load(null, null); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate rootcaCert = cf.generateCertificate(