diff --git a/make/data/charsetmapping/IBM864.c2b b/make/data/charsetmapping/IBM864.c2b new file mode 100644 index 00000000000..87d30430496 --- /dev/null +++ b/make/data/charsetmapping/IBM864.c2b @@ -0,0 +1 @@ +0x25 U+0025 diff --git a/make/data/hotspot-symbols/symbols-unix b/make/data/hotspot-symbols/symbols-unix index d30ba899ce1..aa81e3d99fa 100644 --- a/make/data/hotspot-symbols/symbols-unix +++ b/make/data/hotspot-symbols/symbols-unix @@ -81,6 +81,7 @@ JVM_GetClassDeclaredConstructors JVM_GetClassDeclaredFields JVM_GetClassDeclaredMethods JVM_GetClassFieldsCount +JVM_GetClassFileVersion JVM_GetClassInterfaces JVM_GetClassMethodsCount JVM_GetClassModifiers diff --git a/make/modules/java.base/lib/CoreLibraries.gmk b/make/modules/java.base/lib/CoreLibraries.gmk index e7188218df3..b86c439c2d9 100644 --- a/make/modules/java.base/lib/CoreLibraries.gmk +++ b/make/modules/java.base/lib/CoreLibraries.gmk @@ -172,8 +172,10 @@ ifeq ($(call isTargetOs, macosx), true) endif ifeq ($(call isTargetOs, windows), true) - # Supply the name of the C runtime lib. - LIBJLI_CFLAGS += -DMSVCR_DLL_NAME='"$(notdir $(MSVCR_DLL))"' + # Supply the name of the C runtime libs. + ifneq ($(MSVCR_DLL), ) + LIBJLI_CFLAGS += -DMSVCR_DLL_NAME='"$(notdir $(MSVCR_DLL))"' + endif ifneq ($(VCRUNTIME_1_DLL), ) LIBJLI_CFLAGS += -DVCRUNTIME_1_DLL_NAME='"$(notdir $(VCRUNTIME_1_DLL))"' endif diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp index 3ce1c12a2d4..d41383443d4 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp @@ -336,19 +336,13 @@ inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { // Compiled frames inline oop frame::saved_oop_result(RegisterMap* map) const { - PRAGMA_DIAG_PUSH - PRAGMA_NONNULL_IGNORED oop* result_adr = (oop *)map->location(r0->as_VMReg(), sp()); - PRAGMA_DIAG_POP guarantee(result_adr != NULL, "bad register save location"); return *result_adr; } inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { - PRAGMA_DIAG_PUSH - PRAGMA_NONNULL_IGNORED oop* result_adr = (oop *)map->location(r0->as_VMReg(), sp()); - PRAGMA_DIAG_POP guarantee(result_adr != NULL, "bad register save location"); *result_adr = obj; diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 9ab941557f3..a9ef6ee8068 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -28,13 +28,11 @@ #include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" #include "runtime/java.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/vm_version.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/macros.hpp" -#include OS_HEADER_INLINE(os) - int VM_Version::_cpu; int VM_Version::_model; int VM_Version::_model2; diff --git a/src/hotspot/cpu/arm/frame_arm.inline.hpp b/src/hotspot/cpu/arm/frame_arm.inline.hpp index 2e60a83df8b..62d292886eb 100644 --- a/src/hotspot/cpu/arm/frame_arm.inline.hpp +++ b/src/hotspot/cpu/arm/frame_arm.inline.hpp @@ -196,6 +196,10 @@ inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { // Compiled frames +// Register is a class, but it would be assigned numerical value. +// "0" is assigned for rax. Thus we need to ignore -Wnonnull. +PRAGMA_DIAG_PUSH +PRAGMA_NONNULL_IGNORED inline oop frame::saved_oop_result(RegisterMap* map) const { oop* result_adr = (oop*) map->location(R0->as_VMReg(), nullptr); guarantee(result_adr != NULL, "bad register save location"); @@ -207,6 +211,7 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { guarantee(result_adr != NULL, "bad register save location"); *result_adr = obj; } +PRAGMA_DIAG_POP inline int frame::frame_size() const { return sender_sp() - sp(); diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp index 47a73e42e9b..da1cecf3e8a 100644 --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp @@ -38,6 +38,7 @@ #include "oops/compressedOops.hpp" #include "oops/objArrayKlass.hpp" #include "runtime/frame.inline.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safepointMechanism.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp index 760ab28f47e..0ab74d3b500 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp @@ -34,6 +34,7 @@ #include "gc/shared/barrierSetAssembler.hpp" #include "oops/accessDecorators.hpp" #include "oops/compressedOops.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safepointMechanism.hpp" #include "runtime/vm_version.hpp" #include "utilities/powerOfTwo.hpp" diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index ef90ca16593..5a55d8f4dc2 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -38,6 +38,7 @@ #include "oops/klass.inline.hpp" #include "prims/methodHandles.hpp" #include "runtime/jniHandles.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index e8138643a1f..89fdacf79ec 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -41,6 +41,7 @@ #include #if defined(_AIX) +#include "os_aix.hpp" #include #endif diff --git a/src/hotspot/cpu/riscv/assembler_riscv.cpp b/src/hotspot/cpu/riscv/assembler_riscv.cpp index 7eb878d37cd..32b06e30c79 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.cpp @@ -311,13 +311,6 @@ void Assembler::movptr(Register Rd, address addr) { addi(Rd, Rd, offset); } -void Assembler::ifence() { - fence_i(); - if (UseConservativeFence) { - fence(ir, ir); - } -} - #define INSN(NAME, NEG_INSN) \ void Assembler::NAME(Register Rs, Register Rt, const address &dest) { \ NEG_INSN(Rt, Rs, dest); \ diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 25d7233975b..35144fc9552 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -339,7 +339,6 @@ public: void movptr(Register Rd, address addr); void movptr_with_offset(Register Rd, address addr, int32_t &offset); void movptr(Register Rd, uintptr_t imm64); - void ifence(); void j(const address &dest, Register temp = t0); void j(const Address &adr, Register temp = t0); void j(Label &l, Register temp = t0); @@ -961,7 +960,6 @@ public: emit(insn); \ } - INSN(fence_i, 0b0001111, 0b001, 0b000000000000); INSN(ecall, 0b1110011, 0b000, 0b000000000000); INSN(_ebreak, 0b1110011, 0b000, 0b000000000001); diff --git a/src/hotspot/cpu/riscv/compiledIC_riscv.cpp b/src/hotspot/cpu/riscv/compiledIC_riscv.cpp index 75bc4be7840..d202db92a4c 100644 --- a/src/hotspot/cpu/riscv/compiledIC_riscv.cpp +++ b/src/hotspot/cpu/riscv/compiledIC_riscv.cpp @@ -69,8 +69,8 @@ address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) #undef __ int CompiledStaticCall::to_interp_stub_size() { - // fence_i + fence* + (lui, addi, slli, addi, slli, addi) + (lui, addi, slli, addi, slli) + jalr - return NativeFenceI::instruction_size() + 12 * NativeInstruction::instruction_size; + // (lui, addi, slli, addi, slli, addi) + (lui, addi, slli, addi, slli) + jalr + return 12 * NativeInstruction::instruction_size; } int CompiledStaticCall::to_trampoline_stub_size() { @@ -98,7 +98,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad // Creation also verifies the object. NativeMovConstReg* method_holder - = nativeMovConstReg_at(stub + NativeFenceI::instruction_size()); + = nativeMovConstReg_at(stub); #ifdef ASSERT NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address()); @@ -119,7 +119,7 @@ void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_ assert(CompiledICLocker::is_safe(stub), "mt unsafe call"); // Creation also verifies the object. NativeMovConstReg* method_holder - = nativeMovConstReg_at(stub + NativeFenceI::instruction_size()); + = nativeMovConstReg_at(stub); method_holder->set_data(0); NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); jump->set_jump_destination((address)-1); @@ -139,7 +139,7 @@ void CompiledDirectStaticCall::verify() { assert(stub != NULL, "no stub found for static call"); // Creation also verifies the object. NativeMovConstReg* method_holder - = nativeMovConstReg_at(stub + NativeFenceI::instruction_size()); + = nativeMovConstReg_at(stub); NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); // Verify state. diff --git a/src/hotspot/cpu/riscv/frame_riscv.inline.hpp b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp index e6f09ccbe89..934f0e5910e 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.inline.hpp +++ b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp @@ -275,13 +275,11 @@ inline intptr_t* frame::interpreter_frame_expression_stack() const { // Entry frames inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { - return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset); + return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset); } // Compiled frames -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED inline oop frame::saved_oop_result(RegisterMap* map) const { oop* result_adr = (oop *)map->location(x10->as_VMReg(), nullptr); guarantee(result_adr != NULL, "bad register save location"); @@ -293,7 +291,6 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { guarantee(result_adr != NULL, "bad register save location"); *result_adr = obj; } -PRAGMA_DIAG_POP inline const ImmutableOopMap* frame::get_oop_map() const { if (_cb == NULL) return NULL; diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index ff4ec2f284d..3b73bb42236 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -88,8 +88,7 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, TraceTraps, false, "Trace all traps the signal handler") \ /* For now we're going to be safe and add the I/O bits to userspace fences. */ \ product(bool, UseConservativeFence, true, \ - "Extend i for r and o for w in the pred/succ flags of fence;" \ - "Extend fence.i to fence.i + fence.") \ + "Extend i for r and o for w in the pred/succ flags of fence") \ product(bool, AvoidUnalignedAccesses, true, \ "Avoid generating unaligned memory accesses") \ product(bool, UseRVV, false, EXPERIMENTAL, "Use RVV instructions") \ diff --git a/src/hotspot/cpu/riscv/icache_riscv.cpp b/src/hotspot/cpu/riscv/icache_riscv.cpp index 922a80f9f3e..a6a5f42b47a 100644 --- a/src/hotspot/cpu/riscv/icache_riscv.cpp +++ b/src/hotspot/cpu/riscv/icache_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,7 +30,15 @@ #define __ _masm-> static int icache_flush(address addr, int lines, int magic) { - os::icache_flush((long int) addr, (long int) (addr + (lines << ICache::log2_line_size))); + // To make a store to instruction memory visible to all RISC-V harts, + // the writing hart has to execute a data FENCE before requesting that + // all remote RISC-V harts execute a FENCE.I. + // + // No sush assurance is defined at the interface level of the builtin + // method, and so we should make sure it works. + __asm__ volatile("fence rw, rw" : : : "memory"); + + __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size)); return magic; } diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index c44b5e28318..bbccb8b6c55 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -555,7 +555,6 @@ void MacroAssembler::emit_static_call_stub() { // CompiledDirectStaticCall::set_to_interpreted knows the // exact layout of this stub. - ifence(); mov_metadata(xmethod, (Metadata*)NULL); // Jump to the entry point of the i2c stub. @@ -1668,7 +1667,6 @@ void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) { // nmethod entry barrier necessitate using the constant pool. They have to be // ordered with respected to oop access. - // Using immediate literals would necessitate fence.i. if (BarrierSet::barrier_set()->barrier_set_nmethod() != NULL || !immediate) { address dummy = address(uintptr_t(pc()) & -wordSize); // A nearby aligned address ld_constant(dst, Address(dummy, rspec)); @@ -2746,7 +2744,6 @@ void MacroAssembler::build_frame(int framesize) { sd(fp, Address(sp, framesize - 2 * wordSize)); sd(ra, Address(sp, framesize - wordSize)); if (PreserveFramePointer) { add(fp, sp, framesize); } - verify_cross_modify_fence_not_required(); } void MacroAssembler::remove_frame(int framesize) { @@ -2797,7 +2794,6 @@ address MacroAssembler::read_polling_page(Register r, int32_t offset, relocInfo: lwu(zr, Address(r, offset)); mark = inst_mark(); } - verify_cross_modify_fence_not_required(); return mark; } @@ -3981,29 +3977,3 @@ void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Registe neg(dst, dst); bind(done); } - -void MacroAssembler::safepoint_ifence() { - ifence(); -#ifndef PRODUCT - if (VerifyCrossModifyFence) { - // Clear the thread state. - sb(zr, Address(xthread, in_bytes(JavaThread::requires_cross_modify_fence_offset()))); - } -#endif -} - -#ifndef PRODUCT -void MacroAssembler::verify_cross_modify_fence_not_required() { - if (VerifyCrossModifyFence) { - // Check if thread needs a cross modify fence. - lbu(t0, Address(xthread, in_bytes(JavaThread::requires_cross_modify_fence_offset()))); - Label fence_not_required; - beqz(t0, fence_not_required); - // If it does then fail. - la(t0, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::verify_cross_modify_fence_failure))); - mv(c_rarg0, xthread); - jalr(t0); - bind(fence_not_required); - } -} -#endif diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 8451c8495e2..8c315eff18e 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -46,9 +46,6 @@ class MacroAssembler: public Assembler { void safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod); - // Place a fence.i after code may have been modified due to a safepoint. - void safepoint_ifence(); - // Alignment void align(int modulus, int extra_offset = 0); @@ -836,9 +833,6 @@ private: void load_reserved(Register addr, enum operand_size size, Assembler::Aqrl acquire); void store_conditional(Register addr, Register new_val, enum operand_size size, Assembler::Aqrl release); - - // Check the current thread doesn't need a cross modify fence. - void verify_cross_modify_fence_not_required() PRODUCT_RETURN; }; #ifdef ASSERT diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.hpp b/src/hotspot/cpu/riscv/nativeInst_riscv.hpp index 02d48d4657f..3f0618fc257 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.hpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.hpp @@ -42,7 +42,6 @@ // - - NativeIllegalInstruction // - - NativeCallTrampolineStub // - - NativeMembar -// - - NativeFenceI // The base class for different kinds of native instruction abstractions. // Provides the primitive operations to manipulate code relative to this. @@ -554,14 +553,6 @@ inline NativeMembar *NativeMembar_at(address addr) { return (NativeMembar*)addr; } -class NativeFenceI : public NativeInstruction { -public: - static inline int instruction_size() { - // 2 for fence.i + fence - return (UseConservativeFence ? 2 : 1) * NativeInstruction::instruction_size; - } -}; - class NativePostCallNop: public NativeInstruction { public: bool check() const { return is_nop(); } diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 2d34774556f..dd5bbe7cba5 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -354,10 +354,6 @@ static void patch_callers_callsite(MacroAssembler *masm) { __ la_patchable(t0, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)), offset); __ jalr(x1, t0, offset); - // Explicit fence.i required because fixup_callers_callsite may change the code - // stream. - __ safepoint_ifence(); - __ pop_CPU_state(); // restore sp __ leave(); diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 559f8b5e4ea..02133dbb595 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,13 +25,11 @@ #include "precompiled.hpp" #include "runtime/java.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/vm_version.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/macros.hpp" -#include OS_HEADER_INLINE(os) - const char* VM_Version::_uarch = ""; uint32_t VM_Version::_initial_vector_length = 0; diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 981a26dedeb..58c4428bf73 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -896,6 +896,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) { tail_size = 1; break; + case 0x10: // movups + case 0x11: // movups case 0x12: // movlps case 0x28: // movaps case 0x2E: // ucomiss @@ -2561,10 +2563,22 @@ void Assembler::movddup(XMMRegister dst, XMMRegister src) { emit_int16(0x12, 0xC0 | encode); } +void Assembler::movddup(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse3(), "")); + InstructionMark im(this); + InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_DUP, /* input_size_in_bits */ EVEX_64bit); + attributes.set_rex_vex_w_reverted(); + simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + emit_int8(0x12); + emit_operand(dst, src); +} + void Assembler::vmovddup(XMMRegister dst, Address src, int vector_len) { assert(VM_Version::supports_avx(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_DUP, /* input_size_in_bits */ EVEX_64bit); attributes.set_rex_vex_w_reverted(); simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); emit_int8(0x12); @@ -3505,6 +3519,46 @@ void Assembler::movswl(Register dst, Register src) { // movsxw emit_int24(0x0F, (unsigned char)0xBF, (0xC0 | encode)); } +void Assembler::movups(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_32bit); + simd_prefix(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); + emit_int8(0x10); + emit_operand(dst, src); +} + +void Assembler::vmovups(XMMRegister dst, Address src, int vector_len) { + assert(vector_len == AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), ""); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_32bit); + simd_prefix(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); + emit_int8(0x10); + emit_operand(dst, src); +} + +void Assembler::movups(Address dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse(), "")); + InstructionMark im(this); + InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_32bit); + simd_prefix(src, xnoreg, dst, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); + emit_int8(0x11); + emit_operand(src, dst); +} + +void Assembler::vmovups(Address dst, XMMRegister src, int vector_len) { + assert(vector_len == AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), ""); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_32bit); + simd_prefix(src, xnoreg, dst, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); + emit_int8(0x11); + emit_operand(src, dst); +} + void Assembler::movw(Address dst, int imm16) { InstructionMark im(this); @@ -5156,7 +5210,7 @@ void Assembler::evshufi64x2(XMMRegister dst, XMMRegister nds, XMMRegister src, i emit_int24(0x43, (0xC0 | encode), imm8 & 0xFF); } -void Assembler::pshufpd(XMMRegister dst, XMMRegister src, int imm8) { +void Assembler::shufpd(XMMRegister dst, XMMRegister src, int imm8) { assert(isByte(imm8), "invalid value"); NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); @@ -5164,14 +5218,14 @@ void Assembler::pshufpd(XMMRegister dst, XMMRegister src, int imm8) { emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF); } -void Assembler::vpshufpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) { +void Assembler::vshufpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) { InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_rex_vex_w_reverted(); int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF); } -void Assembler::pshufps(XMMRegister dst, XMMRegister src, int imm8) { +void Assembler::shufps(XMMRegister dst, XMMRegister src, int imm8) { assert(isByte(imm8), "invalid value"); NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); @@ -5179,7 +5233,7 @@ void Assembler::pshufps(XMMRegister dst, XMMRegister src, int imm8) { emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF); } -void Assembler::vpshufps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) { +void Assembler::vshufps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) { InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF); @@ -7993,10 +8047,6 @@ void Assembler::evprolq(XMMRegister dst, XMMRegister src, int shift, int vector_ emit_int24(0x72, (0xC0 | encode), shift & 0xFF); } -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for xmm0. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED void Assembler::evprord(XMMRegister dst, XMMRegister src, int shift, int vector_len) { assert(VM_Version::supports_evex(), "requires EVEX support"); assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support"); @@ -8014,7 +8064,6 @@ void Assembler::evprorq(XMMRegister dst, XMMRegister src, int shift, int vector_ int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int24(0x72, (0xC0 | encode), shift & 0xFF); } -PRAGMA_DIAG_POP void Assembler::evprolvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) { assert(VM_Version::supports_evex(), "requires EVEX support"); @@ -11566,10 +11615,6 @@ void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address emit_int8((unsigned char)comparison); } -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for xmm0. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED void Assembler::evprord(XMMRegister dst, KRegister mask, XMMRegister src, int shift, bool merge, int vector_len) { assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); @@ -11593,7 +11638,6 @@ void Assembler::evprorq(XMMRegister dst, KRegister mask, XMMRegister src, int sh int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int24(0x72, (0xC0 | encode), shift & 0xFF); } -PRAGMA_DIAG_POP void Assembler::evprorvd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) { assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), ""); diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 901a6330494..66605cc2bca 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -1492,6 +1492,7 @@ private: void movb(Register dst, Address src); void movddup(XMMRegister dst, XMMRegister src); + void movddup(XMMRegister dst, Address src); void vmovddup(XMMRegister dst, Address src, int vector_len); void kandbl(KRegister dst, KRegister src1, KRegister src2); @@ -1663,6 +1664,11 @@ private: void movswq(Register dst, Register src); #endif + void movups(XMMRegister dst, Address src); + void vmovups(XMMRegister dst, Address src, int vector_len); + void movups(Address dst, XMMRegister src); + void vmovups(Address dst, XMMRegister src, int vector_len); + void movw(Address dst, int imm16); void movw(Register dst, Address src); void movw(Address dst, Register src); @@ -1942,10 +1948,10 @@ private: void pshuflw(XMMRegister dst, Address src, int mode); //shuffle floats and doubles - void pshufps(XMMRegister, XMMRegister, int); - void pshufpd(XMMRegister, XMMRegister, int); - void vpshufps(XMMRegister, XMMRegister, XMMRegister, int, int); - void vpshufpd(XMMRegister, XMMRegister, XMMRegister, int, int); + void shufps(XMMRegister, XMMRegister, int); + void shufpd(XMMRegister, XMMRegister, int); + void vshufps(XMMRegister, XMMRegister, XMMRegister, int, int); + void vshufpd(XMMRegister, XMMRegister, XMMRegister, int, int); // Shuffle packed values at 128 bit granularity void evshufi64x2(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len); diff --git a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp index 011e62739b3..87c87f069e2 100644 --- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp +++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp @@ -320,10 +320,6 @@ enum reg_save_layout { // describe FPU registers. In all other cases it should be sufficient // to simply save their current value. // -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for rax. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, bool save_fpu_registers = true) { @@ -418,7 +414,6 @@ static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, return map; } -PRAGMA_DIAG_POP #define __ this-> diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 8284cd071c2..f6fa13b620a 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1643,12 +1643,12 @@ void C2_MacroAssembler::load_vector_mask(KRegister dst, XMMRegister src, XMMRegi void C2_MacroAssembler::load_vector(XMMRegister dst, Address src, int vlen_in_bytes) { switch (vlen_in_bytes) { - case 4: movdl(dst, src); break; - case 8: movq(dst, src); break; - case 16: movdqu(dst, src); break; - case 32: vmovdqu(dst, src); break; - case 64: evmovdquq(dst, src, Assembler::AVX_512bit); break; - default: ShouldNotReachHere(); + case 4: movdl(dst, src); break; + case 8: movq(dst, src); break; + case 16: movdqu(dst, src); break; + case 32: vmovdqu(dst, src); break; + case 64: evmovdqul(dst, src, Assembler::AVX_512bit); break; + default: ShouldNotReachHere(); } } @@ -1661,6 +1661,38 @@ void C2_MacroAssembler::load_vector(XMMRegister dst, AddressLiteral src, int vle } } +void C2_MacroAssembler::load_constant_vector(BasicType bt, XMMRegister dst, InternalAddress src, int vlen) { + int vlen_enc = vector_length_encoding(vlen); + if (VM_Version::supports_avx()) { + if (bt == T_LONG) { + if (VM_Version::supports_avx2()) { + vpbroadcastq(dst, src, vlen_enc, noreg); + } else { + vmovddup(dst, src, vlen_enc, noreg); + } + } else if (bt == T_DOUBLE) { + if (vlen_enc != Assembler::AVX_128bit) { + vbroadcastsd(dst, src, vlen_enc, noreg); + } else { + vmovddup(dst, src, vlen_enc, noreg); + } + } else { + if (VM_Version::supports_avx2() && is_integral_type(bt)) { + vpbroadcastd(dst, src, vlen_enc, noreg); + } else { + vbroadcastss(dst, src, vlen_enc, noreg); + } + } + } else if (VM_Version::supports_sse3()) { + movddup(dst, src); + } else { + movq(dst, src); + if (vlen == 16) { + punpcklqdq(dst, dst); + } + } +} + void C2_MacroAssembler::load_iota_indices(XMMRegister dst, Register scratch, int vlen_in_bytes) { ExternalAddress addr(StubRoutines::x86::vector_iota_indices()); if (vlen_in_bytes <= 4) { @@ -2317,9 +2349,9 @@ void C2_MacroAssembler::get_elem(BasicType typ, XMMRegister dst, XMMRegister src if (typ == T_FLOAT) { if (UseAVX == 0) { movdqu(dst, src); - pshufps(dst, dst, eindex); + shufps(dst, dst, eindex); } else { - vpshufps(dst, src, src, eindex, Assembler::AVX_128bit); + vshufps(dst, src, src, eindex, Assembler::AVX_128bit); } } else { if (UseAVX == 0) { diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index 21b294a7ff7..dd9a401dbbe 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -159,6 +159,7 @@ public: void load_vector(XMMRegister dst, Address src, int vlen_in_bytes); void load_vector(XMMRegister dst, AddressLiteral src, int vlen_in_bytes, Register rscratch = rscratch1); + void load_constant_vector(BasicType bt, XMMRegister dst, InternalAddress src, int vlen); void load_iota_indices(XMMRegister dst, Register scratch, int vlen_in_bytes); // Reductions for vectors of bytes, shorts, ints, longs, floats, and doubles. diff --git a/src/hotspot/cpu/x86/frame_x86.inline.hpp b/src/hotspot/cpu/x86/frame_x86.inline.hpp index 24396304818..6b228f4a52a 100644 --- a/src/hotspot/cpu/x86/frame_x86.inline.hpp +++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp @@ -322,10 +322,6 @@ inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { // Compiled frames -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for rax. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED inline oop frame::saved_oop_result(RegisterMap* map) const { oop* result_adr = (oop *)map->location(rax->as_VMReg(), sp()); guarantee(result_adr != NULL, "bad register save location"); @@ -338,7 +334,6 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { *result_adr = obj; } -PRAGMA_DIAG_POP inline bool frame::is_interpreted_frame() const { return Interpreter::contains(pc()); diff --git a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp index 00071d66da3..c93d1d4de6f 100644 --- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp @@ -466,10 +466,6 @@ private: _spill_offset += 8; } -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for rax. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED void initialize(ZLoadBarrierStubC2* stub) { // Create mask of caller saved registers that need to // be saved/restored if live @@ -545,7 +541,6 @@ PRAGMA_NONNULL_IGNORED // Stack pointer must be 16 bytes aligned for the call _spill_offset = _spill_size = align_up(xmm_spill_size + gp_spill_size + opmask_spill_size + arg_spill_size, 16); } -PRAGMA_DIAG_POP public: ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) : diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index c0c5c55b483..cc920b228e8 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1122,7 +1122,7 @@ void InterpreterMacroAssembler::remove_activation( bind(loop); // check if current entry is used - cmpptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL); + cmpptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD); jcc(Assembler::notEqual, exception); addptr(rmon, entry_size); // otherwise advance to next entry diff --git a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp index 31cc616dfce..7e390564f4c 100644 --- a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp +++ b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -348,10 +348,10 @@ class SlowSignatureHandler intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); _from -= Interpreter::stackElementSize; if (_num_args < Argument::n_int_register_parameters_c-1) { - *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; + *_reg_args++ = (*from_addr == 0) ? NULL_WORD : (intptr_t) from_addr; _num_args++; } else { - *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; + *_to++ = (*from_addr == 0) ? NULL_WORD : (intptr_t) from_addr; } } @@ -443,10 +443,10 @@ class SlowSignatureHandler _from -= Interpreter::stackElementSize; if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr; + *_int_args++ = (*from_addr == 0) ? NULL_WORD : (intptr_t)from_addr; _num_int_args++; } else { - *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; + *_to++ = (*from_addr == 0) ? NULL_WORD : (intptr_t) from_addr; } } diff --git a/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp b/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp index 1eb740f3877..22052c83578 100644 --- a/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp +++ b/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safepoint.hpp" #include "runtime/stubRoutines.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 4660ac22e31..746c2d115e3 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -2732,6 +2732,15 @@ void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { } } +void MacroAssembler::movddup(XMMRegister dst, AddressLiteral src, Register rscratch) { + if (reachable(src)) { + Assembler::movddup(dst, as_Address(src)); + } else { + lea(rscratch, src); + Assembler::movddup(dst, Address(rscratch, 0)); + } +} + void MacroAssembler::vmovddup(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch) { if (reachable(src)) { Assembler::vmovddup(dst, as_Address(src), vector_len); @@ -3288,9 +3297,13 @@ void MacroAssembler::vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, } } -void MacroAssembler::vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len) { - assert(((dst->encoding() < 16 && src->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15"); - Assembler::vpbroadcastw(dst, src, vector_len); +void MacroAssembler::vpbroadcastd(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch) { + if (reachable(src)) { + Assembler::vpbroadcastd(dst, as_Address(src), vector_len); + } else { + lea(rscratch, src); + Assembler::vpbroadcastd(dst, Address(rscratch, 0), vector_len); + } } void MacroAssembler::vpbroadcastq(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch) { @@ -3311,6 +3324,15 @@ void MacroAssembler::vbroadcastsd(XMMRegister dst, AddressLiteral src, int vecto } } +void MacroAssembler::vbroadcastss(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch) { + if (reachable(src)) { + Assembler::vbroadcastss(dst, as_Address(src), vector_len); + } else { + lea(rscratch, src); + Assembler::vbroadcastss(dst, Address(rscratch, 0), vector_len); + } +} + void MacroAssembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(((dst->encoding() < 16 && src->encoding() < 16 && nds->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15"); Assembler::vpcmpeqb(dst, nds, src, vector_len); @@ -4354,10 +4376,14 @@ void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file, void MacroAssembler::vallones(XMMRegister dst, int vector_len) { if (UseAVX > 2 && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl())) { + // Only pcmpeq has dependency breaking treatment (i.e the execution can begin without + // waiting for the previous result on dst), not vpcmpeqd, so just use vpternlog vpternlogd(dst, 0xFF, dst, dst, vector_len); + } else if (VM_Version::supports_avx()) { + vpcmpeqd(dst, dst, dst, vector_len); } else { - assert(UseAVX > 0, ""); - vpcmpeqb(dst, dst, dst, vector_len); + assert(VM_Version::supports_sse2(), ""); + pcmpeqd(dst, dst); } } diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index 998903f5797..e01a1d591dc 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -1114,6 +1114,12 @@ public: void addpd(XMMRegister dst, Address src) { Assembler::addpd(dst, src); } void addpd(XMMRegister dst, AddressLiteral src); + using Assembler::vbroadcastsd; + void vbroadcastsd(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); + + using Assembler::vbroadcastss; + void vbroadcastss(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); + void divsd(XMMRegister dst, XMMRegister src) { Assembler::divsd(dst, src); } void divsd(XMMRegister dst, Address src) { Assembler::divsd(dst, src); } void divsd(XMMRegister dst, AddressLiteral src); @@ -1150,6 +1156,11 @@ public: void kmov(Register dst, KRegister src); void kmov(KRegister dst, Register src); + using Assembler::movddup; + void movddup(XMMRegister dst, AddressLiteral src, Register rscratch = rscratch1); + using Assembler::vmovddup; + void vmovddup(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); + // AVX Unaligned forms void vmovdqu(Address dst, XMMRegister src); void vmovdqu(XMMRegister dst, Address src); @@ -1157,7 +1168,6 @@ public: void vmovdqu(XMMRegister dst, AddressLiteral src, Register scratch_reg = rscratch1); void vmovdqu(XMMRegister dst, AddressLiteral src, Register scratch_reg, int vector_len); - // AVX512 Unaligned void evmovdqu(BasicType type, KRegister kmask, Address dst, XMMRegister src, bool merge, int vector_len); void evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, Address src, bool merge, int vector_len); @@ -1229,9 +1239,6 @@ public: void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } void movsd(XMMRegister dst, AddressLiteral src); - using Assembler::vmovddup; - void vmovddup(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); - void mulpd(XMMRegister dst, XMMRegister src) { Assembler::mulpd(dst, src); } void mulpd(XMMRegister dst, Address src) { Assembler::mulpd(dst, src); } void mulpd(XMMRegister dst, AddressLiteral src); @@ -1337,16 +1344,11 @@ public: void vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vpand(dst, nds, src, vector_len); } void vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1); - void vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len); - void vpbroadcastw(XMMRegister dst, Address src, int vector_len) { Assembler::vpbroadcastw(dst, src, vector_len); } + using Assembler::vpbroadcastd; + void vpbroadcastd(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); - using Assembler::vbroadcastsd; - void vbroadcastsd(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); + using Assembler::vpbroadcastq; void vpbroadcastq(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); - void vpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len) { Assembler::vpbroadcastq(dst, src, vector_len); } - void vpbroadcastq(XMMRegister dst, Address src, int vector_len) { Assembler::vpbroadcastq(dst, src, vector_len); } - - void vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); diff --git a/src/hotspot/cpu/x86/rdtsc_x86.cpp b/src/hotspot/cpu/x86/rdtsc_x86.cpp index 120ca8124c1..8a927dd15e4 100644 --- a/src/hotspot/cpu/x86/rdtsc_x86.cpp +++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,12 +26,10 @@ #include "rdtsc_x86.hpp" #include "runtime/globals_extension.hpp" #include "runtime/javaThread.hpp" +#include "runtime/os.inline.hpp" #include "runtime/orderAccess.hpp" #include "vm_version_x86.hpp" -// The following header contains the implementations of rdtsc() -#include OS_CPU_HEADER_INLINE(os) - static jlong _epoch = 0; static bool rdtsc_elapsed_counter_enabled = false; static jlong tsc_frequency = 0; diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index 9266d1897b2..a26cd61298d 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -171,10 +171,6 @@ class RegisterSaver { static void restore_result_registers(MacroAssembler* masm); }; -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for rax. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_wide_vectors) { int off = 0; int num_xmm_regs = XMMRegisterImpl::available_xmm_registers(); @@ -365,7 +361,6 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ return map; } -PRAGMA_DIAG_POP void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_wide_vectors) { int num_xmm_regs = XMMRegisterImpl::available_xmm_registers(); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index b4befba12fa..327bdfab287 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -529,7 +529,7 @@ class StubGenerator: public StubCodeGenerator { // make sure this code is only executed if there is a pending exception { Label L; - __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL); + __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); __ jcc(Assembler::notEqual, L); __ stop("StubRoutines::forward exception: no pending exception (1)"); __ bind(L); diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index 850668f3129..45002227372 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -164,10 +164,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr __ block_comment("} restore_callee_saved_regs "); } -// Register is a class, but it would be assigned numerical value. -// "0" is assigned for rax and for xmm0. Thus we need to ignore -Wnonnull. -PRAGMA_DIAG_PUSH -PRAGMA_NONNULL_IGNORED + address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, BasicType* in_sig_bt, int total_in_args, BasicType* out_sig_bt, int total_out_args, @@ -398,4 +395,3 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, return blob->code_begin(); } -PRAGMA_DIAG_POP diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 377916422e2..e2191a837ed 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -33,14 +33,12 @@ #include "memory/universe.hpp" #include "runtime/globals_extension.hpp" #include "runtime/java.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/vm_version.hpp" #include "utilities/powerOfTwo.hpp" #include "utilities/virtualizationSupport.hpp" -#include OS_HEADER_INLINE(os) - int VM_Version::_cpu; int VM_Version::_model; int VM_Version::_stepping; diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 31b5347a06d..c6e955290a7 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -4107,37 +4107,43 @@ instruct scatter_masked(memory mem, vec src, vec idx, kReg mask, kReg ktmp, rReg // ====================REPLICATE======================================= // Replicate byte scalar to be vector -instruct ReplB_reg(vec dst, rRegI src) %{ +instruct vReplB_reg(vec dst, rRegI src) %{ + predicate(UseAVX >= 2); match(Set dst (ReplicateB src)); format %{ "replicateB $dst,$src" %} ins_encode %{ uint vlen = Matcher::vector_length(this); + int vlen_enc = vector_length_encoding(this); if (vlen == 64 || VM_Version::supports_avx512vlbw()) { // AVX512VL for <512bit operands assert(VM_Version::supports_avx512bw(), "required"); // 512-bit byte vectors assume AVX512BW - int vlen_enc = vector_length_encoding(this); __ evpbroadcastb($dst$$XMMRegister, $src$$Register, vlen_enc); - } else if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); - __ movdl($dst$$XMMRegister, $src$$Register); - __ vpbroadcastb($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); } else { __ movdl($dst$$XMMRegister, $src$$Register); - __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); - __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); - if (vlen >= 16) { - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - if (vlen >= 32) { - assert(vlen == 32, "sanity"); - __ vinserti128_high($dst$$XMMRegister, $dst$$XMMRegister); - } - } + __ vpbroadcastb($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); + } + %} + ins_pipe( pipe_slow ); +%} + +instruct ReplB_reg(vec dst, rRegI src) %{ + predicate(UseAVX < 2); + match(Set dst (ReplicateB src)); + format %{ "replicateB $dst,$src" %} + ins_encode %{ + uint vlen = Matcher::vector_length(this); + __ movdl($dst$$XMMRegister, $src$$Register); + __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); + __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); + if (vlen >= 16) { + assert(vlen == 16, ""); + __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( pipe_slow ); %} instruct ReplB_mem(vec dst, memory mem) %{ - predicate(VM_Version::supports_avx2()); + predicate(UseAVX >= 2); match(Set dst (ReplicateB (LoadB mem))); format %{ "replicateB $dst,$mem" %} ins_encode %{ @@ -4147,48 +4153,45 @@ instruct ReplB_mem(vec dst, memory mem) %{ ins_pipe( pipe_slow ); %} -instruct ReplB_imm(vec dst, immI con) %{ - match(Set dst (ReplicateB con)); - format %{ "replicateB $dst,$con" %} - ins_encode %{ - InternalAddress addr = $constantaddress(T_BYTE, vreplicate_imm(T_BYTE, $con$$constant, Matcher::vector_length(this))); - __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); - %} - ins_pipe( pipe_slow ); -%} - // ====================ReplicateS======================================= -instruct ReplS_reg(vec dst, rRegI src) %{ +instruct vReplS_reg(vec dst, rRegI src) %{ + predicate(UseAVX >= 2); match(Set dst (ReplicateS src)); format %{ "replicateS $dst,$src" %} ins_encode %{ uint vlen = Matcher::vector_length(this); + int vlen_enc = vector_length_encoding(this); if (vlen == 32 || VM_Version::supports_avx512vlbw()) { // AVX512VL for <512bit operands assert(VM_Version::supports_avx512bw(), "required"); // 512-bit short vectors assume AVX512BW - int vlen_enc = vector_length_encoding(this); __ evpbroadcastw($dst$$XMMRegister, $src$$Register, vlen_enc); - } else if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); - __ movdl($dst$$XMMRegister, $src$$Register); - __ vpbroadcastw($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); } else { __ movdl($dst$$XMMRegister, $src$$Register); - __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); - if (vlen >= 8) { - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - if (vlen >= 16) { - assert(vlen == 16, "sanity"); - __ vinserti128_high($dst$$XMMRegister, $dst$$XMMRegister); - } - } + __ vpbroadcastw($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); + } + %} + ins_pipe( pipe_slow ); +%} + +instruct ReplS_reg(vec dst, rRegI src) %{ + predicate(UseAVX < 2); + match(Set dst (ReplicateS src)); + format %{ "replicateS $dst,$src" %} + ins_encode %{ + uint vlen = Matcher::vector_length(this); + int vlen_enc = vector_length_encoding(this); + __ movdl($dst$$XMMRegister, $src$$Register); + __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); + if (vlen >= 8) { + assert(vlen == 8, ""); + __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( pipe_slow ); %} instruct ReplS_mem(vec dst, memory mem) %{ - predicate(VM_Version::supports_avx2()); + predicate(UseAVX >= 2); match(Set dst (ReplicateS (LoadS mem))); format %{ "replicateS $dst,$mem" %} ins_encode %{ @@ -4198,16 +4201,6 @@ instruct ReplS_mem(vec dst, memory mem) %{ ins_pipe( pipe_slow ); %} -instruct ReplS_imm(vec dst, immI con) %{ - match(Set dst (ReplicateS con)); - format %{ "replicateS $dst,$con" %} - ins_encode %{ - InternalAddress addr = $constantaddress(T_SHORT, vreplicate_imm(T_SHORT, $con$$constant, Matcher::vector_length(this))); - __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); - %} - ins_pipe( pipe_slow ); -%} - // ====================ReplicateI======================================= instruct ReplI_reg(vec dst, rRegI src) %{ @@ -4215,20 +4208,15 @@ instruct ReplI_reg(vec dst, rRegI src) %{ format %{ "replicateI $dst,$src" %} ins_encode %{ uint vlen = Matcher::vector_length(this); + int vlen_enc = vector_length_encoding(this); if (vlen == 16 || VM_Version::supports_avx512vl()) { // AVX512VL for <512bit operands - int vlen_enc = vector_length_encoding(this); __ evpbroadcastd($dst$$XMMRegister, $src$$Register, vlen_enc); } else if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); __ movdl($dst$$XMMRegister, $src$$Register); __ vpbroadcastd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); } else { __ movdl($dst$$XMMRegister, $src$$Register); __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00); - if (vlen >= 8) { - assert(vlen == 8, "sanity"); - __ vinserti128_high($dst$$XMMRegister, $dst$$XMMRegister); - } } %} ins_pipe( pipe_slow ); @@ -4238,25 +4226,32 @@ instruct ReplI_mem(vec dst, memory mem) %{ match(Set dst (ReplicateI (LoadI mem))); format %{ "replicateI $dst,$mem" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen <= 4) { + int vlen_enc = vector_length_encoding(this); + if (VM_Version::supports_avx2()) { + __ vpbroadcastd($dst$$XMMRegister, $mem$$Address, vlen_enc); + } else if (VM_Version::supports_avx()) { + __ vbroadcastss($dst$$XMMRegister, $mem$$Address, vlen_enc); + } else { __ movdl($dst$$XMMRegister, $mem$$Address); __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00); - } else { - assert(VM_Version::supports_avx2(), "sanity"); - int vlen_enc = vector_length_encoding(this); - __ vpbroadcastd($dst$$XMMRegister, $mem$$Address, vlen_enc); } %} ins_pipe( pipe_slow ); %} instruct ReplI_imm(vec dst, immI con) %{ + match(Set dst (ReplicateB con)); + match(Set dst (ReplicateS con)); match(Set dst (ReplicateI con)); format %{ "replicateI $dst,$con" %} ins_encode %{ - InternalAddress addr = $constantaddress(T_INT, vreplicate_imm(T_INT, $con$$constant, Matcher::vector_length(this))); - __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); + InternalAddress addr = $constantaddress(Matcher::vector_element_basic_type(this), + vreplicate_imm(Matcher::vector_element_basic_type(this), $con$$constant, + (VM_Version::supports_sse3() ? (VM_Version::supports_avx() ? 4 : 8) : 8) / + type2aelembytes(Matcher::vector_element_basic_type(this)))); + BasicType bt = Matcher::vector_element_basic_type(this); + int vlen = Matcher::vector_length_in_bytes(this); + __ load_constant_vector(bt, $dst$$XMMRegister, addr, vlen); %} ins_pipe( pipe_slow ); %} @@ -4268,23 +4263,21 @@ instruct ReplI_zero(vec dst, immI_0 zero) %{ match(Set dst (ReplicateI zero)); format %{ "replicateI $dst,$zero" %} ins_encode %{ - uint vsize = Matcher::vector_length_in_bytes(this); - if (vsize <= 16) { - __ pxor($dst$$XMMRegister, $dst$$XMMRegister); - } else { - int vlen_enc = vector_length_encoding(this); + int vlen_enc = vector_length_encoding(this); + if (VM_Version::supports_evex() && !VM_Version::supports_avx512vl()) { __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); + } else { + __ pxor($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( fpu_reg_reg ); %} instruct ReplI_M1(vec dst, immI_M1 con) %{ - predicate(UseAVX > 0 && Matcher::vector_length_in_bytes(n) >= 16); + predicate(UseSSE >= 2); match(Set dst (ReplicateB con)); match(Set dst (ReplicateS con)); match(Set dst (ReplicateI con)); - effect(TEMP dst); format %{ "vallones $dst" %} ins_encode %{ int vector_len = vector_length_encoding(this); @@ -4301,23 +4294,16 @@ instruct ReplL_reg(vec dst, rRegL src) %{ match(Set dst (ReplicateL src)); format %{ "replicateL $dst,$src" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen == 2) { - __ movdq($dst$$XMMRegister, $src$$Register); - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - } else if (vlen == 8 || VM_Version::supports_avx512vl()) { // AVX512VL for <512bit operands - int vlen_enc = vector_length_encoding(this); + int vlen = Matcher::vector_length(this); + int vlen_enc = vector_length_encoding(this); + if (vlen == 8 || VM_Version::supports_avx512vl()) { // AVX512VL for <512bit operands __ evpbroadcastq($dst$$XMMRegister, $src$$Register, vlen_enc); } else if (VM_Version::supports_avx2()) { - assert(vlen == 4, "sanity"); - int vlen_enc = vector_length_encoding(this); __ movdq($dst$$XMMRegister, $src$$Register); __ vpbroadcastq($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); } else { - assert(vlen == 4, "sanity"); __ movdq($dst$$XMMRegister, $src$$Register); __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - __ vinserti128_high($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( pipe_slow ); @@ -4382,14 +4368,14 @@ instruct ReplL_mem(vec dst, memory mem) %{ match(Set dst (ReplicateL (LoadL mem))); format %{ "replicateL $dst,$mem" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen == 2) { + int vlen_enc = vector_length_encoding(this); + if (VM_Version::supports_avx2()) { + __ vpbroadcastq($dst$$XMMRegister, $mem$$Address, vlen_enc); + } else if (VM_Version::supports_sse3()) { + __ movddup($dst$$XMMRegister, $mem$$Address); + } else { __ movq($dst$$XMMRegister, $mem$$Address); __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - } else { - assert(VM_Version::supports_avx2(), "sanity"); - int vlen_enc = vector_length_encoding(this); - __ vpbroadcastq($dst$$XMMRegister, $mem$$Address, vlen_enc); } %} ins_pipe( pipe_slow ); @@ -4400,8 +4386,9 @@ instruct ReplL_imm(vec dst, immL con) %{ match(Set dst (ReplicateL con)); format %{ "replicateL $dst,$con" %} ins_encode %{ - InternalAddress addr = $constantaddress(T_LONG, vreplicate_imm(T_LONG, $con$$constant, Matcher::vector_length(this))); - __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); + InternalAddress addr = $constantaddress(T_LONG, vreplicate_imm(T_LONG, $con$$constant, 1)); + int vlen = Matcher::vector_length_in_bytes(this); + __ load_constant_vector(T_LONG, $dst$$XMMRegister, addr, vlen); %} ins_pipe( pipe_slow ); %} @@ -4410,21 +4397,19 @@ instruct ReplL_zero(vec dst, immL0 zero) %{ match(Set dst (ReplicateL zero)); format %{ "replicateL $dst,$zero" %} ins_encode %{ - int vlen = Matcher::vector_length(this); - if (vlen == 2) { - __ pxor($dst$$XMMRegister, $dst$$XMMRegister); - } else { - int vlen_enc = vector_length_encoding(this); + int vlen_enc = vector_length_encoding(this); + if (VM_Version::supports_evex() && !VM_Version::supports_avx512vl()) { __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); + } else { + __ pxor($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( fpu_reg_reg ); %} instruct ReplL_M1(vec dst, immL_M1 con) %{ - predicate(UseAVX > 0); + predicate(UseSSE >= 2); match(Set dst (ReplicateL con)); - effect(TEMP dst); format %{ "vallones $dst" %} ins_encode %{ int vector_len = vector_length_encoding(this); @@ -4435,38 +4420,43 @@ instruct ReplL_M1(vec dst, immL_M1 con) %{ // ====================ReplicateF======================================= -instruct ReplF_reg(vec dst, vlRegF src) %{ +instruct vReplF_reg(vec dst, vlRegF src) %{ + predicate(UseAVX > 0); match(Set dst (ReplicateF src)); format %{ "replicateF $dst,$src" %} ins_encode %{ uint vlen = Matcher::vector_length(this); + int vlen_enc = vector_length_encoding(this); if (vlen <= 4) { - __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00); - } else if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); + __ vpermilps($dst$$XMMRegister, $src$$XMMRegister, 0x00, Assembler::AVX_128bit); + } else if (VM_Version::supports_avx2()) { __ vbroadcastss($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); // reg-to-reg variant requires AVX2 } else { assert(vlen == 8, "sanity"); - __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00); + __ vpermilps($dst$$XMMRegister, $src$$XMMRegister, 0x00, Assembler::AVX_128bit); __ vinsertf128_high($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( pipe_slow ); %} +instruct ReplF_reg(vec dst, vlRegF src) %{ + predicate(UseAVX == 0); + match(Set dst (ReplicateF src)); + format %{ "replicateF $dst,$src" %} + ins_encode %{ + __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00); + %} + ins_pipe( pipe_slow ); +%} + instruct ReplF_mem(vec dst, memory mem) %{ + predicate(UseAVX > 0); match(Set dst (ReplicateF (LoadF mem))); format %{ "replicateF $dst,$mem" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen <= 4) { - __ movdl($dst$$XMMRegister, $mem$$Address); - __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00); - } else { - assert(VM_Version::supports_avx(), "sanity"); - int vlen_enc = vector_length_encoding(this); - __ vbroadcastss($dst$$XMMRegister, $mem$$Address, vlen_enc); - } + int vlen_enc = vector_length_encoding(this); + __ vbroadcastss($dst$$XMMRegister, $mem$$Address, vlen_enc); %} ins_pipe( pipe_slow ); %} @@ -4476,8 +4466,10 @@ instruct ReplF_imm(vec dst, immF con) %{ match(Set dst (ReplicateF con)); format %{ "replicateF $dst,$con" %} ins_encode %{ - InternalAddress addr = $constantaddress(T_FLOAT, vreplicate_imm(T_FLOAT, $con$$constant, Matcher::vector_length(this))); - __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); + InternalAddress addr = $constantaddress(T_FLOAT, vreplicate_imm(T_FLOAT, $con$$constant, + VM_Version::supports_sse3() ? (VM_Version::supports_avx() ? 1 : 2) : 2)); + int vlen = Matcher::vector_length_in_bytes(this); + __ load_constant_vector(T_FLOAT, $dst$$XMMRegister, addr, vlen); %} ins_pipe( pipe_slow ); %} @@ -4486,12 +4478,11 @@ instruct ReplF_zero(vec dst, immF0 zero) %{ match(Set dst (ReplicateF zero)); format %{ "replicateF $dst,$zero" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen <= 4) { - __ xorps($dst$$XMMRegister, $dst$$XMMRegister); + int vlen_enc = vector_length_encoding(this); + if (VM_Version::supports_evex() && !VM_Version::supports_avx512vldq()) { + __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); } else { - int vlen_enc = vector_length_encoding(this); - __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); // 512bit vxorps requires AVX512DQ + __ xorps($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( fpu_reg_reg ); @@ -4500,37 +4491,46 @@ instruct ReplF_zero(vec dst, immF0 zero) %{ // ====================ReplicateD======================================= // Replicate double (8 bytes) scalar to be vector -instruct ReplD_reg(vec dst, vlRegD src) %{ +instruct vReplD_reg(vec dst, vlRegD src) %{ + predicate(UseSSE >= 3); match(Set dst (ReplicateD src)); format %{ "replicateD $dst,$src" %} ins_encode %{ uint vlen = Matcher::vector_length(this); - if (vlen == 2) { - __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x44); + int vlen_enc = vector_length_encoding(this); + if (vlen <= 2) { + __ movddup($dst$$XMMRegister, $src$$XMMRegister); } else if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); __ vbroadcastsd($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); // reg-to-reg variant requires AVX2 } else { assert(vlen == 4, "sanity"); - __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x44); + __ movddup($dst$$XMMRegister, $src$$XMMRegister); __ vinsertf128_high($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( pipe_slow ); %} +instruct ReplD_reg(vec dst, vlRegD src) %{ + predicate(UseSSE < 3); + match(Set dst (ReplicateD src)); + format %{ "replicateD $dst,$src" %} + ins_encode %{ + __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x44); + %} + ins_pipe( pipe_slow ); +%} + instruct ReplD_mem(vec dst, memory mem) %{ + predicate(UseSSE >= 3); match(Set dst (ReplicateD (LoadD mem))); format %{ "replicateD $dst,$mem" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen == 2) { - __ movq($dst$$XMMRegister, $mem$$Address); - __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x44); - } else { - assert(VM_Version::supports_avx(), "sanity"); + if (Matcher::vector_length(this) >= 4) { int vlen_enc = vector_length_encoding(this); __ vbroadcastsd($dst$$XMMRegister, $mem$$Address, vlen_enc); + } else { + __ movddup($dst$$XMMRegister, $mem$$Address); } %} ins_pipe( pipe_slow ); @@ -4541,8 +4541,9 @@ instruct ReplD_imm(vec dst, immD con) %{ match(Set dst (ReplicateD con)); format %{ "replicateD $dst,$con" %} ins_encode %{ - InternalAddress addr = $constantaddress(T_DOUBLE, vreplicate_imm(T_DOUBLE, $con$$constant, Matcher::vector_length(this))); - __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); + InternalAddress addr = $constantaddress(T_DOUBLE, vreplicate_imm(T_DOUBLE, $con$$constant, 1)); + int vlen = Matcher::vector_length_in_bytes(this); + __ load_constant_vector(T_DOUBLE, $dst$$XMMRegister, addr, vlen); %} ins_pipe( pipe_slow ); %} @@ -4551,12 +4552,11 @@ instruct ReplD_zero(vec dst, immD0 zero) %{ match(Set dst (ReplicateD zero)); format %{ "replicateD $dst,$zero" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen == 2) { - __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); + int vlen_enc = vector_length_encoding(this); + if (VM_Version::supports_evex() && !VM_Version::supports_avx512vldq()) { + __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); } else { - int vlen_enc = vector_length_encoding(this); - __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); // 512bit vxorps requires AVX512DQ + __ xorps($dst$$XMMRegister, $dst$$XMMRegister); } %} ins_pipe( fpu_reg_reg ); @@ -8335,7 +8335,7 @@ instruct storeMask8B_avx(vec dst, vec src, immI_8 size, vec vtmp) %{ effect(TEMP_DEF dst, TEMP vtmp); ins_encode %{ int vlen_enc = Assembler::AVX_128bit; - __ vpshufps($dst$$XMMRegister, $src$$XMMRegister, $src$$XMMRegister, 0x88, Assembler::AVX_256bit); + __ vshufps($dst$$XMMRegister, $src$$XMMRegister, $src$$XMMRegister, 0x88, Assembler::AVX_256bit); __ vextracti128($vtmp$$XMMRegister, $dst$$XMMRegister, 0x1); __ vblendps($dst$$XMMRegister, $dst$$XMMRegister, $vtmp$$XMMRegister, 0xC, vlen_enc); __ vpxor($vtmp$$XMMRegister, $vtmp$$XMMRegister, $vtmp$$XMMRegister, vlen_enc); diff --git a/src/hotspot/os/aix/attachListener_aix.cpp b/src/hotspot/os/aix/attachListener_aix.cpp index 6ef5c44ec71..b5b204258c8 100644 --- a/src/hotspot/os/aix/attachListener_aix.cpp +++ b/src/hotspot/os/aix/attachListener_aix.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" +#include "os_posix.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/os.inline.hpp" #include "services/attachListener.hpp" diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 1cd6249d107..acea86bbb14 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -45,6 +45,7 @@ #include "misc_aix.hpp" #include "oops/oop.inline.hpp" #include "os_aix.inline.hpp" +#include "os_posix.hpp" #include "porting_aix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" diff --git a/src/hotspot/os/aix/os_aix.hpp b/src/hotspot/os/aix/os_aix.hpp index 67c52a9208b..7e1d72a8f55 100644 --- a/src/hotspot/os/aix/os_aix.hpp +++ b/src/hotspot/os/aix/os_aix.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,12 +26,11 @@ #ifndef OS_AIX_OS_AIX_HPP #define OS_AIX_OS_AIX_HPP -// Information about the protection of the page at address '0' on this os. -static bool zero_page_read_protected() { return false; } +#include "runtime/os.hpp" // Class Aix defines the interface to the Aix operating systems. -class Aix { +class os::Aix { friend class os; private: @@ -177,6 +176,9 @@ class Aix { // (on AIX, using libperfstat, on PASE with libo4.so). // Returns true if ok, false if error. static bool get_meminfo(meminfo_t* pmi); + + static bool platform_print_native_stack(outputStream* st, void* context, char *buf, int buf_size); + static void* resolve_function_descriptor(void* p); }; #endif // OS_AIX_OS_AIX_HPP diff --git a/src/hotspot/os/aix/os_aix.inline.hpp b/src/hotspot/os/aix/os_aix.inline.hpp index a15982ff925..edc50a9fae4 100644 --- a/src/hotspot/os/aix/os_aix.inline.hpp +++ b/src/hotspot/os/aix/os_aix.inline.hpp @@ -26,11 +26,16 @@ #ifndef OS_AIX_OS_AIX_INLINE_HPP #define OS_AIX_OS_AIX_INLINE_HPP -// os_aix.hpp included by os.hpp +#include "os_aix.hpp" #include "runtime/os.hpp" #include "os_posix.inline.hpp" +// Information about the protection of the page at address '0' on this os. +inline bool os::zero_page_read_protected() { + return false; +} + inline bool os::uses_stack_guard_pages() { return true; } diff --git a/src/hotspot/os/bsd/attachListener_bsd.cpp b/src/hotspot/os/bsd/attachListener_bsd.cpp index 395f1e44472..7999210bc3e 100644 --- a/src/hotspot/os/bsd/attachListener_bsd.cpp +++ b/src/hotspot/os/bsd/attachListener_bsd.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" +#include "os_posix.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/os.inline.hpp" #include "services/attachListener.hpp" diff --git a/src/hotspot/os/bsd/os_bsd.hpp b/src/hotspot/os/bsd/os_bsd.hpp index e61469290f4..2bd9e42c09d 100644 --- a/src/hotspot/os/bsd/os_bsd.hpp +++ b/src/hotspot/os/bsd/os_bsd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,11 @@ #ifndef OS_BSD_OS_BSD_HPP #define OS_BSD_OS_BSD_HPP +#include "runtime/os.hpp" + // Bsd_OS defines the interface to Bsd operating systems -// Information about the protection of the page at address '0' on this os. -static bool zero_page_read_protected() { return true; } - -class Bsd { +class os::Bsd { friend class os; #ifdef __APPLE__ diff --git a/src/hotspot/os/bsd/os_bsd.inline.hpp b/src/hotspot/os/bsd/os_bsd.inline.hpp index 0b9fc65b0d8..ba8edb0d462 100644 --- a/src/hotspot/os/bsd/os_bsd.inline.hpp +++ b/src/hotspot/os/bsd/os_bsd.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,15 @@ #ifndef OS_BSD_OS_BSD_INLINE_HPP #define OS_BSD_OS_BSD_INLINE_HPP -// os_bsd.hpp included by os.hpp +#include "os_bsd.hpp" #include "runtime/os.hpp" #include "os_posix.inline.hpp" +inline bool os::zero_page_read_protected() { + return true; +} + inline bool os::uses_stack_guard_pages() { return true; } diff --git a/src/hotspot/os/linux/attachListener_linux.cpp b/src/hotspot/os/linux/attachListener_linux.cpp index f51734f658c..0f7c45d9214 100644 --- a/src/hotspot/os/linux/attachListener_linux.cpp +++ b/src/hotspot/os/linux/attachListener_linux.cpp @@ -27,6 +27,7 @@ #include "memory/allocation.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/os.inline.hpp" +#include "os_posix.hpp" #include "services/attachListener.hpp" #include diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp index b9775711a13..f98f4c54758 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp @@ -30,6 +30,7 @@ #include "cgroupV2Subsystem_linux.hpp" #include "logging/log.hpp" #include "memory/allocation.hpp" +#include "os_linux.hpp" #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp b/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp index cfe25549ffc..c5ba06ea8b7 100644 --- a/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #include "gc/z/zErrno.hpp" #include "gc/z/zNUMA.hpp" #include "gc/z/zSyscall_linux.hpp" +#include "os_linux.hpp" #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index 3562243cb82..1538764bad7 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -32,6 +32,7 @@ #include "gc/z/zPhysicalMemoryBacking_linux.hpp" #include "gc/z/zSyscall_linux.hpp" #include "logging/log.hpp" +#include "os_linux.hpp" #include "runtime/init.hpp" #include "runtime/os.hpp" #include "runtime/safefetch.hpp" diff --git a/src/hotspot/os/linux/osContainer_linux.cpp b/src/hotspot/os/linux/osContainer_linux.cpp index 9ae6534d3c4..d6f0d627fdf 100644 --- a/src/hotspot/os/linux/osContainer_linux.cpp +++ b/src/hotspot/os/linux/osContainer_linux.cpp @@ -28,6 +28,7 @@ #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "logging/log.hpp" +#include "os_linux.hpp" #include "osContainer_linux.hpp" #include "cgroupSubsystem_linux.hpp" diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index b1c580e7643..ed0a15ebb64 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -4455,6 +4455,89 @@ void os::Linux::numa_init() { } } +#if defined(IA32) && !defined(ZERO) +/* + * Work-around (execute code at a high address) for broken NX emulation using CS limit, + * Red Hat patch "Exec-Shield" (IA32 only). + * + * Map and execute at a high VA to prevent CS lazy updates race with SMP MM + * invalidation.Further code generation by the JVM will no longer cause CS limit + * updates. + * + * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04. + * @see JDK-8023956 + */ +static void workaround_expand_exec_shield_cs_limit() { + assert(os::Linux::initial_thread_stack_bottom() != NULL, "sanity"); + size_t page_size = os::vm_page_size(); + + /* + * JDK-8197429 + * + * Expand the stack mapping to the end of the initial stack before + * attempting to install the codebuf. This is needed because newer + * Linux kernels impose a distance of a megabyte between stack + * memory and other memory regions. If we try to install the + * codebuf before expanding the stack the installation will appear + * to succeed but we'll get a segfault later if we expand the stack + * in Java code. + * + */ + if (os::is_primordial_thread()) { + address limit = os::Linux::initial_thread_stack_bottom(); + if (! DisablePrimordialThreadGuardPages) { + limit += StackOverflow::stack_red_zone_size() + + StackOverflow::stack_yellow_zone_size(); + } + os::Linux::expand_stack_to(limit); + } + + /* + * Take the highest VA the OS will give us and exec + * + * Although using -(pagesz) as mmap hint works on newer kernel as you would + * think, older variants affected by this work-around don't (search forward only). + * + * On the affected distributions, we understand the memory layout to be: + * + * TASK_LIMIT= 3G, main stack base close to TASK_LIMT. + * + * A few pages south main stack will do it. + * + * If we are embedded in an app other than launcher (initial != main stack), + * we don't have much control or understanding of the address space, just let it slide. + */ + char* hint = (char*)(os::Linux::initial_thread_stack_bottom() - + (StackOverflow::stack_guard_zone_size() + page_size)); + char* codebuf = os::attempt_reserve_memory_at(hint, page_size); + + if (codebuf == NULL) { + // JDK-8197429: There may be a stack gap of one megabyte between + // the limit of the stack and the nearest memory region: this is a + // Linux kernel workaround for CVE-2017-1000364. If we failed to + // map our codebuf, try again at an address one megabyte lower. + hint -= 1 * M; + codebuf = os::attempt_reserve_memory_at(hint, page_size); + } + + if ((codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true))) { + return; // No matter, we tried, best effort. + } + + MemTracker::record_virtual_memory_type((address)codebuf, mtInternal); + + log_info(os)("[CS limit NX emulation work-around, exec code at: %p]", codebuf); + + // Some code to exec: the 'ret' instruction + codebuf[0] = 0xC3; + + // Call the code in the codebuf + __asm__ volatile("call *%0" : : "r"(codebuf)); + + // keep the page mapped so CS limit isn't reduced. +} +#endif // defined(IA32) && !defined(ZERO) + // this is called _after_ the global arguments have been parsed jint os::init_2(void) { diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 863f996058b..b9ef04e1ee0 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -25,12 +25,11 @@ #ifndef OS_LINUX_OS_LINUX_HPP #define OS_LINUX_OS_LINUX_HPP -// Linux_OS defines the interface to Linux operating systems +#include "runtime/os.hpp" -// Information about the protection of the page at address '0' on this os. -static bool zero_page_read_protected() { return true; } +// os::Linux defines the interface to Linux operating systems -class Linux { +class os::Linux { friend class CgroupSubsystem; friend class os; friend class OSContainer; @@ -157,6 +156,7 @@ class Linux { // Stack overflow handling static bool manually_expand_stack(JavaThread * t, address addr); + static void expand_stack_to(address bottom); // fast POSIX clocks support static void fast_thread_clock_init(void); @@ -198,7 +198,6 @@ class Linux { private: static void numa_init(); - static void expand_stack_to(address bottom); typedef int (*sched_getcpu_func_t)(void); typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); @@ -428,6 +427,8 @@ class Linux { static const GrowableArray* numa_nindex_to_node() { return _nindex_to_node; } + + void* resolve_function_descriptor(void* p); }; #endif // OS_LINUX_OS_LINUX_HPP diff --git a/src/hotspot/os/linux/os_linux.inline.hpp b/src/hotspot/os/linux/os_linux.inline.hpp index 7cbb72eed65..416e3f4f71b 100644 --- a/src/hotspot/os/linux/os_linux.inline.hpp +++ b/src/hotspot/os/linux/os_linux.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,15 @@ #ifndef OS_LINUX_OS_LINUX_INLINE_HPP #define OS_LINUX_OS_LINUX_INLINE_HPP -// os_linux.hpp included by os.hpp +#include "os_linux.hpp" #include "runtime/os.hpp" #include "os_posix.inline.hpp" +inline bool os::zero_page_read_protected() { + return true; +} + inline bool os::uses_stack_guard_pages() { return true; } diff --git a/src/hotspot/os/linux/os_perf_linux.cpp b/src/hotspot/os/linux/os_perf_linux.cpp index 2f1aff11f9c..851434fb324 100644 --- a/src/hotspot/os/linux/os_perf_linux.cpp +++ b/src/hotspot/os/linux/os_perf_linux.cpp @@ -26,6 +26,7 @@ #include "jvm.h" #include "memory/allocation.inline.hpp" #include "os_linux.inline.hpp" +#include "os_posix.hpp" #include "runtime/os.hpp" #include "runtime/os_perf.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os/linux/trimCHeapDCmd.cpp b/src/hotspot/os/linux/trimCHeapDCmd.cpp index ee93ac5e8c8..ec212e2c70c 100644 --- a/src/hotspot/os/linux/trimCHeapDCmd.cpp +++ b/src/hotspot/os/linux/trimCHeapDCmd.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" +#include "os_linux.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index a61406c4cce..80ba2f8c806 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -24,9 +24,7 @@ #include "jvm.h" -#ifdef LINUX #include "classfile/classLoader.hpp" -#endif #include "jvmtifiles/jvmti.h" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" @@ -51,6 +49,9 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #include "utilities/vmError.hpp" +#ifdef LINUX +#include "os_linux.hpp" +#endif #include #include @@ -554,7 +555,7 @@ void os::Posix::print_umask(outputStream* st, mode_t umsk) { st->print((umsk & S_IXOTH) ? "x" : "-"); } -void os::Posix::print_user_info(outputStream* st) { +void os::print_user_info(outputStream* st) { unsigned id = (unsigned) ::getuid(); st->print("uid : %u ", id); id = (unsigned) ::geteuid(); @@ -568,13 +569,13 @@ void os::Posix::print_user_info(outputStream* st) { mode_t umsk = ::umask(0); ::umask(umsk); st->print("umask: %04o (", (unsigned) umsk); - print_umask(st, umsk); + os::Posix::print_umask(st, umsk); st->print_cr(")"); st->cr(); } // Print all active locale categories, one line each -void os::Posix::print_active_locale(outputStream* st) { +void os::print_active_locale(outputStream* st) { st->print_cr("Active Locale:"); // Posix is quiet about how exactly LC_ALL is implemented. // Just print it out too, in case LC_ALL is held separately @@ -1128,8 +1129,8 @@ bool os::Posix::handle_stack_overflow(JavaThread* thread, address addr, address "enabled executable stack (see man page execstack(8))"); } else { -#if !defined(AIX) && !defined(__APPLE__) - // bsd and aix don't have this +#ifdef LINUX + // This only works with os::Linux::manually_expand_stack() // Accessing stack address below sp may cause SEGV if current // thread has MAP_GROWSDOWN stack. This should only happen when @@ -1147,7 +1148,7 @@ bool os::Posix::handle_stack_overflow(JavaThread* thread, address addr, address } #else tty->print_raw_cr("SIGSEGV happened inside stack but outside yellow and red zone."); -#endif // AIX or BSD +#endif // LINUX } return false; } @@ -2010,3 +2011,8 @@ void os::die() { ::abort(); } } + +const char* os::file_separator() { return "/"; } +const char* os::line_separator() { return "\n"; } +const char* os::path_separator() { return ":"; } + diff --git a/src/hotspot/os/posix/os_posix.hpp b/src/hotspot/os/posix/os_posix.hpp index 1a6102e11f9..f8bf60c775a 100644 --- a/src/hotspot/os/posix/os_posix.hpp +++ b/src/hotspot/os/posix/os_posix.hpp @@ -25,6 +25,10 @@ #ifndef OS_POSIX_OS_POSIX_HPP #define OS_POSIX_OS_POSIX_HPP +#include "runtime/os.hpp" + +#include + // Note: the Posix API aims to capture functionality available on all Posix // compliant platforms, but in practice the implementations may depend on // non-Posix functionality. For example, the use of lseek64 and ftruncate64. @@ -34,12 +38,19 @@ // behaviour in API's that are defined by Posix. For example, that SIGSTKSZ // is not defined as a constant as of Glibc 2.34. -// File conventions -static const char* file_separator() { return "/"; } -static const char* line_separator() { return "\n"; } -static const char* path_separator() { return ":"; } +// macros for restartable system calls -class Posix { +#define RESTARTABLE(_cmd, _result) do { \ + _result = _cmd; \ + } while(((int)_result == OS_ERR) && (errno == EINTR)) + +#define RESTARTABLE_RETURN_INT(_cmd) do { \ + int _result; \ + RESTARTABLE(_cmd, _result); \ + return _result; \ +} while(false) + +class os::Posix { friend class os; protected: @@ -81,8 +92,6 @@ public: static void print_umask(outputStream* st, mode_t umsk); - static void print_user_info(outputStream* st); - // Set PC into context. Needed for continuation after signal. static address ucontext_get_pc(const ucontext_t* ctx); static void ucontext_set_pc(ucontext_t* ctx, address pc); @@ -92,8 +101,6 @@ public: static bool handle_stack_overflow(JavaThread* thread, address addr, address pc, const void* ucVoid, address* stub); - - static void print_active_locale(outputStream* st); }; #endif // OS_POSIX_OS_POSIX_HPP diff --git a/src/hotspot/os/posix/os_posix.inline.hpp b/src/hotspot/os/posix/os_posix.inline.hpp index 9273d240068..2966b571d4e 100644 --- a/src/hotspot/os/posix/os_posix.inline.hpp +++ b/src/hotspot/os/posix/os_posix.inline.hpp @@ -25,7 +25,7 @@ #ifndef OS_POSIX_OS_POSIX_INLINE_HPP #define OS_POSIX_OS_POSIX_INLINE_HPP -// os_posix.hpp included by os.hpp +#include "os_posix.hpp" #include "runtime/mutex.hpp" #include "runtime/os.hpp" @@ -34,18 +34,6 @@ #include #include -// macros for restartable system calls - -#define RESTARTABLE(_cmd, _result) do { \ - _result = _cmd; \ - } while(((int)_result == OS_ERR) && (errno == EINTR)) - -#define RESTARTABLE_RETURN_INT(_cmd) do { \ - int _result; \ - RESTARTABLE(_cmd, _result); \ - return _result; \ -} while(false) - // Aix does not have NUMA support but need these for compilation. inline bool os::numa_has_static_binding() { AIX_ONLY(ShouldNotReachHere();) return true; } inline bool os::numa_has_group_homing() { AIX_ONLY(ShouldNotReachHere();) return false; } diff --git a/src/hotspot/os/posix/perfMemory_posix.cpp b/src/hotspot/os/posix/perfMemory_posix.cpp index 45d16b153f9..b65f6151eba 100644 --- a/src/hotspot/os/posix/perfMemory_posix.cpp +++ b/src/hotspot/os/posix/perfMemory_posix.cpp @@ -37,6 +37,9 @@ #include "runtime/perfMemory.hpp" #include "services/memTracker.hpp" #include "utilities/exceptions.hpp" +#if defined(LINUX) +#include "os_linux.hpp" +#endif // put OS-includes here # include diff --git a/src/hotspot/os/posix/safefetch_static_posix.cpp b/src/hotspot/os/posix/safefetch_static_posix.cpp index 186f25e089d..f6a71c6042b 100644 --- a/src/hotspot/os/posix/safefetch_static_posix.cpp +++ b/src/hotspot/os/posix/safefetch_static_posix.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" +#include "os_posix.hpp" #include "runtime/os.hpp" #include "runtime/safefetch.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/os/posix/semaphore_posix.cpp b/src/hotspot/os/posix/semaphore_posix.cpp index 7f61e6d469e..f0caaaafb06 100644 --- a/src/hotspot/os/posix/semaphore_posix.cpp +++ b/src/hotspot/os/posix/semaphore_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ #include "precompiled.hpp" #ifndef __APPLE__ +#include "os_posix.hpp" #include "runtime/os.hpp" // POSIX unnamed semaphores are not supported on OS X. #include "semaphore_posix.hpp" diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index 5591ec6d6e2..0a1e5a79758 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -29,6 +29,7 @@ #include "code/compiledMethod.hpp" #include "code/nativeInst.hpp" #include "logging/log.hpp" +#include "os_posix.hpp" #include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.inline.hpp" diff --git a/src/hotspot/os/posix/vmError_posix.cpp b/src/hotspot/os/posix/vmError_posix.cpp index de325b29b09..548fcced518 100644 --- a/src/hotspot/os/posix/vmError_posix.cpp +++ b/src/hotspot/os/posix/vmError_posix.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "cds/metaspaceShared.hpp" +#include "os_posix.hpp" #include "runtime/javaThread.hpp" #include "runtime/os.hpp" #include "runtime/safefetch.hpp" diff --git a/src/hotspot/os/windows/iphlp_interface.cpp b/src/hotspot/os/windows/iphlp_interface.cpp index cfbd9032e2f..0f55ee17b23 100644 --- a/src/hotspot/os/windows/iphlp_interface.cpp +++ b/src/hotspot/os/windows/iphlp_interface.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "iphlp_interface.hpp" +#include "os_windows.hpp" #include "runtime/os.hpp" // IPHLP API diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index c50e0796466..0a8e4168369 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -5938,3 +5938,16 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) { } } } + +// File conventions +const char* os::file_separator() { return "\\"; } +const char* os::line_separator() { return "\r\n"; } +const char* os::path_separator() { return ";"; } + +void os::print_user_info(outputStream* st) { + // not implemented yet +} + +void os::print_active_locale(outputStream* st) { + // not implemented yet +} diff --git a/src/hotspot/os/windows/os_windows.hpp b/src/hotspot/os/windows/os_windows.hpp index 6c9210e00c8..1ec110426f2 100644 --- a/src/hotspot/os/windows/os_windows.hpp +++ b/src/hotspot/os/windows/os_windows.hpp @@ -24,25 +24,17 @@ #ifndef OS_WINDOWS_OS_WINDOWS_HPP #define OS_WINDOWS_OS_WINDOWS_HPP + +#include "runtime/os.hpp" + // Win32_OS defines the interface to windows operating systems -// strtok_s is the Windows thread-safe equivalent of POSIX strtok_r -#define strtok_r strtok_s +class outputStream; +class Thread; -#define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) -#define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO) - -// Information about the protection of the page at address '0' on this os. -static bool zero_page_read_protected() { return true; } - -// File conventions -static const char* file_separator() { return "\\"; } -static const char* line_separator() { return "\r\n"; } -static const char* path_separator() { return ";"; } - -class win32 { +class os::win32 { friend class os; - friend unsigned __stdcall thread_native_entry(class Thread*); + friend unsigned __stdcall thread_native_entry(Thread*); protected: static int _vm_page_size; @@ -56,6 +48,11 @@ class win32 { static void print_windows_version(outputStream* st); static void print_uptime_info(outputStream* st); + static bool platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size); + + static bool register_code_area(char *low, char *high); + public: // Windows-specific interface: static void initialize_system_info(); diff --git a/src/hotspot/os/windows/os_windows.inline.hpp b/src/hotspot/os/windows/os_windows.inline.hpp index 508a73eccc3..705c529e772 100644 --- a/src/hotspot/os/windows/os_windows.inline.hpp +++ b/src/hotspot/os/windows/os_windows.inline.hpp @@ -25,12 +25,16 @@ #ifndef OS_WINDOWS_OS_WINDOWS_INLINE_HPP #define OS_WINDOWS_OS_WINDOWS_INLINE_HPP -// os_windows.hpp included by os.hpp +#include "os_windows.hpp" #include "runtime/javaThread.hpp" #include "runtime/mutex.hpp" #include "runtime/os.hpp" +inline bool os::zero_page_read_protected() { + return true; +} + inline bool os::uses_stack_guard_pages() { return true; } diff --git a/src/hotspot/os/windows/pdh_interface.cpp b/src/hotspot/os/windows/pdh_interface.cpp index 85b238b8a5b..474a88e8562 100644 --- a/src/hotspot/os/windows/pdh_interface.cpp +++ b/src/hotspot/os/windows/pdh_interface.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "os_windows.hpp" #include "pdh_interface.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp index 7e19accaa33..2631a7bcc3f 100644 --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp @@ -34,6 +34,8 @@ #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "nativeInst_ppc.hpp" +#include "os_aix.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "porting_aix.hpp" @@ -508,12 +510,14 @@ int os::extra_bang_size_in_bytes() { return 0; } -bool os::platform_print_native_stack(outputStream* st, void* context, char *buf, int buf_size) { +bool os::Aix::platform_print_native_stack(outputStream* st, void* context, char *buf, int buf_size) { AixNativeCallstack::print_callstack_for_context(st, (const ucontext_t*)context, true, buf, (size_t) buf_size); return true; } // HAVE_FUNCTION_DESCRIPTORS -void* os::resolve_function_descriptor(void* p) { +void* os::Aix::resolve_function_descriptor(void* p) { return ((const FunctionDescriptor*)p)->entry(); } + +void os::setup_fpu() {} diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.hpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.inline.hpp similarity index 60% rename from src/hotspot/os_cpu/aix_ppc/os_aix_ppc.hpp rename to src/hotspot/os_cpu/aix_ppc/os_aix_ppc.inline.hpp index 130c1f4d48b..c20654bbdc1 100644 --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.hpp +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,20 +23,19 @@ * */ -#ifndef OS_CPU_AIX_PPC_OS_AIX_PPC_HPP -#define OS_CPU_AIX_PPC_OS_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_OS_AIX_PPC_INLINE_HPP +#define OS_CPU_AIX_PPC_OS_AIX_PPC_INLINE_HPP - static void setup_fpu() {} +#include "os_aix.hpp" - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } +#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1 +inline bool os::platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size) { + return os::Aix::platform_print_native_stack(st, context, buf, buf_size); +} - #define PLATFORM_PRINT_NATIVE_STACK 1 - static bool platform_print_native_stack(outputStream* st, void* context, - char *buf, int buf_size); - - #define HAVE_FUNCTION_DESCRIPTORS 1 - static void* resolve_function_descriptor(void* p); - -#endif // OS_CPU_AIX_PPC_OS_AIX_PPC_HPP +#define HAVE_FUNCTION_DESCRIPTORS 1 +inline void* os::resolve_function_descriptor(void* p) { + return os::Aix::resolve_function_descriptor(p); +} +#endif // OS_CPU_AIX_PPC_OS_AIX_PPC_INLINE_HPP diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp index 87b7c877c4e..da0dd1795d6 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp @@ -35,6 +35,8 @@ #include "interpreter/interpreter.hpp" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" +#include "os_bsd.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" @@ -337,10 +339,6 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info, void os::Bsd::init_thread_fpu_state(void) { } -bool os::is_allocatable(size_t bytes) { - return true; -} - //////////////////////////////////////////////////////////////////////////////// // thread stack diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.hpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.inline.hpp similarity index 67% rename from src/hotspot/os_cpu/bsd_zero/os_bsd_zero.hpp rename to src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.inline.hpp index 9dc9094b6e3..df4de1cf4eb 100644 --- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.hpp +++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.inline.hpp @@ -1,6 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2010 Red Hat, Inc. + * Copyright (c) 2022, 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,13 +22,7 @@ * */ -#ifndef OS_CPU_BSD_ZERO_OS_BSD_ZERO_HPP -#define OS_CPU_BSD_ZERO_OS_BSD_ZERO_HPP +#ifndef OS_CPU_BSD_AARCH64_OS_BSD_AARCH64_INLINE_HPP +#define OS_CPU_BSD_AARCH64_OS_BSD_AARCH64_INLINE_HPP - static void setup_fpu() {} - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - -#endif // OS_CPU_BSD_ZERO_OS_BSD_ZERO_HPP +#endif // OS_CPU_BSD_AARCH64_OS_BSD_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp index 4df3be6398b..e8d4edd3bbf 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp @@ -32,6 +32,8 @@ #include "interpreter/interpreter.hpp" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" +#include "os_bsd.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.inline.hpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.inline.hpp index b78490caeb5..5398a642d84 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.inline.hpp +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, 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 @@ -27,6 +27,16 @@ #include "runtime/os.hpp" +#if defined(__APPLE__) && defined(COMPATIBLE_CDS_ALIGNMENT) +#define HAVE_CDS_CORE_REGION_ALIGNMENT 1 +inline size_t os::cds_core_region_alignment() { + // Core region alignment is 16K to be able to run binaries built on MacOS x64 + // on MacOS aarch64. + return (16*K); +} +#endif + + // See http://www.technovelty.org/code/c/reading-rdtsc.htl for details inline jlong os::rdtsc() { #ifndef AMD64 diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp index 77f2cbd2d8f..e18cba5b0c2 100644 --- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp +++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp @@ -38,6 +38,8 @@ #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "nativeInst_zero.hpp" +#include "os_bsd.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" @@ -360,3 +362,5 @@ void os::current_thread_enable_wx(WXMode mode) { pthread_jit_write_protect_np(mode == WXExec); } #endif + +void os::setup_fpu() {} diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.inline.hpp b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.inline.hpp new file mode 100644 index 00000000000..3c8c2fc61c7 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.inline.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_ZERO_OS_BSD_ZERO_INLINE_HPP +#define OS_CPU_BSD_ZERO_OS_BSD_ZERO_INLINE_HPP + +#endif // OS_CPU_BSD_ZERO_OS_BSD_ZERO_INLINE_HPP diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index e70f1ea489d..349420c65dc 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -33,6 +33,8 @@ #include "code/nativeInst.hpp" #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.hpp deleted file mode 100644 index d4662a96d3a..00000000000 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_HPP -#define OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_HPP - -#if defined(COMPATIBLE_CDS_ALIGNMENT) -#define CDS_CORE_REGION_ALIGNMENT (64*K) -#endif - - static void setup_fpu(); - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - -#endif // OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_HPP diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.hpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.inline.hpp similarity index 69% rename from src/hotspot/os_cpu/linux_s390/os_linux_s390.hpp rename to src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.inline.hpp index 35618f4e8f4..2870c0050e4 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.inline.hpp @@ -1,6 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2022, 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,12 +22,16 @@ * */ -#ifndef OS_CPU_LINUX_S390_OS_LINUX_S390_HPP -#define OS_CPU_LINUX_S390_OS_LINUX_S390_HPP +#ifndef OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_INLINE_HPP +#define OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_INLINE_HPP - static void setup_fpu() {} +#include "runtime/os.hpp" - // Used to register dynamic code cache area with the OS. - static bool register_code_area(char *low, char *high) { return true; } +#if defined(COMPATIBLE_CDS_ALIGNMENT) +#define HAVE_CDS_CORE_REGION_ALIGNMENT 1 +inline size_t os::cds_core_region_alignment() { + return (64*K); +} +#endif -#endif // OS_CPU_LINUX_S390_OS_LINUX_S390_HPP +#endif // OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp index 2fc2e153e92..61dcf9b702f 100644 --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp @@ -31,6 +31,8 @@ #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "nativeInst_arm.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.hpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.inline.hpp similarity index 69% rename from src/hotspot/os_cpu/linux_arm/os_linux_arm.hpp rename to src/hotspot/os_cpu/linux_arm/os_linux_arm.inline.hpp index 94582ef89a8..3fac76a1792 100644 --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.hpp +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,8 @@ * */ -#ifndef OS_CPU_LINUX_ARM_OS_LINUX_ARM_HPP -#define OS_CPU_LINUX_ARM_OS_LINUX_ARM_HPP +#ifndef OS_CPU_LINUX_ARM_OS_LINUX_ARM_INLINE_HPP +#define OS_CPU_LINUX_ARM_OS_LINUX_ARM_INLINE_HPP - static void setup_fpu(); - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - -#endif // OS_CPU_LINUX_ARM_OS_LINUX_ARM_HPP +#endif // OS_CPU_LINUX_ARM_OS_LINUX_ARM_INLINE_HPP diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp index 71db9cd2b36..b52b4a9f9a3 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp @@ -34,6 +34,8 @@ #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "nativeInst_ppc.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" @@ -43,6 +45,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/javaThread.hpp" #include "runtime/mutexLocker.hpp" +#include "runtime/os.inline.hpp" #include "runtime/osThread.hpp" #include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" @@ -515,7 +518,9 @@ int os::extra_bang_size_in_bytes() { } #ifdef HAVE_FUNCTION_DESCRIPTORS -void* os::resolve_function_descriptor(void* p) { +void* os::Linux::resolve_function_descriptor(void* p) { return ((const FunctionDescriptor*)p)->entry(); } #endif + +void os::setup_fpu() {} diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.hpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.inline.hpp similarity index 69% rename from src/hotspot/os_cpu/linux_ppc/os_linux_ppc.hpp rename to src/hotspot/os_cpu/linux_ppc/os_linux_ppc.inline.hpp index edf56927884..7fbcf5ef150 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.hpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,19 +23,17 @@ * */ -#ifndef OS_CPU_LINUX_PPC_OS_LINUX_PPC_HPP -#define OS_CPU_LINUX_PPC_OS_LINUX_PPC_HPP +#ifndef OS_CPU_LINUX_PPC_OS_LINUX_PPC_INLINE_HPP +#define OS_CPU_LINUX_PPC_OS_LINUX_PPC_INLINE_HPP - static void setup_fpu() {} - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } +#include "os_linux.hpp" #if !defined(ABI_ELFv2) // ppc (not ppcle) has function descriptors - #define HAVE_FUNCTION_DESCRIPTORS 1 - static void* resolve_function_descriptor(void* p); +#define HAVE_FUNCTION_DESCRIPTORS 1 +inline void* os::resolve_function_descriptor(void* p) { + return os::Linux::resolve_function_descriptor(p); +} #endif -#endif // OS_CPU_LINUX_PPC_OS_LINUX_PPC_HPP +#endif // OS_CPU_LINUX_PPC_OS_LINUX_PPC_INLINE_HPP diff --git a/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp b/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp index 1c33dc1e87f..2b500376f9b 100644 --- a/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp +++ b/src/hotspot/os_cpu/linux_riscv/orderAccess_linux_riscv.hpp @@ -54,10 +54,6 @@ inline void OrderAccess::fence() { } inline void OrderAccess::cross_modify_fence_impl() { - asm volatile("fence.i" : : : "memory"); - if (UseConservativeFence) { - asm volatile("fence ir, ir" : : : "memory"); - } } #endif // OS_CPU_LINUX_RISCV_ORDERACCESS_LINUX_RISCV_HPP 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 d6d45e64705..eeeca1a7dd6 100644 --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp @@ -33,6 +33,8 @@ #include "interpreter/interpreter.hpp" #include "jvm.h" #include "memory/allocation.inline.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.hpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.hpp deleted file mode 100644 index 6a8eb3abb64..00000000000 --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_RISCV_VM_OS_LINUX_RISCV_HPP -#define OS_CPU_LINUX_RISCV_VM_OS_LINUX_RISCV_HPP - - static void setup_fpu(); - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - - // SYSCALL_RISCV_FLUSH_ICACHE is used to flush instruction cache. The "fence.i" instruction - // only work on the current hart, so kernel provides the icache flush syscall to flush icache - // on each hart. You can pass a flag to determine a global or local icache flush. - static void icache_flush(long int start, long int end) - { - const int SYSCALL_RISCV_FLUSH_ICACHE = 259; - register long int __a7 asm ("a7") = SYSCALL_RISCV_FLUSH_ICACHE; - register long int __a0 asm ("a0") = start; - register long int __a1 asm ("a1") = end; - // the flush can be applied to either all threads or only the current. - // 0 means a global icache flush, and the icache flush will be applied - // to other harts concurrently executing. - register long int __a2 asm ("a2") = 0; - __asm__ volatile ("ecall\n\t" - : "+r" (__a0) - : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a7) - : "memory"); - } - -#endif // OS_CPU_LINUX_RISCV_VM_OS_LINUX_RISCV_HPP diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.inline.hpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.inline.hpp new file mode 100644 index 00000000000..e9b9a126607 --- /dev/null +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.inline.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_RISCV_OS_LINUX_RISCV_INLINE_HPP +#define OS_CPU_LINUX_RISCV_OS_LINUX_RISCV_INLINE_HPP + +#endif // OS_CPU_LINUX_RISCV_OS_LINUX_RISCV_INLINE_HPP diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp index b416f39baa8..4dc15a07921 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp @@ -36,6 +36,8 @@ #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "nativeInst_s390.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" @@ -477,3 +479,5 @@ int os::extra_bang_size_in_bytes() { // z/Architecture does not require the additional stack bang. return 0; } + +void os::setup_fpu() {} diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.inline.hpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.inline.hpp new file mode 100644 index 00000000000..10c623ec6c9 --- /dev/null +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.inline.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_S390_OS_LINUX_S390_INLINE_HPP +#define OS_CPU_LINUX_S390_OS_LINUX_S390_INLINE_HPP + +#endif // OS_CPU_LINUX_S390_OS_LINUX_S390_INLINE_HPP diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp index 37997576782..b178de941e8 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp @@ -32,6 +32,8 @@ #include "interpreter/interpreter.hpp" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/frame.inline.hpp" @@ -651,83 +653,6 @@ void os::verify_stack_alignment() { } #endif - -/* - * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit - * updates (JDK-8023956). - */ -void os::workaround_expand_exec_shield_cs_limit() { -#if defined(IA32) - assert(Linux::initial_thread_stack_bottom() != NULL, "sanity"); - size_t page_size = os::vm_page_size(); - - /* - * JDK-8197429 - * - * Expand the stack mapping to the end of the initial stack before - * attempting to install the codebuf. This is needed because newer - * Linux kernels impose a distance of a megabyte between stack - * memory and other memory regions. If we try to install the - * codebuf before expanding the stack the installation will appear - * to succeed but we'll get a segfault later if we expand the stack - * in Java code. - * - */ - if (os::is_primordial_thread()) { - address limit = Linux::initial_thread_stack_bottom(); - if (! DisablePrimordialThreadGuardPages) { - limit += StackOverflow::stack_red_zone_size() + - StackOverflow::stack_yellow_zone_size(); - } - os::Linux::expand_stack_to(limit); - } - - /* - * Take the highest VA the OS will give us and exec - * - * Although using -(pagesz) as mmap hint works on newer kernel as you would - * think, older variants affected by this work-around don't (search forward only). - * - * On the affected distributions, we understand the memory layout to be: - * - * TASK_LIMIT= 3G, main stack base close to TASK_LIMT. - * - * A few pages south main stack will do it. - * - * If we are embedded in an app other than launcher (initial != main stack), - * we don't have much control or understanding of the address space, just let it slide. - */ - char* hint = (char*)(Linux::initial_thread_stack_bottom() - - (StackOverflow::stack_guard_zone_size() + page_size)); - char* codebuf = os::attempt_reserve_memory_at(hint, page_size); - - if (codebuf == NULL) { - // JDK-8197429: There may be a stack gap of one megabyte between - // the limit of the stack and the nearest memory region: this is a - // Linux kernel workaround for CVE-2017-1000364. If we failed to - // map our codebuf, try again at an address one megabyte lower. - hint -= 1 * M; - codebuf = os::attempt_reserve_memory_at(hint, page_size); - } - - if ((codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true))) { - return; // No matter, we tried, best effort. - } - - MemTracker::record_virtual_memory_type((address)codebuf, mtInternal); - - log_info(os)("[CS limit NX emulation work-around, exec code at: %p]", codebuf); - - // Some code to exec: the 'ret' instruction - codebuf[0] = 0xC3; - - // Call the code in the codebuf - __asm__ volatile("call *%0" : : "r"(codebuf)); - - // keep the page mapped so CS limit isn't reduced. -#endif -} - int os::extra_bang_size_in_bytes() { // JDK-8050147 requires the full cache line bang for x86. return VM_Version::L1_line_size(); diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp deleted file mode 100644 index 979006035cc..00000000000 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_X86_OS_LINUX_X86_HPP -#define OS_CPU_LINUX_X86_OS_LINUX_X86_HPP - - static void setup_fpu(); - static bool supports_sse(); - static juint cpu_microcode_revision(); - - static jlong rdtsc(); - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - - /* - * Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield" - * (IA32 only). - * - * Map and execute at a high VA to prevent CS lazy updates race with SMP MM - * invalidation.Further code generation by the JVM will no longer cause CS limit - * updates. - * - * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04. - * @see JDK-8023956 - */ - static void workaround_expand_exec_shield_cs_limit(); - -#endif // OS_CPU_LINUX_X86_OS_LINUX_X86_HPP diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp index a9c7973b703..9fbf0ca7079 100644 --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp @@ -33,6 +33,8 @@ #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "nativeInst_zero.hpp" +#include "os_linux.hpp" +#include "os_posix.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" @@ -398,3 +400,5 @@ int os::extra_bang_size_in_bytes() { // Zero does not require an additional stack banging. return 0; } + +void os::setup_fpu() {} diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp deleted file mode 100644 index 51ad6de66ab..00000000000 --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2010, 2018, Red Hat, Inc. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_ZERO_OS_LINUX_ZERO_HPP -#define OS_CPU_LINUX_ZERO_OS_LINUX_ZERO_HPP - - static void setup_fpu() {} - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - - /* - * Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield" - * (IA32 only). - * - * Map and execute at a high VA to prevent CS lazy updates race with SMP MM - * invalidation.Further code generation by the JVM will no longer cause CS limit - * updates. - * - * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04. - * @see JDK-8023956 - */ - static void workaround_expand_exec_shield_cs_limit(); - -#endif // OS_CPU_LINUX_ZERO_OS_LINUX_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.inline.hpp similarity index 70% rename from src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp rename to src/hotspot/os_cpu/linux_zero/os_linux_zero.inline.hpp index fedf5848f9e..ca97c2a2951 100644 --- a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,15 +22,9 @@ * */ -#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP -#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP +#ifndef OS_CPU_LINUX_ZERO_OS_LINUX_ZERO_INLINE_HPP +#define OS_CPU_LINUX_ZERO_OS_LINUX_ZERO_INLINE_HPP - static void setup_fpu(); - static bool supports_sse(); - static bool register_code_area(char *low, char *high) { - // Using Vectored Exception Handling - return true; - } -#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP +#endif // OS_CPU_LINUX_ZERO_OS_LINUX_ZERO_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp index 338333a94a9..8f297d9bea2 100644 --- a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp @@ -33,6 +33,7 @@ #include "code/nativeInst.hpp" #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" +#include "os_windows.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp index 673cd3fa29d..794aa12155b 100644 --- a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp @@ -27,4 +27,9 @@ #include "runtime/os.hpp" +inline bool os::register_code_area(char *low, char *high) { + // Using Vectored Exception Handling + return true; +} + #endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp index 3cc0003cd4c..5a04b289604 100644 --- a/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" +#include "os_windows.hpp" #include "runtime/os.hpp" void MacroAssembler::int3() { diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp index 8a9d244339e..5a4c0a1c3e2 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp @@ -32,6 +32,7 @@ #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "nativeInst_x86.hpp" +#include "os_windows.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" @@ -41,6 +42,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/javaThread.hpp" #include "runtime/mutexLocker.hpp" +#include "runtime/os.inline.hpp" #include "runtime/osThread.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" @@ -165,7 +167,7 @@ typedef struct { // Arguments: low and high are the address of the full reserved // codeCache area // -bool os::register_code_area(char *low, char *high) { +bool os::win32::register_code_area(char *low, char *high) { #ifdef AMD64 ResourceMark rm; @@ -209,7 +211,7 @@ bool os::register_code_area(char *low, char *high) { return true; } -#ifdef AMD64 +#ifdef HAVE_PLATFORM_PRINT_NATIVE_STACK /* * Windows/x64 does not use stack frames the way expected by Java: * [1] in most cases, there is no frame pointer. All locals are addressed via RSP @@ -221,8 +223,8 @@ bool os::register_code_area(char *low, char *high) { * while (...) {... fr = os::get_sender_for_C_frame(&fr); } * loop in vmError.cpp. We need to roll our own loop. */ -bool os::platform_print_native_stack(outputStream* st, const void* context, - char *buf, int buf_size) +bool os::win32::platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size) { CONTEXT ctx; if (context != NULL) { @@ -293,7 +295,7 @@ bool os::platform_print_native_stack(outputStream* st, const void* context, return true; } -#endif // AMD64 +#endif // HAVE_PLATFORM_PRINT_NATIVE_STACK address os::fetch_frame_from_context(const void* ucVoid, intptr_t** ret_sp, intptr_t** ret_fp) { @@ -558,3 +560,7 @@ int os::extra_bang_size_in_bytes() { // JDK-8050147 requires the full cache line bang for x86. return VM_Version::L1_line_size(); } + +bool os::supports_sse() { + return true; +} diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.hpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.hpp deleted file mode 100644 index 7fdd068219c..00000000000 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_WINDOWS_X86_OS_WINDOWS_X86_HPP -#define OS_CPU_WINDOWS_X86_OS_WINDOWS_X86_HPP - - // - // NOTE: we are back in class os here, not win32 - // - - static void setup_fpu(); - static bool supports_sse() { return true; } - static juint cpu_microcode_revision(); - - static jlong rdtsc(); - - static bool register_code_area(char *low, char *high); - -#ifdef AMD64 -#define PLATFORM_PRINT_NATIVE_STACK 1 -static bool platform_print_native_stack(outputStream* st, const void* context, - char *buf, int buf_size); -#endif - -#endif // OS_CPU_WINDOWS_X86_OS_WINDOWS_X86_HPP diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.inline.hpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.inline.hpp index 3a9754532f7..f69cbecbb70 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.inline.hpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,15 @@ #define OS_CPU_WINDOWS_X86_OS_WINDOWS_X86_INLINE_HPP #include "runtime/os.hpp" +#include "os_windows.hpp" + +#ifdef AMD64 +#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1 +inline bool os::platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size) { + return os::win32::platform_print_native_stack(st, context, buf, buf_size); +} +#endif inline jlong os::rdtsc() { // 32 bit: 64 bit result in edx:eax @@ -35,4 +44,8 @@ inline jlong os::rdtsc() { return (jlong)res; } +inline bool os::register_code_area(char *low, char *high) { + return os::win32::register_code_area(low, high); +} + #endif // OS_CPU_WINDOWS_X86_OS_WINDOWS_X86_INLINE_HPP diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index e13a25b8a25..26a3c3a7d5f 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp @@ -3334,20 +3334,20 @@ void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) { if (_curchar == '(') { parens_depth++; encoding->add_code("("); - next_char(); + next_char_or_line(); } else if (_curchar == ')') { parens_depth--; if (parens_depth > 0) encoding->add_code(")"); - next_char(); + next_char_or_line(); } else { // (1) // Check if there is a string to pass through to output char *start = _ptr; // Record start of the next string while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) { - next_char(); + next_char_or_line(); } // If a string was found, terminate it and record in EncClass if (start != _ptr) { diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index 7921cff886c..d09c6a5ca92 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -65,7 +65,7 @@ InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule) : _ident(id), _ideal_only(false), _localNames(instr->_localNames), _effects(instr->_effects), - _is_mach_constant(false), + _is_mach_constant(instr->_is_mach_constant), _needs_constant_base(false), _has_call(false) { @@ -4090,12 +4090,6 @@ int MatchRule::is_expensive() const { strcmp(opType,"ReverseBytesL")==0 || strcmp(opType,"ReverseBytesUS")==0 || strcmp(opType,"ReverseBytesS")==0 || - strcmp(opType,"ReplicateB")==0 || - strcmp(opType,"ReplicateS")==0 || - strcmp(opType,"ReplicateI")==0 || - strcmp(opType,"ReplicateL")==0 || - strcmp(opType,"ReplicateF")==0 || - strcmp(opType,"ReplicateD")==0 || strcmp(opType,"PopulateIndex")==0 || strcmp(opType,"AddReductionVI")==0 || strcmp(opType,"AddReductionVL")==0 || @@ -4111,8 +4105,9 @@ int MatchRule::is_expensive() const { strcmp(opType,"OrReductionV")==0 || strcmp(opType,"XorReductionV")==0 || strcmp(opType,"MaskAll")==0 || - 0 /* 0 to line up columns nicely */ ) + 0 /* 0 to line up columns nicely */ ) { return 1; + } } return 0; } diff --git a/src/hotspot/share/asm/assembler.hpp b/src/hotspot/share/asm/assembler.hpp index 21229d37462..7b5ddb657e9 100644 --- a/src/hotspot/share/asm/assembler.hpp +++ b/src/hotspot/share/asm/assembler.hpp @@ -429,11 +429,11 @@ class AbstractAssembler : public ResourceObj { } return ptr; } - address array_constant(BasicType bt, GrowableArray* c) { + address array_constant(BasicType bt, GrowableArray* c, int alignment) { CodeSection* c1 = _code_section; int len = c->length(); int size = type2aelembytes(bt) * len; - address ptr = start_a_const(size, MIN2(round_up_power_of_2(size), 8)); + address ptr = start_a_const(size, alignment); if (ptr != NULL) { for (int i = 0; i < len; i++) { jvalue e = c->at(i); diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.cpp b/src/hotspot/share/cds/dumpTimeClassInfo.cpp index 4bf2172d598..f3d738e358e 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.cpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.cpp @@ -31,40 +31,60 @@ #include "classfile/systemDictionaryShared.hpp" #include "memory/resourceArea.hpp" -DumpTimeClassInfo DumpTimeClassInfo::clone() { - DumpTimeClassInfo clone; - clone._klass = _klass; - clone._nest_host = _nest_host; - clone._failed_verification = _failed_verification; - clone._is_archived_lambda_proxy = _is_archived_lambda_proxy; - clone._has_checked_exclusion = _has_checked_exclusion; - clone._id = _id; - clone._clsfile_size = _clsfile_size; - clone._clsfile_crc32 = _clsfile_crc32; - clone._excluded = _excluded; - clone._is_early_klass = _is_early_klass; - clone._verifier_constraints = NULL; - clone._verifier_constraint_flags = NULL; - clone._loader_constraints = NULL; - clone._enum_klass_static_fields = NULL; - int clone_num_verifier_constraints = num_verifier_constraints(); - if (clone_num_verifier_constraints > 0) { - clone._verifier_constraints = new (ResourceObj::C_HEAP, mtClass) GrowableArray(clone_num_verifier_constraints, mtClass); - clone._verifier_constraint_flags = new (ResourceObj::C_HEAP, mtClass) GrowableArray(clone_num_verifier_constraints, mtClass); - for (int i = 0; i < clone_num_verifier_constraints; i++) { - clone._verifier_constraints->append(_verifier_constraints->at(i)); - clone._verifier_constraint_flags->append(_verifier_constraint_flags->at(i)); +// This constructor is used only by SystemDictionaryShared::clone_dumptime_tables(). +// See comments there about the need for making a deep copy. +DumpTimeClassInfo::DumpTimeClassInfo(const DumpTimeClassInfo& src) { + assert(DynamicDumpSharedSpaces, "must be"); + + _klass = src._klass; + _nest_host = src._nest_host; + _failed_verification = src._failed_verification; + _is_archived_lambda_proxy = src._is_archived_lambda_proxy; + _has_checked_exclusion = src._has_checked_exclusion; + _id = src._id; + _clsfile_size = src._clsfile_size; + _clsfile_crc32 = src._clsfile_crc32; + _excluded = src._excluded; + _is_early_klass = src._is_early_klass; + _verifier_constraints = NULL; + _verifier_constraint_flags = NULL; + _loader_constraints = NULL; + + assert(src._enum_klass_static_fields == NULL, "This should not happen with dynamic dump."); + _enum_klass_static_fields = NULL; + + { + int n = src.num_verifier_constraints(); + if (n > 0) { + _verifier_constraints = new (ResourceObj::C_HEAP, mtClass) GrowableArray(n, mtClass); + _verifier_constraint_flags = new (ResourceObj::C_HEAP, mtClass) GrowableArray(n, mtClass); + for (int i = 0; i < n; i++) { + _verifier_constraints->append(src._verifier_constraints->at(i)); + _verifier_constraint_flags->append(src._verifier_constraint_flags->at(i)); + } } } - int clone_num_loader_constraints = num_loader_constraints(); - if (clone_num_loader_constraints > 0) { - clone._loader_constraints = new (ResourceObj::C_HEAP, mtClass) GrowableArray(clone_num_loader_constraints, mtClass); - for (int i = 0; i < clone_num_loader_constraints; i++) { - clone._loader_constraints->append(_loader_constraints->at(i)); + + { + int n = src.num_loader_constraints(); + if (n > 0) { + _loader_constraints = new (ResourceObj::C_HEAP, mtClass) GrowableArray(n, mtClass); + for (int i = 0; i < n; i++) { + _loader_constraints->append(src._loader_constraints->at(i)); + } } } - assert(_enum_klass_static_fields == NULL, "This should not happen with jcmd VM.cds dumping"); - return clone; +} + +DumpTimeClassInfo::~DumpTimeClassInfo() { + if (_verifier_constraints != NULL) { + assert(_verifier_constraint_flags != NULL, "must be"); + delete _verifier_constraints; + delete _verifier_constraint_flags; + } + if (_loader_constraints != NULL) { + delete _loader_constraints; + } } size_t DumpTimeClassInfo::runtime_info_bytesize() const { @@ -83,8 +103,7 @@ void DumpTimeClassInfo::add_verification_constraint(InstanceKlass* k, Symbol* na } GrowableArray* vc_array = _verifier_constraints; for (int i = 0; i < vc_array->length(); i++) { - DTVerifierConstraint* p = vc_array->adr_at(i); - if (name == p->_name && from_name == p->_from_name) { + if (vc_array->at(i).equals(name, from_name)) { return; } } @@ -128,8 +147,7 @@ void DumpTimeClassInfo::record_linking_constraint(Symbol* name, Handle loader1, char lt2 = get_loader_type_by(loader2()); DTLoaderConstraint lc(name, lt1, lt2); for (int i = 0; i < _loader_constraints->length(); i++) { - DTLoaderConstraint dt = _loader_constraints->at(i); - if (lc.equals(dt)) { + if (lc.equals(_loader_constraints->at(i))) { if (log.is_enabled()) { ResourceMark rm; // Use loader[0]/loader[1] to be consistent with the logs in loaderConstraints.cpp diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp index 117c682f695..698b21e638e 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp @@ -40,32 +40,83 @@ class DumpTimeClassInfo: public CHeapObj { bool _excluded; bool _is_early_klass; bool _has_checked_exclusion; -public: - struct DTLoaderConstraint { + + class DTLoaderConstraint { Symbol* _name; char _loader_type1; char _loader_type2; - DTLoaderConstraint(Symbol* name, char l1, char l2) : _name(name), _loader_type1(l1), _loader_type2(l2) { - _name->increment_refcount(); - } + public: DTLoaderConstraint() : _name(NULL), _loader_type1('0'), _loader_type2('0') {} + DTLoaderConstraint(Symbol* name, char l1, char l2) : _name(name), _loader_type1(l1), _loader_type2(l2) { + Symbol::maybe_increment_refcount(_name); + } + DTLoaderConstraint(const DTLoaderConstraint& src) { + _name = src._name; + _loader_type1 = src._loader_type1; + _loader_type2 = src._loader_type2; + Symbol::maybe_increment_refcount(_name); + } + DTLoaderConstraint& operator=(DTLoaderConstraint src) { + swap(_name, src._name); // c++ copy-and-swap idiom + _loader_type1 = src._loader_type1; + _loader_type2 = src._loader_type2; + return *this; + } + ~DTLoaderConstraint() { + Symbol::maybe_decrement_refcount(_name); + } + bool equals(const DTLoaderConstraint& t) { return t._name == _name && ((t._loader_type1 == _loader_type1 && t._loader_type2 == _loader_type2) || (t._loader_type2 == _loader_type1 && t._loader_type1 == _loader_type2)); } + void metaspace_pointers_do(MetaspaceClosure* it) { + it->push(&_name); + } + + Symbol* name() { return _name; } + char loader_type1() { return _loader_type1; } + char loader_type2() { return _loader_type2; } }; - struct DTVerifierConstraint { + class DTVerifierConstraint { Symbol* _name; Symbol* _from_name; + public: DTVerifierConstraint() : _name(NULL), _from_name(NULL) {} DTVerifierConstraint(Symbol* n, Symbol* fn) : _name(n), _from_name(fn) { - _name->increment_refcount(); - _from_name->increment_refcount(); + Symbol::maybe_increment_refcount(_name); + Symbol::maybe_increment_refcount(_from_name); } + DTVerifierConstraint(const DTVerifierConstraint& src) { + _name = src._name; + _from_name = src._from_name; + Symbol::maybe_increment_refcount(_name); + Symbol::maybe_increment_refcount(_from_name); + } + DTVerifierConstraint& operator=(DTVerifierConstraint src) { + swap(_name, src._name); // c++ copy-and-swap idiom + swap(_from_name, src._from_name); // c++ copy-and-swap idiom + return *this; + } + ~DTVerifierConstraint() { + Symbol::maybe_decrement_refcount(_name); + Symbol::maybe_decrement_refcount(_from_name); + } + bool equals(Symbol* n, Symbol* fn) { + return (_name == n) && (_from_name == fn); + } + void metaspace_pointers_do(MetaspaceClosure* it) { + it->push(&_name); + it->push(&_from_name); + } + + Symbol* name() { return _name; } + Symbol* from_name() { return _from_name; } }; +public: InstanceKlass* _klass; InstanceKlass* _nest_host; bool _failed_verification; @@ -94,6 +145,9 @@ public: _loader_constraints = NULL; _enum_klass_static_fields = NULL; } + DumpTimeClassInfo(const DumpTimeClassInfo& src); + DumpTimeClassInfo& operator=(const DumpTimeClassInfo&) = delete; + ~DumpTimeClassInfo(); void add_verification_constraint(InstanceKlass* k, Symbol* name, Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object); @@ -131,15 +185,12 @@ public: it->push(&_nest_host); if (_verifier_constraints != NULL) { for (int i = 0; i < _verifier_constraints->length(); i++) { - DTVerifierConstraint* cons = _verifier_constraints->adr_at(i); - it->push(&cons->_name); - it->push(&cons->_from_name); + _verifier_constraints->adr_at(i)->metaspace_pointers_do(it); } } if (_loader_constraints != NULL) { for (int i = 0; i < _loader_constraints->length(); i++) { - DTLoaderConstraint* lc = _loader_constraints->adr_at(i); - it->push(&lc->_name); + _loader_constraints->adr_at(i)->metaspace_pointers_do(it); } } } @@ -162,7 +213,6 @@ public: InstanceKlass* nest_host() const { return _nest_host; } void set_nest_host(InstanceKlass* nest_host) { _nest_host = nest_host; } - DumpTimeClassInfo clone(); size_t runtime_info_bytesize() const; }; diff --git a/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp b/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp index 78917ebaae3..dc6f136b0c9 100644 --- a/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp +++ b/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -27,17 +27,23 @@ #include "cds/lambdaProxyClassDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" -DumpTimeLambdaProxyClassInfo DumpTimeLambdaProxyClassInfo::clone() { - DumpTimeLambdaProxyClassInfo res; - res._proxy_klasses = NULL; - if (_proxy_klasses != NULL && _proxy_klasses->length() > 0) { - int num_proxy_klasses = _proxy_klasses->length(); - res._proxy_klasses = new (ResourceObj::C_HEAP, mtClassShared) GrowableArray(num_proxy_klasses, mtClassShared); - for (int i = 0; i < num_proxy_klasses; i++) { - res._proxy_klasses->append(_proxy_klasses->at(i)); +// This constructor is used only by SystemDictionaryShared::clone_dumptime_tables(). +// See comments there about the need for making a deep copy. +DumpTimeLambdaProxyClassInfo::DumpTimeLambdaProxyClassInfo(const DumpTimeLambdaProxyClassInfo& src) { + _proxy_klasses = NULL; + if (src._proxy_klasses != NULL && src._proxy_klasses->length() > 0) { + int n = src._proxy_klasses->length(); + _proxy_klasses = new (ResourceObj::C_HEAP, mtClassShared) GrowableArray(n, mtClassShared); + for (int i = 0; i < n; i++) { + _proxy_klasses->append(src._proxy_klasses->at(i)); } } - return res; +} + +DumpTimeLambdaProxyClassInfo::~DumpTimeLambdaProxyClassInfo() { + if (_proxy_klasses != NULL) { + delete _proxy_klasses; + } } void LambdaProxyClassKey::mark_pointers() { diff --git a/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp b/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp index 55c49923f82..e90ec075c3c 100644 --- a/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp +++ b/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -108,6 +108,10 @@ class DumpTimeLambdaProxyClassInfo { public: GrowableArray* _proxy_klasses; DumpTimeLambdaProxyClassInfo() : _proxy_klasses(NULL) {} + DumpTimeLambdaProxyClassInfo(const DumpTimeLambdaProxyClassInfo& src); + DumpTimeLambdaProxyClassInfo& operator=(const DumpTimeLambdaProxyClassInfo&) = delete; + ~DumpTimeLambdaProxyClassInfo(); + void add_proxy_klass(InstanceKlass* proxy_klass) { if (_proxy_klasses == NULL) { _proxy_klasses = new (ResourceObj::C_HEAP, mtClassShared) GrowableArray(5, mtClassShared); @@ -121,7 +125,6 @@ public: it->push(_proxy_klasses->adr_at(i)); } } - DumpTimeLambdaProxyClassInfo clone(); // copy ctor will cause implicitly-declared }; class RunTimeLambdaProxyClassInfo { diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index af2806f319c..57d4b93f3af 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -67,7 +67,7 @@ #include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safepointVerifiers.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/vmThread.hpp" @@ -126,20 +126,17 @@ char* MetaspaceShared::symbol_space_alloc(size_t num_bytes) { return _symbol_region.allocate(num_bytes); } -// os::vm_allocation_granularity() is usually 4K for most OSes. However, on Linux/aarch64, -// it can be either 4K or 64K and on Macosx-arm it is 16K. To generate archives that are +// os::vm_allocation_granularity() is usually 4K for most OSes. However, some platforms +// such as linux-aarch64 and macos-x64 ... +// it can be either 4K or 64K and on macos-aarch64 it is 16K. To generate archives that are // compatible for both settings, an alternative cds core region alignment can be enabled // at building time: // --enable-compactible-cds-alignment -// Upon successful configuration, the compactible alignment then can be defined as in: -// os_linux_aarch64.hpp -// which is the highest page size configured on the platform. +// Upon successful configuration, the compactible alignment then can be defined in: +// os_linux_aarch64.cpp +// os_bsd_x86.cpp size_t MetaspaceShared::core_region_alignment() { -#if defined(CDS_CORE_REGION_ALIGNMENT) - return CDS_CORE_REGION_ALIGNMENT; -#else - return (size_t)os::vm_allocation_granularity(); -#endif // CDS_CORE_REGION_ALIGNMENT + return os::cds_core_region_alignment(); } static bool shared_base_valid(char* shared_base) { diff --git a/src/hotspot/share/cds/runTimeClassInfo.cpp b/src/hotspot/share/cds/runTimeClassInfo.cpp index 70036bd6e82..8c17659f242 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.cpp +++ b/src/hotspot/share/cds/runTimeClassInfo.cpp @@ -44,8 +44,8 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) { RTVerifierConstraint* vf_constraints = verifier_constraints(); char* flags = verifier_constraint_flags(); for (i = 0; i < _num_verifier_constraints; i++) { - vf_constraints[i]._name = builder->any_to_offset_u4(info._verifier_constraints->at(i)._name); - vf_constraints[i]._from_name = builder->any_to_offset_u4(info._verifier_constraints->at(i)._from_name); + vf_constraints[i]._name = builder->any_to_offset_u4(info._verifier_constraints->at(i).name()); + vf_constraints[i]._from_name = builder->any_to_offset_u4(info._verifier_constraints->at(i).from_name()); } for (i = 0; i < _num_verifier_constraints; i++) { flags[i] = info._verifier_constraint_flags->at(i); @@ -55,9 +55,9 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) { if (_num_loader_constraints > 0) { RTLoaderConstraint* ld_constraints = loader_constraints(); for (i = 0; i < _num_loader_constraints; i++) { - ld_constraints[i]._name = builder->any_to_offset_u4(info._loader_constraints->at(i)._name); - ld_constraints[i]._loader_type1 = info._loader_constraints->at(i)._loader_type1; - ld_constraints[i]._loader_type2 = info._loader_constraints->at(i)._loader_type2; + ld_constraints[i]._name = builder->any_to_offset_u4(info._loader_constraints->at(i).name()); + ld_constraints[i]._loader_type1 = info._loader_constraints->at(i).loader_type1(); + ld_constraints[i]._loader_type2 = info._loader_constraints->at(i).loader_type2(); } } diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp index 88a318b7092..b25b578cfe5 100644 --- a/src/hotspot/share/classfile/classLoaderData.hpp +++ b/src/hotspot/share/classfile/classLoaderData.hpp @@ -249,6 +249,8 @@ class ClassLoaderData : public CHeapObj { bool is_builtin_class_loader_data() const; bool is_permanent_class_loader_data() const; + OopHandle class_loader_handle() const { return _class_loader; } + // The Metaspace is created lazily so may be NULL. This // method will allocate a Metaspace if needed. ClassLoaderMetaspace* metaspace_non_null(); diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index a7f4e0bfb5a..a78c553a075 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -481,89 +481,6 @@ void Dictionary::clean_cached_protection_domains(GrowableArraydecrement_refcount(); - // Free OopHandle - _method_type.release(Universe::vm_global()); -} - -void SymbolPropertyEntry::print_entry(outputStream* st) const { - symbol()->print_value_on(st); - st->print("/mode=" INTX_FORMAT, symbol_mode()); - st->print(" -> "); - bool printed = false; - if (method() != NULL) { - method()->print_value_on(st); - printed = true; - } - if (method_type() != NULL) { - if (printed) st->print(" and "); - st->print(INTPTR_FORMAT, p2i((void *)method_type())); - printed = true; - } - st->print_cr(printed ? "" : "(empty)"); -} - -SymbolPropertyTable::SymbolPropertyTable(int table_size) - : Hashtable(table_size, sizeof(SymbolPropertyEntry)) -{ -} -SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, - int number_of_entries) - : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) -{ -} - - -SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, - Symbol* sym, - intptr_t sym_mode) { - assert(index == index_for(sym, sym_mode), "incorrect index?"); - for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { - if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) { - return p; - } - } - return NULL; -} - - -SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, - Symbol* sym, intptr_t sym_mode) { - assert_locked_or_safepoint(SystemDictionary_lock); - assert(index == index_for(sym, sym_mode), "incorrect index?"); - assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); - - SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode); - Hashtable::add_entry(index, p); - return p; -} - -void SymbolPropertyTable::methods_do(void f(Method*)) { - for (int index = 0; index < table_size(); index++) { - for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { - Method* prop = p->method(); - if (prop != NULL) { - f((Method*)prop); - } - } - } -} - -void SymbolPropertyTable::free_entry(SymbolPropertyEntry* entry) { - entry->free_entry(); - BasicHashtable::free_entry(entry); -} - void DictionaryEntry::verify_protection_domain_set() { assert(SafepointSynchronize::is_at_safepoint(), "must only be called as safepoint"); for (ProtectionDomainEntry* current = pd_set_acquire(); // accessed at a safepoint diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp index 322244e5d17..ef77bacb1f3 100644 --- a/src/hotspot/share/classfile/dictionary.hpp +++ b/src/hotspot/share/classfile/dictionary.hpp @@ -153,98 +153,4 @@ class DictionaryEntry : public HashtableEntry { void verify(); }; -// Entry in a SymbolPropertyTable, mapping a single Symbol* -// to a managed and an unmanaged pointer. -class SymbolPropertyEntry : public HashtableEntry { - friend class VMStructs; - private: - intptr_t _symbol_mode; // secondary key - Method* _method; - OopHandle _method_type; - - public: - Symbol* symbol() const { return literal(); } - - intptr_t symbol_mode() const { return _symbol_mode; } - void set_symbol_mode(intptr_t m) { _symbol_mode = m; } - - Method* method() const { return _method; } - void set_method(Method* p) { _method = p; } - - oop method_type() const; - void set_method_type(oop p); - - // We need to clear the OopHandle because these hashtable entries are not constructed properly. - void clear_method_type() { _method_type = OopHandle(); } - - void free_entry(); - - SymbolPropertyEntry* next() const { - return (SymbolPropertyEntry*)HashtableEntry::next(); - } - - SymbolPropertyEntry** next_addr() { - return (SymbolPropertyEntry**)HashtableEntry::next_addr(); - } - - void print_entry(outputStream* st) const; -}; - -// A system-internal mapping of symbols to pointers, both managed -// and unmanaged. Used to record the auto-generation of each method -// MethodHandle.invoke(S)T, for all signatures (S)T. -class SymbolPropertyTable : public Hashtable { - friend class VMStructs; -private: - // The following method is not MT-safe and must be done under lock. - SymbolPropertyEntry** bucket_addr(int i) { - return (SymbolPropertyEntry**) Hashtable::bucket_addr(i); - } - - void add_entry(int index, SymbolPropertyEntry* new_entry) { - ShouldNotReachHere(); - } - void set_entry(int index, SymbolPropertyEntry* new_entry) { - ShouldNotReachHere(); - } - - SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) { - SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol); - // Hashtable with Symbol* literal must increment and decrement refcount. - symbol->increment_refcount(); - entry->set_symbol_mode(symbol_mode); - entry->set_method(NULL); - entry->clear_method_type(); - return entry; - } - -public: - SymbolPropertyTable(int table_size); - SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries); - - void free_entry(SymbolPropertyEntry* entry); - - unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) { - // Use the regular identity_hash. - return Hashtable::compute_hash(sym) ^ symbol_mode; - } - - int index_for(Symbol* name, intptr_t symbol_mode) { - return hash_to_index(compute_hash(name, symbol_mode)); - } - - // need not be locked; no state change - SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode); - - // must be done under SystemDictionary_lock - SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode); - - void methods_do(void f(Method*)); - - void verify(); - - SymbolPropertyEntry* bucket(int i) { - return (SymbolPropertyEntry*) Hashtable::bucket(i); - } -}; #endif // SHARE_CLASSFILE_DICTIONARY_HPP diff --git a/src/hotspot/share/classfile/modules.cpp b/src/hotspot/share/classfile/modules.cpp index 61551697bf4..139f2f9de76 100644 --- a/src/hotspot/share/classfile/modules.cpp +++ b/src/hotspot/share/classfile/modules.cpp @@ -44,6 +44,7 @@ #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" #include "prims/jvmtiExport.hpp" +#include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" @@ -499,9 +500,16 @@ void Modules::define_archived_modules(Handle h_platform_loader, Handle h_system_ } ClassLoaderData* platform_loader_data = SystemDictionary::register_loader(h_platform_loader); + SystemDictionary::set_platform_loader(platform_loader_data); ClassLoaderDataShared::restore_java_platform_loader_from_archive(platform_loader_data); ClassLoaderData* system_loader_data = SystemDictionary::register_loader(h_system_loader); + SystemDictionary::set_system_loader(system_loader_data); + // system_loader_data here is always an instance of jdk.internal.loader.ClassLoader$AppClassLoader. + // However, if -Djava.system.class.loader=xxx is specified, java_platform_loader() would + // be an instance of a user-defined class, so make sure this never happens. + assert(Arguments::get_property("java.system.class.loader") == NULL, + "archived full module should have been disabled if -Djava.system.class.loader is specified"); ClassLoaderDataShared::restore_java_system_loader_from_archive(system_loader_data); } diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 608ecdb3ffd..71b4ebc0934 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -62,6 +62,8 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" +#include "oops/oop.hpp" +#include "oops/oopHandle.hpp" #include "oops/oopHandle.inline.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" @@ -87,7 +89,32 @@ #include "jfr/jfr.hpp" #endif -SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; +class InvokeMethodKey : public StackObj { + private: + Symbol* _symbol; + intptr_t _iid; + + public: + InvokeMethodKey(Symbol* symbol, intptr_t iid) : + _symbol(symbol), + _iid(iid) {} + + static bool key_comparison(InvokeMethodKey const &k1, InvokeMethodKey const &k2){ + return k1._symbol == k2._symbol && k1._iid == k2._iid; + } + + static unsigned int compute_hash(const InvokeMethodKey &k) { + Symbol* sym = k._symbol; + intptr_t iid = k._iid; + unsigned int hash = (unsigned int) sym -> identity_hash(); + return (unsigned int) (hash ^ iid); + } + +}; + +ResourceHashtable _invoke_method_intrinsic_table; +ResourceHashtable _invoke_method_type_table; ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL; OopHandle SystemDictionary::_java_system_loader; @@ -120,23 +147,53 @@ oop SystemDictionary::java_platform_loader() { } void SystemDictionary::compute_java_loaders(TRAPS) { + if (_java_system_loader.is_empty()) { + oop system_loader = get_system_class_loader_impl(CHECK); + _java_system_loader = OopHandle(Universe::vm_global(), system_loader); + } else { + // It must have been restored from the archived module graph + assert(UseSharedSpaces, "must be"); + assert(MetaspaceShared::use_full_module_graph(), "must be"); + DEBUG_ONLY( + oop system_loader = get_system_class_loader_impl(CHECK); + assert(_java_system_loader.resolve() == system_loader, "must be"); + ) + } + + if (_java_platform_loader.is_empty()) { + oop platform_loader = get_platform_class_loader_impl(CHECK); + _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader); + } else { + // It must have been restored from the archived module graph + assert(UseSharedSpaces, "must be"); + assert(MetaspaceShared::use_full_module_graph(), "must be"); + DEBUG_ONLY( + oop platform_loader = get_platform_class_loader_impl(CHECK); + assert(_java_platform_loader.resolve() == platform_loader, "must be"); + ) + } +} + +oop SystemDictionary::get_system_class_loader_impl(TRAPS) { JavaValue result(T_OBJECT); InstanceKlass* class_loader_klass = vmClasses::ClassLoader_klass(); JavaCalls::call_static(&result, class_loader_klass, vmSymbols::getSystemClassLoader_name(), vmSymbols::void_classloader_signature(), - CHECK); - - _java_system_loader = OopHandle(Universe::vm_global(), result.get_oop()); + CHECK_NULL); + return result.get_oop(); +} +oop SystemDictionary::get_platform_class_loader_impl(TRAPS) { + JavaValue result(T_OBJECT); + InstanceKlass* class_loader_klass = vmClasses::ClassLoader_klass(); JavaCalls::call_static(&result, class_loader_klass, vmSymbols::getPlatformClassLoader_name(), vmSymbols::void_classloader_signature(), - CHECK); - - _java_platform_loader = OopHandle(Universe::vm_global(), result.get_oop()); + CHECK_NULL); + return result.get_oop(); } ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool create_mirror_cld) { @@ -149,6 +206,18 @@ ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool cre } } +void SystemDictionary::set_system_loader(ClassLoaderData *cld) { + if (_java_system_loader.is_empty()) { + _java_system_loader = cld->class_loader_handle(); + } +} + +void SystemDictionary::set_platform_loader(ClassLoaderData *cld) { + if (_java_platform_loader.is_empty()) { + _java_platform_loader = cld->class_loader_handle(); + } +} + // ---------------------------------------------------------------------------- // Parallel class loading check @@ -1633,10 +1702,21 @@ bool SystemDictionary::do_unloading(GCTimer* gc_timer) { void SystemDictionary::methods_do(void f(Method*)) { // Walk methods in loaded classes - MutexLocker ml(ClassLoaderDataGraph_lock); - ClassLoaderDataGraph::methods_do(f); - // Walk method handle intrinsics - invoke_method_table()->methods_do(f); + + { + MutexLocker ml(ClassLoaderDataGraph_lock); + ClassLoaderDataGraph::methods_do(f); + } + + auto doit = [&] (InvokeMethodKey key, Method* method) { + f(method); + }; + + { + MutexLocker ml(InvokeMethodTable_lock); + _invoke_method_intrinsic_table.iterate_all(doit); + } + } // ---------------------------------------------------------------------------- @@ -1646,7 +1726,6 @@ void SystemDictionary::initialize(TRAPS) { // Allocate arrays _placeholders = new PlaceholderTable(_placeholder_table_size); _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); - _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize); #if INCLUDE_CDS @@ -1994,6 +2073,7 @@ Symbol* SystemDictionary::check_signature_loaders(Symbol* signature, Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid, Symbol* signature, TRAPS) { + methodHandle empty; const int iid_as_int = vmIntrinsics::as_int(iid); assert(MethodHandles::is_signature_polymorphic(iid) && @@ -2001,16 +2081,19 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid, iid != vmIntrinsics::_invokeGeneric, "must be a known MH intrinsic iid=%d: %s", iid_as_int, vmIntrinsics::name_at(iid)); - unsigned int hash = invoke_method_table()->compute_hash(signature, iid_as_int); - int index = invoke_method_table()->hash_to_index(hash); - SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, iid_as_int); - methodHandle m; - if (spe == NULL || spe->method() == NULL) { - spe = NULL; - // Must create lots of stuff here, but outside of the SystemDictionary lock. - m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL); - if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) { - // Generate a compiled form of the MH intrinsic. + Method** met; + InvokeMethodKey key(signature, iid_as_int); + { + MutexLocker ml(THREAD, InvokeMethodTable_lock); + met = _invoke_method_intrinsic_table.get(key); + if (met != nullptr) { + return *met; + } + } + + methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL); + if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) { + // Generate a compiled form of the MH intrinsic // linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version. AdapterHandlerLibrary::create_native_wrapper(m); // Check if have the compiled code. @@ -2018,24 +2101,20 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid, THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for method handle intrinsic"); } - } - // Now grab the lock. We might have to throw away the new method, - // if a racing thread has managed to install one at the same time. - { - MutexLocker ml(THREAD, SystemDictionary_lock); - spe = invoke_method_table()->find_entry(index, hash, signature, iid_as_int); - if (spe == NULL) - spe = invoke_method_table()->add_entry(index, hash, signature, iid_as_int); - if (spe->method() == NULL) - spe->set_method(m()); - } } - - assert(spe != NULL && spe->method() != NULL, ""); - assert(Arguments::is_interpreter_only() || (spe->method()->has_compiled_code() && - spe->method()->code()->entry_point() == spe->method()->from_compiled_entry()), + // Now grab the lock. We might have to throw away the new method, + // if a racing thread has managed to install one at the same time. + { + MutexLocker ml(THREAD, InvokeMethodTable_lock); + signature->make_permanent(); // The signature is never unloaded. + bool created; + met = _invoke_method_intrinsic_table.put_if_absent(key, m(), &created); + Method* saved_method = *met; + assert(Arguments::is_interpreter_only() || (saved_method->has_compiled_code() && + saved_method->code()->entry_point() == saved_method->from_compiled_entry()), "MH intrinsic invariant"); - return spe->method(); + return saved_method; + } } // Helper for unpacking the return value from linkMethod and linkCallSite. @@ -2176,13 +2255,16 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, Klass* accessing_klass, TRAPS) { Handle empty; - int null_iid = vmIntrinsics::as_int(vmIntrinsics::_none); // distinct from all method handle invoker intrinsics - unsigned int hash = invoke_method_table()->compute_hash(signature, null_iid); - int index = invoke_method_table()->hash_to_index(hash); - SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, null_iid); - if (spe != NULL && spe->method_type() != NULL) { - assert(java_lang_invoke_MethodType::is_instance(spe->method_type()), ""); - return Handle(THREAD, spe->method_type()); + OopHandle* o; + { + MutexLocker ml(THREAD, InvokeMethodTable_lock); + o = _invoke_method_type_table.get(signature); + } + + if (o != nullptr) { + oop mt = o->resolve(); + assert(java_lang_invoke_MethodType::is_instance(mt), ""); + return Handle(THREAD, mt); } else if (!THREAD->can_call_java()) { warning("SystemDictionary::find_method_handle_type called from compiler thread"); // FIXME return Handle(); // do not attempt from within compiler, unless it was cached @@ -2244,15 +2326,17 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, if (can_be_cached) { // We can cache this MethodType inside the JVM. - MutexLocker ml(THREAD, SystemDictionary_lock); - spe = invoke_method_table()->find_entry(index, hash, signature, null_iid); - if (spe == NULL) - spe = invoke_method_table()->add_entry(index, hash, signature, null_iid); - if (spe->method_type() == NULL) { - spe->set_method_type(method_type()); + MutexLocker ml(THREAD, InvokeMethodTable_lock); + bool created = false; + assert(method_type != NULL, "unexpected null"); + OopHandle* h = _invoke_method_type_table.get(signature); + if (h == nullptr) { + signature->make_permanent(); // The signature is never unloaded. + OopHandle elem = OopHandle(Universe::vm_global(), method_type()); + bool created = _invoke_method_type_table.put(signature, elem); + assert(created, "better be created"); } } - // report back to the caller with the MethodType return method_type; } @@ -2451,21 +2535,6 @@ void SystemDictionary::dump(outputStream *st, bool verbose) { } } -TableStatistics SystemDictionary::placeholders_statistics() { - MutexLocker ml(SystemDictionary_lock); - return placeholders()->statistics_calculate(); -} - -TableStatistics SystemDictionary::loader_constraints_statistics() { - MutexLocker ml(SystemDictionary_lock); - return constraints()->statistics_calculate(); -} - -TableStatistics SystemDictionary::protection_domain_cache_statistics() { - MutexLocker ml(SystemDictionary_lock); - return pd_cache_table()->statistics_calculate(); -} - // Utility for dumping dictionaries. SystemDictionaryDCmd::SystemDictionaryDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index c09bc0791b7..6b1bb6a6a74 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -78,7 +78,6 @@ class ProtectionDomainCacheEntry; class GCTimer; class EventClassLoad; class Symbol; -class TableStatistics; class SystemDictionary : AllStatic { friend class BootstrapInfo; @@ -133,6 +132,9 @@ class SystemDictionary : AllStatic { const ClassLoadInfo& cl_info, TRAPS); + static oop get_system_class_loader_impl(TRAPS); + static oop get_platform_class_loader_impl(TRAPS); + public: // Resolve either a hidden or normal class from a stream of bytes, based on ClassLoadInfo static InstanceKlass* resolve_from_stream(ClassFileStream* st, @@ -218,6 +220,9 @@ public: // Register a new class loader static ClassLoaderData* register_loader(Handle class_loader, bool create_mirror_cld = false); + static void set_system_loader(ClassLoaderData *cld); + static void set_platform_loader(ClassLoaderData *cld); + static Symbol* check_signature_loaders(Symbol* signature, Klass* klass_being_linked, Handle loader1, Handle loader2, bool is_method); @@ -400,11 +405,6 @@ protected: bool defining, TRAPS); static void update_dictionary(unsigned int hash, InstanceKlass* k, Handle loader); - -public: - static TableStatistics placeholders_statistics(); - static TableStatistics loader_constraints_statistics(); - static TableStatistics protection_domain_cache_statistics(); }; #endif // SHARE_CLASSFILE_SYSTEMDICTIONARY_HPP diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 781bb395733..5371692c0d5 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -515,35 +515,6 @@ void SystemDictionaryShared::init_dumptime_info(InstanceKlass* k) { void SystemDictionaryShared::remove_dumptime_info(InstanceKlass* k) { MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); - DumpTimeClassInfo* p = _dumptime_table->get(k); - if (p == NULL) { - return; - } - if (p->_verifier_constraints != NULL) { - for (int i = 0; i < p->_verifier_constraints->length(); i++) { - DumpTimeClassInfo::DTVerifierConstraint constraint = p->_verifier_constraints->at(i); - if (constraint._name != NULL ) { - constraint._name->decrement_refcount(); - } - if (constraint._from_name != NULL ) { - constraint._from_name->decrement_refcount(); - } - } - FREE_C_HEAP_ARRAY(DumpTimeClassInfo::DTVerifierConstraint, p->_verifier_constraints); - p->_verifier_constraints = NULL; - FREE_C_HEAP_ARRAY(char, p->_verifier_constraint_flags); - p->_verifier_constraint_flags = NULL; - } - if (p->_loader_constraints != NULL) { - for (int i = 0; i < p->_loader_constraints->length(); i++) { - DumpTimeClassInfo::DTLoaderConstraint ld = p->_loader_constraints->at(i); - if (ld._name != NULL) { - ld._name->decrement_refcount(); - } - } - FREE_C_HEAP_ARRAY(DumpTimeClassInfo::DTLoaderConstraint, p->_loader_constraints); - p->_loader_constraints = NULL; - } _dumptime_table->remove(k); } @@ -759,16 +730,11 @@ void SystemDictionaryShared::add_to_dump_time_lambda_proxy_class_dictionary(Lamb InstanceKlass* proxy_klass) { assert_lock_strong(DumpTimeTable_lock); - DumpTimeLambdaProxyClassInfo* lambda_info = _dumptime_lambda_proxy_class_dictionary->get(key); - if (lambda_info == NULL) { - DumpTimeLambdaProxyClassInfo info; - info.add_proxy_klass(proxy_klass); - _dumptime_lambda_proxy_class_dictionary->put(key, info); - //lambda_info = _dumptime_lambda_proxy_class_dictionary->get(key); - //assert(lambda_info->_proxy_klass == proxy_klass, "must be"); // debug only -- remove + bool created; + DumpTimeLambdaProxyClassInfo* info = _dumptime_lambda_proxy_class_dictionary->put_if_absent(key, &created); + info->add_proxy_klass(proxy_klass); + if (created) { ++_dumptime_lambda_proxy_class_dictionary->_count; - } else { - lambda_info->add_proxy_klass(proxy_klass); } } @@ -1484,7 +1450,8 @@ class CloneDumpTimeClassTable: public StackObj { void do_entry(InstanceKlass* k, DumpTimeClassInfo& info) { if (!info.is_excluded()) { bool created; - _cloned_table->put_if_absent(k, info.clone(), &created); + _cloned_table->put_if_absent(k, info, &created); + assert(created, "must be"); } } }; @@ -1505,12 +1472,25 @@ class CloneDumpTimeLambdaProxyClassTable: StackObj { bool created; // make copies then store in _clone_table LambdaProxyClassKey keyCopy = key; - _cloned_table->put_if_absent(keyCopy, info.clone(), &created); + _cloned_table->put_if_absent(keyCopy, info, &created); + assert(created, "must be"); ++ _cloned_table->_count; return true; // keep on iterating } }; +// When dumping the CDS archive, the ArchiveBuilder will irrecoverably modify the +// _dumptime_table and _dumptime_lambda_proxy_class_dictionary (e.g., metaspace +// pointers are changed to use "buffer" addresses.) +// +// We save a copy of these tables and restore them after the dumping is finished. +// This makes it possible to repeat the dumping operation (e.g., use +// "jcmd VM.cds dynamic_dump" multiple times on the same JVM process). +// +// We use the copy constructors to clone the values in these tables. The copy constructors +// must make a deep copy, as internal data structures such as the contents of +// DumpTimeClassInfo::_loader_constraints are also modified by the ArchiveBuilder. + void SystemDictionaryShared::clone_dumptime_tables() { Arguments::assert_is_dumping_archive(); assert_lock_strong(DumpTimeTable_lock); diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 3c22508babc..dbb0269ecf0 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -41,14 +41,12 @@ class OopMapSet; // CodeBlob Types // Used in the CodeCache to assign CodeBlobs to different CodeHeaps -struct CodeBlobType { - enum { - MethodNonProfiled = 0, // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) - MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods - NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs - All = 3, // All types (No code cache segmentation) - NumTypes = 4 // Number of CodeBlobTypes - }; +enum class CodeBlobType { + MethodNonProfiled = 0, // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) + MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods + NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs + All = 3, // All types (No code cache segmentation) + NumTypes = 4 // Number of CodeBlobTypes }; // CodeBlob - superclass for all entries in the CodeCache. diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 00cd0601dbd..e639f166479 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -57,6 +57,7 @@ #include "runtime/icache.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safepointVerifiers.hpp" #include "runtime/sweeper.hpp" #include "runtime/vmThread.hpp" @@ -172,10 +173,10 @@ int CodeCache::Sweep::_compiled_method_iterators = 0; bool CodeCache::Sweep::_pending_sweep = false; // Initialize arrays of CodeHeap subsets -GrowableArray* CodeCache::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, mtCode); -GrowableArray* CodeCache::_compiled_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, mtCode); -GrowableArray* CodeCache::_nmethod_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, mtCode); -GrowableArray* CodeCache::_allocable_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, mtCode); +GrowableArray* CodeCache::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (static_cast(CodeBlobType::All), mtCode); +GrowableArray* CodeCache::_compiled_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (static_cast(CodeBlobType::All), mtCode); +GrowableArray* CodeCache::_nmethod_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (static_cast(CodeBlobType::All), mtCode); +GrowableArray* CodeCache::_allocable_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (static_cast(CodeBlobType::All), mtCode); void CodeCache::check_heap_sizes(size_t non_nmethod_size, size_t profiled_size, size_t non_profiled_size, size_t cache_size, bool all_set) { size_t total_size = non_nmethod_size + profiled_size + non_profiled_size; @@ -369,7 +370,7 @@ ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) { } // Heaps available for allocation -bool CodeCache::heap_available(int code_blob_type) { +bool CodeCache::heap_available(CodeBlobType code_blob_type) { if (!SegmentedCodeCache) { // No segmentation: use a single code heap return (code_blob_type == CodeBlobType::All); @@ -386,7 +387,7 @@ bool CodeCache::heap_available(int code_blob_type) { } } -const char* CodeCache::get_code_heap_flag_name(int code_blob_type) { +const char* CodeCache::get_code_heap_flag_name(CodeBlobType code_blob_type) { switch(code_blob_type) { case CodeBlobType::NonNMethod: return "NonNMethodCodeHeapSize"; @@ -397,16 +398,17 @@ const char* CodeCache::get_code_heap_flag_name(int code_blob_type) { case CodeBlobType::MethodProfiled: return "ProfiledCodeHeapSize"; break; + default: + ShouldNotReachHere(); + return NULL; } - ShouldNotReachHere(); - return NULL; } int CodeCache::code_heap_compare(CodeHeap* const &lhs, CodeHeap* const &rhs) { if (lhs->code_blob_type() == rhs->code_blob_type()) { return (lhs > rhs) ? 1 : ((lhs < rhs) ? -1 : 0); } else { - return lhs->code_blob_type() - rhs->code_blob_type(); + return static_cast(lhs->code_blob_type()) - static_cast(rhs->code_blob_type()); } } @@ -415,7 +417,7 @@ void CodeCache::add_heap(CodeHeap* heap) { _heaps->insert_sorted(heap); - int type = heap->code_blob_type(); + CodeBlobType type = heap->code_blob_type(); if (code_blob_type_accepts_compiled(type)) { _compiled_heaps->insert_sorted(heap); } @@ -427,7 +429,7 @@ void CodeCache::add_heap(CodeHeap* heap) { } } -void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) { +void CodeCache::add_heap(ReservedSpace rs, const char* name, CodeBlobType code_blob_type) { // Check if heap is needed if (!heap_available(code_blob_type)) { return; @@ -469,7 +471,7 @@ CodeHeap* CodeCache::get_code_heap(const CodeBlob* cb) { return NULL; } -CodeHeap* CodeCache::get_code_heap(int code_blob_type) { +CodeHeap* CodeCache::get_code_heap(CodeBlobType code_blob_type) { FOR_ALL_HEAPS(heap) { if ((*heap)->accepts(code_blob_type)) { return *heap; @@ -518,7 +520,7 @@ CodeBlob* CodeCache::first_blob(CodeHeap* heap) { return (CodeBlob*)heap->first(); } -CodeBlob* CodeCache::first_blob(int code_blob_type) { +CodeBlob* CodeCache::first_blob(CodeBlobType code_blob_type) { if (heap_available(code_blob_type)) { return first_blob(get_code_heap(code_blob_type)); } else { @@ -539,7 +541,7 @@ CodeBlob* CodeCache::next_blob(CodeHeap* heap, CodeBlob* cb) { * run the constructor for the CodeBlob subclass he is busy * instantiating. */ -CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool handle_alloc_failure, int orig_code_blob_type) { +CodeBlob* CodeCache::allocate(int size, CodeBlobType code_blob_type, bool handle_alloc_failure, CodeBlobType orig_code_blob_type) { // Possibly wakes up the sweeper thread. NMethodSweeper::report_allocation(); assert_locked_or_safepoint(CodeCache_lock); @@ -567,7 +569,7 @@ CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool handle_alloc_fa // NonNMethod -> MethodNonProfiled -> MethodProfiled (-> MethodNonProfiled) // Note that in the sweeper, we check the reverse_free_ratio of the code heap // and force stack scanning if less than 10% of the entire code cache are free. - int type = code_blob_type; + CodeBlobType type = code_blob_type; switch (type) { case CodeBlobType::NonNMethod: type = CodeBlobType::MethodNonProfiled; @@ -581,6 +583,8 @@ CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool handle_alloc_fa type = CodeBlobType::MethodNonProfiled; } break; + default: + break; } if (type != code_blob_type && type != orig_code_blob_type && heap_available(type)) { if (PrintCodeCacheExtension) { @@ -872,7 +876,7 @@ void CodeCache::verify_oops() { } } -int CodeCache::blob_count(int code_blob_type) { +int CodeCache::blob_count(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? heap->blob_count() : 0; } @@ -885,7 +889,7 @@ int CodeCache::blob_count() { return count; } -int CodeCache::nmethod_count(int code_blob_type) { +int CodeCache::nmethod_count(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? heap->nmethod_count() : 0; } @@ -898,7 +902,7 @@ int CodeCache::nmethod_count() { return count; } -int CodeCache::adapter_count(int code_blob_type) { +int CodeCache::adapter_count(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? heap->adapter_count() : 0; } @@ -911,12 +915,12 @@ int CodeCache::adapter_count() { return count; } -address CodeCache::low_bound(int code_blob_type) { +address CodeCache::low_bound(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? (address)heap->low_boundary() : NULL; } -address CodeCache::high_bound(int code_blob_type) { +address CodeCache::high_bound(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? (address)heap->high_boundary() : NULL; } @@ -929,7 +933,7 @@ size_t CodeCache::capacity() { return cap; } -size_t CodeCache::unallocated_capacity(int code_blob_type) { +size_t CodeCache::unallocated_capacity(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? heap->unallocated_capacity() : 0; } @@ -1304,7 +1308,7 @@ void CodeCache::verify() { // A CodeHeap is full. Print out warning and report event. PRAGMA_DIAG_PUSH PRAGMA_FORMAT_NONLITERAL_IGNORED -void CodeCache::report_codemem_full(int code_blob_type, bool print) { +void CodeCache::report_codemem_full(CodeBlobType code_blob_type, bool print) { // Get nmethod heap for the given CodeBlobType and build CodeCacheFull event CodeHeap* heap = get_code_heap(code_blob_type); assert(heap != NULL, "heap is null"); diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 0e2414ffa3a..becb8079418 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -104,17 +104,17 @@ class CodeCache : AllStatic { // Check the code heap sizes set by the user via command line static void check_heap_sizes(size_t non_nmethod_size, size_t profiled_size, size_t non_profiled_size, size_t cache_size, bool all_set); // Creates a new heap with the given name and size, containing CodeBlobs of the given type - static void add_heap(ReservedSpace rs, const char* name, int code_blob_type); + static void add_heap(ReservedSpace rs, const char* name, CodeBlobType code_blob_type); static CodeHeap* get_code_heap_containing(void* p); // Returns the CodeHeap containing the given pointer, or NULL static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob - static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType + static CodeHeap* get_code_heap(CodeBlobType code_blob_type); // Returns the CodeHeap for the given CodeBlobType // Returns the name of the VM option to set the size of the corresponding CodeHeap - static const char* get_code_heap_flag_name(int code_blob_type); + static const char* get_code_heap_flag_name(CodeBlobType code_blob_type); static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps // Iteration static CodeBlob* first_blob(CodeHeap* heap); // Returns the first CodeBlob on the given CodeHeap - static CodeBlob* first_blob(int code_blob_type); // Returns the first CodeBlob of the given type + static CodeBlob* first_blob(CodeBlobType code_blob_type); // Returns the first CodeBlob of the given type static CodeBlob* next_blob(CodeHeap* heap, CodeBlob* cb); // Returns the next CodeBlob on the given CodeHeap public: @@ -153,7 +153,7 @@ class CodeCache : AllStatic { static const GrowableArray* nmethod_heaps() { return _nmethod_heaps; } // Allocation/administration - static CodeBlob* allocate(int size, int code_blob_type, bool handle_alloc_failure = true, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob + static CodeBlob* allocate(int size, CodeBlobType code_blob_type, bool handle_alloc_failure = true, CodeBlobType orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled static int alignment_unit(); // guaranteed alignment of all CodeBlobs static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header) @@ -176,11 +176,11 @@ class CodeCache : AllStatic { static CompiledMethod* find_compiled(void* start); static int blob_count(); // Returns the total number of CodeBlobs in the cache - static int blob_count(int code_blob_type); + static int blob_count(CodeBlobType code_blob_type); static int adapter_count(); // Returns the total number of Adapters in the cache - static int adapter_count(int code_blob_type); + static int adapter_count(CodeBlobType code_blob_type); static int nmethod_count(); // Returns the total number of nmethods in the cache - static int nmethod_count(int code_blob_type); + static int nmethod_count(CodeBlobType code_blob_type); // GC support static void verify_oops(); @@ -214,8 +214,8 @@ class CodeCache : AllStatic { static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage static void log_state(outputStream* st); LINUX_ONLY(static void write_perf_map();) - static const char* get_code_heap_name(int code_blob_type) { return (heap_available(code_blob_type) ? get_code_heap(code_blob_type)->name() : "Unused"); } - static void report_codemem_full(int code_blob_type, bool print); + static const char* get_code_heap_name(CodeBlobType code_blob_type) { return (heap_available(code_blob_type) ? get_code_heap(code_blob_type)->name() : "Unused"); } + static void report_codemem_full(CodeBlobType code_blob_type, bool print); // Dcmd (Diagnostic commands) static void print_codelist(outputStream* st); @@ -223,13 +223,13 @@ class CodeCache : AllStatic { // The full limits of the codeCache static address low_bound() { return _low_bound; } - static address low_bound(int code_blob_type); + static address low_bound(CodeBlobType code_blob_type); static address high_bound() { return _high_bound; } - static address high_bound(int code_blob_type); + static address high_bound(CodeBlobType code_blob_type); // Profiling static size_t capacity(); - static size_t unallocated_capacity(int code_blob_type); + static size_t unallocated_capacity(CodeBlobType code_blob_type); static size_t unallocated_capacity(); static size_t max_capacity(); @@ -242,29 +242,29 @@ class CodeCache : AllStatic { static void cleanup_inline_caches(); // clean unloaded/zombie nmethods from inline caches // Returns true if an own CodeHeap for the given CodeBlobType is available - static bool heap_available(int code_blob_type); + static bool heap_available(CodeBlobType code_blob_type); // Returns the CodeBlobType for the given CompiledMethod - static int get_code_blob_type(CompiledMethod* cm) { + static CodeBlobType get_code_blob_type(CompiledMethod* cm) { return get_code_heap(cm)->code_blob_type(); } - static bool code_blob_type_accepts_compiled(int type) { - bool result = type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled; + static bool code_blob_type_accepts_compiled(CodeBlobType code_blob_type) { + bool result = code_blob_type == CodeBlobType::All || code_blob_type <= CodeBlobType::MethodProfiled; return result; } - static bool code_blob_type_accepts_nmethod(int type) { + static bool code_blob_type_accepts_nmethod(CodeBlobType type) { return type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled; } - static bool code_blob_type_accepts_allocable(int type) { + static bool code_blob_type_accepts_allocable(CodeBlobType type) { return type <= CodeBlobType::All; } // Returns the CodeBlobType for the given compilation level - static int get_code_blob_type(int comp_level) { + static CodeBlobType get_code_blob_type(int comp_level) { if (comp_level == CompLevel_none || comp_level == CompLevel_simple || comp_level == CompLevel_full_optimization) { @@ -276,7 +276,7 @@ class CodeCache : AllStatic { return CodeBlobType::MethodProfiled; } ShouldNotReachHere(); - return 0; + return static_cast(0); } static void verify_clean_inline_caches(); @@ -309,7 +309,7 @@ class CodeCache : AllStatic { // tells how many nmethods have dependencies static int number_of_nmethods_with_dependencies(); - static int get_codemem_full_count(int code_blob_type) { + static int get_codemem_full_count(CodeBlobType code_blob_type) { CodeHeap* heap = get_code_heap(code_blob_type); return (heap != NULL) ? heap->full_count() : 0; } diff --git a/src/hotspot/share/code/vmreg.cpp b/src/hotspot/share/code/vmreg.cpp index 969dccd7d01..77c6e235fd6 100644 --- a/src/hotspot/share/code/vmreg.cpp +++ b/src/hotspot/share/code/vmreg.cpp @@ -41,11 +41,11 @@ const int VMRegImpl::register_count = ConcreteRegisterImpl::number_of_registers; const char *VMRegImpl::regName[ConcreteRegisterImpl::number_of_registers]; void VMRegImpl::print_on(outputStream* st) const { - if( is_reg() ) { + if (is_reg()) { assert(VMRegImpl::regName[value()], "VMRegImpl::regName[" INTPTR_FORMAT "] returns NULL", value()); st->print("%s",VMRegImpl::regName[value()]); } else if (is_stack()) { - int stk = value() - stack0->value(); + int stk = reg2stack(); st->print("[%d]", stk*4); } else { st->print("BAD!"); diff --git a/src/hotspot/share/code/vmreg.hpp b/src/hotspot/share/code/vmreg.hpp index bc5cbfbe009..59ac28c4cf8 100644 --- a/src/hotspot/share/code/vmreg.hpp +++ b/src/hotspot/share/code/vmreg.hpp @@ -73,12 +73,12 @@ public: return first() + ((ConcreteRegisterImpl::number_of_registers + 7) & ~7); } - static VMReg as_VMReg(int val, bool bad_ok = false) { + static VMReg as_VMReg(int val, bool bad_ok = false) { assert(val > BAD_REG || bad_ok, "invalid"); return val + first(); } - const char* name() { + const char* name() { if (is_reg()) { return regName[value()]; } else if (!is_valid()) { @@ -130,7 +130,7 @@ public: // amounts that are part of the native abi. The VMReg must be a stack slot // and the result must be also. - VMReg bias(int offset) { + VMReg bias(int offset) const { assert(is_stack(), "must be"); // VMReg res = VMRegImpl::as_VMReg(value() + offset); VMReg res = stack2reg(reg2stack() + offset); @@ -139,12 +139,12 @@ public: } // Convert register numbers to stack slots and vice versa - static VMReg stack2reg( int idx ) { + static VMReg stack2reg(int idx) { return stack_0() + idx; } - uintptr_t reg2stack() { - assert( is_stack(), "Not a stack-based register" ); + uintptr_t reg2stack() const { + assert(is_stack(), "Not a stack-based register"); return this - stack_0(); } diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 32cad14823e..6e34d551eaa 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -2417,7 +2417,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { * This function needs to be called only from CodeCache::allocate(), * since we currently handle a full code cache uniformly. */ -void CompileBroker::handle_full_code_cache(int code_blob_type) { +void CompileBroker::handle_full_code_cache(CodeBlobType code_blob_type) { UseInterpreter = true; if (UseCompiler || AlwaysCompileLoopMethods ) { if (xtty != NULL) { diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index 5c7bb3a2018..0dd5c90edd1 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -358,7 +358,7 @@ public: static bool is_compilation_disabled_forever() { return _should_compile_new_jobs == shutdown_compilation; } - static void handle_full_code_cache(int code_blob_type); + static void handle_full_code_cache(CodeBlobType code_blob_type); // Ensures that warning is only printed once. static bool should_print_compiler_warning() { jint old = Atomic::cmpxchg(&_print_compilation_warning, 0, 1); diff --git a/src/hotspot/share/gc/g1/g1Allocator.cpp b/src/hotspot/share/gc/g1/g1Allocator.cpp index f5c2c32b544..d6d93b69a3e 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.cpp +++ b/src/hotspot/share/gc/g1/g1Allocator.cpp @@ -429,8 +429,14 @@ void G1PLABAllocator::flush_and_retire_stats(uint num_workers) { } log_trace(gc, plab)("PLAB boost: Young %zu -> %zu refills %zu (tolerated %zu) Old %zu -> %zu refills %zu (tolerated %zu)", - _g1h->alloc_buffer_stats(G1HeapRegionAttr::Young)->desired_plab_sz(num_workers), plab_size(G1HeapRegionAttr::Young), _num_plab_fills[G1HeapRegionAttr::Young], _tolerated_refills, - _g1h->alloc_buffer_stats(G1HeapRegionAttr::Old)->desired_plab_sz(num_workers), plab_size(G1HeapRegionAttr::Old), _num_plab_fills[G1HeapRegionAttr::Old], _tolerated_refills); + _g1h->alloc_buffer_stats(G1HeapRegionAttr::Young)->desired_plab_size(num_workers), + plab_size(G1HeapRegionAttr::Young), + _num_plab_fills[G1HeapRegionAttr::Young], + _tolerated_refills, + _g1h->alloc_buffer_stats(G1HeapRegionAttr::Old)->desired_plab_size(num_workers), + plab_size(G1HeapRegionAttr::Old), + _num_plab_fills[G1HeapRegionAttr::Old], + _tolerated_refills); } size_t G1PLABAllocator::waste() const { diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 1e1550d0623..6042c18823d 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -2838,8 +2838,8 @@ G1JFRTracerMark::~G1JFRTracerMark() { void G1CollectedHeap::prepare_tlabs_for_mutator() { Ticks start = Ticks::now(); - _survivor_evac_stats.adjust_desired_plab_sz(); - _old_evac_stats.adjust_desired_plab_sz(); + _survivor_evac_stats.adjust_desired_plab_size(); + _old_evac_stats.adjust_desired_plab_size(); allocate_dummy_regions(); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp index cfd197aabe5..6482fbd077f 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp @@ -66,7 +66,7 @@ G1EvacStats* G1CollectedHeap::alloc_buffer_stats(G1HeapRegionAttr dest) { } size_t G1CollectedHeap::desired_plab_sz(G1HeapRegionAttr dest) { - size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(workers()->active_workers()); + size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_size(workers()->active_workers()); return clamp_plab_size(gclab_word_size); } diff --git a/src/hotspot/share/gc/g1/g1EvacStats.cpp b/src/hotspot/share/gc/g1/g1EvacStats.cpp index 1c615a6b679..85ec939e79e 100644 --- a/src/hotspot/share/gc/g1/g1EvacStats.cpp +++ b/src/hotspot/share/gc/g1/g1EvacStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,18 @@ #include "runtime/globals.hpp" void G1EvacStats::log_plab_allocation() { - PLABStats::log_plab_allocation(); + log_debug(gc, plab)("%s PLAB allocation: " + "allocated: %zuB, " + "wasted: %zuB, " + "unused: %zuB, " + "used: %zuB, " + "undo waste: %zuB, ", + _description, + _allocated * HeapWordSize, + _wasted * HeapWordSize, + _unused * HeapWordSize, + used() * HeapWordSize, + _undo_wasted * HeapWordSize); log_debug(gc, plab)("%s other allocation: " "region end waste: %zuB, " "regions filled: %u, " @@ -50,7 +61,16 @@ void G1EvacStats::log_plab_allocation() { _failure_waste * HeapWordSize); } -size_t G1EvacStats::compute_desired_plab_sz() { +void G1EvacStats::log_sizing(size_t calculated_words, size_t net_desired_words) { + log_debug(gc, plab)("%s sizing: " + "calculated: %zuB, " + "actual: %zuB", + _description, + calculated_words * HeapWordSize, + net_desired_words * HeapWordSize); +} + +size_t G1EvacStats::compute_desired_plab_size() const { // The size of the PLAB caps the amount of space that can be wasted at the // end of the collection. In the worst case the last PLAB could be completely // empty. @@ -93,12 +113,14 @@ size_t G1EvacStats::compute_desired_plab_sz() { size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0; size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct; - size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy); - return cur_plab_sz; + return (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy); } G1EvacStats::G1EvacStats(const char* description, size_t default_per_thread_plab_size, unsigned wt) : - PLABStats(description, default_per_thread_plab_size, default_per_thread_plab_size * ParallelGCThreads, wt), + PLABStats(description), + _default_plab_size(default_per_thread_plab_size), + _desired_net_plab_size(default_per_thread_plab_size * ParallelGCThreads), + _net_plab_size_filter(wt), _region_end_waste(0), _regions_filled(0), _num_plab_filled(0), @@ -108,5 +130,36 @@ G1EvacStats::G1EvacStats(const char* description, size_t default_per_thread_plab _failure_waste(0) { } +// Calculates plab size for current number of gc worker threads. +size_t G1EvacStats::desired_plab_size(uint no_of_gc_workers) const { + if (!ResizePLAB) { + return _default_plab_size; + } + return align_object_size(clamp(_desired_net_plab_size / no_of_gc_workers, min_size(), max_size())); +} -G1EvacStats::~G1EvacStats() { } +void G1EvacStats::adjust_desired_plab_size() { + log_plab_allocation(); + + if (ResizePLAB) { + assert(is_object_aligned(max_size()) && min_size() <= max_size(), + "PLAB clipping computation may be incorrect"); + + assert(_allocated != 0 || _unused == 0, + "Inconsistency in PLAB stats: " + "_allocated: %zu, " + "_wasted: %zu, " + "_unused: %zu, " + "_undo_wasted: %zu", + _allocated, _wasted, _unused, _undo_wasted); + + size_t plab_size = compute_desired_plab_size(); + // Take historical weighted average + _net_plab_size_filter.sample(plab_size); + _desired_net_plab_size = MAX2(min_size(), (size_t)_net_plab_size_filter.average()); + + log_sizing(plab_size, _desired_net_plab_size); + } + // Clear accumulators for next round + reset(); +} diff --git a/src/hotspot/share/gc/g1/g1EvacStats.hpp b/src/hotspot/share/gc/g1/g1EvacStats.hpp index c3ecf98efab..8b7360f55e3 100644 --- a/src/hotspot/share/gc/g1/g1EvacStats.hpp +++ b/src/hotspot/share/gc/g1/g1EvacStats.hpp @@ -26,10 +26,16 @@ #define SHARE_GC_G1_G1EVACSTATS_HPP #include "gc/shared/plab.hpp" +#include "gc/shared/gcUtil.hpp" -// Records various memory allocation statistics gathered during evacuation. +// Records various memory allocation statistics gathered during evacuation. All sizes +// are in HeapWords. class G1EvacStats : public PLABStats { - private: + size_t _default_plab_size; + size_t _desired_net_plab_size; // Output of filter (below), suitably trimmed and quantized + AdaptiveWeightedAverage + _net_plab_size_filter; // Integrator with decay + size_t _region_end_waste; // Number of words wasted due to skipping to the next region. uint _regions_filled; // Number of regions filled completely. size_t _num_plab_filled; // Number of PLABs filled and retired. @@ -55,14 +61,21 @@ class G1EvacStats : public PLABStats { _failure_waste = 0; } - virtual void log_plab_allocation(); + void log_plab_allocation(); + void log_sizing(size_t calculated_words, size_t net_desired_words); - virtual size_t compute_desired_plab_sz(); + size_t compute_desired_plab_size() const; - public: +public: G1EvacStats(const char* description, size_t default_per_thread_plab_size, unsigned wt); - ~G1EvacStats(); + // Calculates plab size for current number of gc worker threads. + size_t desired_plab_size(uint no_of_gc_workers) const; + + // Computes the new desired PLAB size assuming one gc worker thread, updating + // _desired_plab_sz, and clearing statistics for the next GC. + // Should be called at the end of a GC pause. + void adjust_desired_plab_size(); uint regions_filled() const { return _regions_filled; } size_t num_plab_filled() const { return _num_plab_filled; } diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 14a776df376..cff382c5b53 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1668,12 +1668,13 @@ bool G1RemSet::clean_card_before_refine(CardValue** const card_ptr_addr) { } else if (card_ptr != orig_card_ptr) { // Original card was inserted and an old card was evicted. start = _ct->addr_for(card_ptr); - r = _g1h->heap_region_containing(start); + r = _g1h->heap_region_containing_or_null(start); // Check whether the region formerly in the cache should be // ignored, as discussed earlier for the original card. The - // region could have been freed while in the cache. - if (!r->is_old_or_humongous_or_archive()) { + // region could have been freed (or even uncommitted) while + // in the cache. + if (r == nullptr || !r->is_old_or_humongous_or_archive()) { return false; } *card_ptr_addr = card_ptr; diff --git a/src/hotspot/share/gc/g1/g1SegmentedArray.cpp b/src/hotspot/share/gc/g1/g1SegmentedArray.cpp index 2abddc3d6d0..3dedd7ef339 100644 --- a/src/hotspot/share/gc/g1/g1SegmentedArray.cpp +++ b/src/hotspot/share/gc/g1/g1SegmentedArray.cpp @@ -27,6 +27,7 @@ #include "gc/g1/g1SegmentedArray.inline.hpp" #include "memory/allocation.hpp" #include "runtime/atomic.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/globalCounter.inline.hpp" G1SegmentedArraySegment::G1SegmentedArraySegment(uint slot_size, uint num_slots, G1SegmentedArraySegment* next, MEMFLAGS flag) : @@ -48,6 +49,11 @@ G1SegmentedArraySegment* G1SegmentedArraySegment::create_segment(uint slot_size, } void G1SegmentedArraySegment::delete_segment(G1SegmentedArraySegment* segment) { + // Wait for concurrent readers of the segment to exit before freeing; but only if the VM + // isn't exiting. + if (!VM_Exit::vm_exited()) { + GlobalCounter::write_synchronize(); + } segment->~G1SegmentedArraySegment(); FREE_C_HEAP_ARRAY(_mem_flag, segment); } diff --git a/src/hotspot/share/gc/shared/plab.cpp b/src/hotspot/share/gc/shared/plab.cpp index 58d6767854c..3af530c76bc 100644 --- a/src/hotspot/share/gc/shared/plab.cpp +++ b/src/hotspot/share/gc/shared/plab.cpp @@ -114,81 +114,3 @@ void PLAB::undo_allocation(HeapWord* obj, size_t word_sz) { add_undo_waste(obj, word_sz); } } - -void PLABStats::log_plab_allocation() { - log_debug(gc, plab)("%s PLAB allocation: " - "allocated: " SIZE_FORMAT "B, " - "wasted: " SIZE_FORMAT "B, " - "unused: " SIZE_FORMAT "B, " - "used: " SIZE_FORMAT "B, " - "undo waste: " SIZE_FORMAT "B, ", - _description, - _allocated * HeapWordSize, - _wasted * HeapWordSize, - _unused * HeapWordSize, - used() * HeapWordSize, - _undo_wasted * HeapWordSize); -} - -void PLABStats::log_sizing(size_t calculated_words, size_t net_desired_words) { - log_debug(gc, plab)("%s sizing: " - "calculated: " SIZE_FORMAT "B, " - "actual: " SIZE_FORMAT "B", - _description, - calculated_words * HeapWordSize, - net_desired_words * HeapWordSize); -} - -// Calculates plab size for current number of gc worker threads. -size_t PLABStats::desired_plab_sz(uint no_of_gc_workers) const { - if (!ResizePLAB) { - return _default_plab_sz; - } - return align_object_size(clamp(_desired_net_plab_sz / no_of_gc_workers, min_size(), max_size())); -} - -// Compute desired plab size for one gc worker thread and latch result for later -// use. This should be called once at the end of parallel -// scavenge; it clears the sensor accumulators. -void PLABStats::adjust_desired_plab_sz() { - log_plab_allocation(); - - if (!ResizePLAB) { - // Clear accumulators for next round. - reset(); - return; - } - - assert(is_object_aligned(max_size()) && min_size() <= max_size(), - "PLAB clipping computation may be incorrect"); - - assert(_allocated != 0 || _unused == 0, - "Inconsistency in PLAB stats: " - "_allocated: " SIZE_FORMAT ", " - "_wasted: " SIZE_FORMAT ", " - "_unused: " SIZE_FORMAT ", " - "_undo_wasted: " SIZE_FORMAT, - _allocated, _wasted, _unused, _undo_wasted); - - size_t plab_sz = compute_desired_plab_sz(); - // Take historical weighted average - _filter.sample(plab_sz); - _desired_net_plab_sz = MAX2(min_size(), (size_t)_filter.average()); - - log_sizing(plab_sz, _desired_net_plab_sz); - // Clear accumulators for next round - reset(); -} - -size_t PLABStats::compute_desired_plab_sz() { - size_t allocated = MAX2(_allocated, size_t(1)); - double wasted_frac = (double)_unused / (double)allocated; - size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct); - if (target_refills == 0) { - target_refills = 1; - } - size_t used = allocated - _wasted - _unused; - // Assumed to have 1 gc worker thread - size_t recent_plab_sz = used / target_refills; - return recent_plab_sz; -} diff --git a/src/hotspot/share/gc/shared/plab.hpp b/src/hotspot/share/gc/shared/plab.hpp index 05b38a4810a..11428bd73fa 100644 --- a/src/hotspot/share/gc/shared/plab.hpp +++ b/src/hotspot/share/gc/shared/plab.hpp @@ -26,7 +26,6 @@ #define SHARE_GC_SHARED_PLAB_HPP #include "gc/shared/collectedHeap.hpp" -#include "gc/shared/gcUtil.hpp" #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" @@ -143,17 +142,13 @@ public: // PLAB book-keeping. class PLABStats : public CHeapObj { - protected: +protected: const char* _description; // Identifying string. size_t _allocated; // Total allocated size_t _wasted; // of which wasted (internal fragmentation) size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) size_t _unused; // Unused in last buffer - size_t _default_plab_sz; - size_t _desired_net_plab_sz;// Output of filter (below), suitably trimmed and quantized - AdaptiveWeightedAverage - _filter; // Integrator with decay virtual void reset() { _allocated = 0; @@ -162,22 +157,13 @@ class PLABStats : public CHeapObj { _unused = 0; } - virtual void log_plab_allocation(); - virtual void log_sizing(size_t calculated, size_t net_desired); - - // helper for adjust_desired_plab_sz(). - virtual size_t compute_desired_plab_sz(); - - public: - PLABStats(const char* description, size_t default_per_thread_plab_size, size_t desired_net_plab_sz, unsigned wt) : +public: + PLABStats(const char* description) : _description(description), _allocated(0), _wasted(0), _undo_wasted(0), - _unused(0), - _default_plab_sz(default_per_thread_plab_size), - _desired_net_plab_sz(desired_net_plab_sz), - _filter(wt) + _unused(0) { } virtual ~PLABStats() { } @@ -196,13 +182,6 @@ class PLABStats : public CHeapObj { return PLAB::max_size(); } - // Calculates plab size for current number of gc worker threads. - size_t desired_plab_sz(uint no_of_gc_workers) const; - - // Updates the current desired PLAB size. Computes the new desired PLAB size with one gc worker thread, - // updates _desired_plab_sz and clears sensor accumulators. - void adjust_desired_plab_sz(); - inline void add_allocated(size_t v); inline void add_unused(size_t v); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp index 66313e7eb56..860e014f029 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -200,7 +200,7 @@ inline oop ShenandoahBarrierSet::oop_cmpxchg(DecoratorSet decorators, T* addr, o // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway, // because it must be the previous value. - res = load_reference_barrier(decorators, res, reinterpret_cast(NULL)); + res = load_reference_barrier(decorators, res, static_cast(nullptr)); satb_enqueue(res); return res; } @@ -211,7 +211,7 @@ inline oop ShenandoahBarrierSet::oop_xchg(DecoratorSet decorators, T* addr, oop oop previous = RawAccess<>::oop_atomic_xchg(addr, new_value); // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway, // because it must be the previous value. - previous = load_reference_barrier(decorators, previous, reinterpret_cast(NULL)); + previous = load_reference_barrier(decorators, previous, static_cast(nullptr)); satb_enqueue(previous); return previous; } diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index d077fa65555..35b36b1ad6d 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -1159,6 +1159,12 @@ JVM_VirtualThreadUnmountBegin(JNIEnv* env, jobject vthread, jboolean last_unmoun JNIEXPORT void JNICALL JVM_VirtualThreadUnmountEnd(JNIEnv* env, jobject vthread, jboolean last_unmount); +/* + * Core reflection support. + */ +JNIEXPORT jint JNICALL +JVM_GetClassFileVersion(JNIEnv *env, jclass current); + /* * This structure is used by the launcher to get the default thread * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 0cfbe0f5638..a415e5115c2 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -842,42 +842,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp index 34475cc3430..da859ab1b1b 100644 --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp @@ -552,21 +552,6 @@ TRACE_REQUEST_FUNC(StringTableStatistics) { emit_table_statistics(statistics); } -TRACE_REQUEST_FUNC(PlaceholderTableStatistics) { - TableStatistics statistics = SystemDictionary::placeholders_statistics(); - emit_table_statistics(statistics); -} - -TRACE_REQUEST_FUNC(LoaderConstraintsTableStatistics) { - TableStatistics statistics = SystemDictionary::loader_constraints_statistics(); - emit_table_statistics(statistics); -} - -TRACE_REQUEST_FUNC(ProtectionDomainCacheTableStatistics) { - TableStatistics statistics = SystemDictionary::protection_domain_cache_statistics(); - emit_table_statistics(statistics); -} - TRACE_REQUEST_FUNC(CompilerStatistics) { EventCompilerStatistics event; event.set_compileCount(CompileBroker::get_total_compile_count()); @@ -592,7 +577,8 @@ TRACE_REQUEST_FUNC(CompilerConfiguration) { TRACE_REQUEST_FUNC(CodeCacheStatistics) { // Emit stats for all available code heaps - for (int bt = 0; bt < CodeBlobType::NumTypes; ++bt) { + for (int bt_index = 0; bt_index < static_cast(CodeBlobType::NumTypes); ++bt_index) { + const CodeBlobType bt = static_cast(bt_index); if (CodeCache::heap_available(bt)) { EventCodeCacheStatistics event; event.set_codeBlobType((u1)bt); diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp index d2bfe04d2a7..3fa70d73264 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp @@ -248,11 +248,11 @@ void NarrowOopModeConstant::serialize(JfrCheckpointWriter& writer) { } void CodeBlobTypeConstant::serialize(JfrCheckpointWriter& writer) { - static const u4 nof_entries = CodeBlobType::NumTypes; + static const u4 nof_entries = static_cast(CodeBlobType::NumTypes); writer.write_count(nof_entries); for (u4 i = 0; i < nof_entries; ++i) { writer.write_key(i); - writer.write(CodeCache::get_code_heap_name(i)); + writer.write(CodeCache::get_code_heap_name(static_cast(i))); } }; diff --git a/src/hotspot/share/jfr/utilities/jfrTime.cpp b/src/hotspot/share/jfr/utilities/jfrTime.cpp index 28f06bd28bb..363550a78e4 100644 --- a/src/hotspot/share/jfr/utilities/jfrTime.cpp +++ b/src/hotspot/share/jfr/utilities/jfrTime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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,13 +24,11 @@ #include "precompiled.hpp" #include "jfr/utilities/jfrTime.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #if defined(X86) && !defined(ZERO) #include "rdtsc_x86.hpp" #endif -#include OS_HEADER_INLINE(os) - bool JfrTime::_ft_enabled = false; bool JfrTime::initialize() { diff --git a/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp b/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp index cf24340a10f..4a6ab84400a 100644 --- a/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp +++ b/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,7 @@ #include "precompiled.hpp" #include "jfr/utilities/jfrTimeConverter.hpp" #include "jfr/utilities/jfrTime.hpp" -#include "runtime/os.hpp" - -#include OS_HEADER_INLINE(os) +#include "runtime/os.inline.hpp" static double ft_counter_to_nanos_factor = .0; static double nanos_to_ft_counter_factor = .0; diff --git a/src/hotspot/share/memory/heap.cpp b/src/hotspot/share/memory/heap.cpp index d1088cb30a9..6d5947d4bb2 100644 --- a/src/hotspot/share/memory/heap.cpp +++ b/src/hotspot/share/memory/heap.cpp @@ -33,7 +33,7 @@ // Implementation of Heap -CodeHeap::CodeHeap(const char* name, const int code_blob_type) +CodeHeap::CodeHeap(const char* name, const CodeBlobType code_blob_type) : _code_blob_type(code_blob_type) { _name = name; _number_of_committed_segments = 0; diff --git a/src/hotspot/share/memory/heap.hpp b/src/hotspot/share/memory/heap.hpp index c8cc2ae8dc6..f68fa3df756 100644 --- a/src/hotspot/share/memory/heap.hpp +++ b/src/hotspot/share/memory/heap.hpp @@ -99,7 +99,7 @@ class CodeHeap : public CHeapObj { size_t _max_allocated_capacity; // Peak capacity that was allocated during lifetime of the heap const char* _name; // Name of the CodeHeap - const int _code_blob_type; // CodeBlobType it contains + const CodeBlobType _code_blob_type; // CodeBlobType it contains int _blob_count; // Number of CodeBlobs int _nmethod_count; // Number of nmethods int _adapter_count; // Number of adapters @@ -146,7 +146,7 @@ class CodeHeap : public CHeapObj { void on_code_mapping(char* base, size_t size); public: - CodeHeap(const char* name, const int code_blob_type); + CodeHeap(const char* name, const CodeBlobType code_blob_type); // Heap extents bool reserve(ReservedSpace rs, size_t committed_size, size_t segment_size); @@ -205,9 +205,9 @@ class CodeHeap : public CHeapObj { size_t unallocated_capacity() const { return max_capacity() - allocated_capacity(); } // Returns true if the CodeHeap contains CodeBlobs of the given type - bool accepts(int code_blob_type) const { return (_code_blob_type == CodeBlobType::All) || + bool accepts(CodeBlobType code_blob_type) const{ return (_code_blob_type == CodeBlobType::All) || (_code_blob_type == code_blob_type); } - int code_blob_type() const { return _code_blob_type; } + CodeBlobType code_blob_type() const { return _code_blob_type; } // Debugging / Profiling const char* name() const { return _name; } diff --git a/src/hotspot/share/oops/access.hpp b/src/hotspot/share/oops/access.hpp index 47e6bd27ea0..a2850148f67 100644 --- a/src/hotspot/share/oops/access.hpp +++ b/src/hotspot/share/oops/access.hpp @@ -294,8 +294,8 @@ public: static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, arrayOop dst_obj, size_t dst_offset_in_bytes, size_t length) { - AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast(NULL), - dst_obj, dst_offset_in_bytes, reinterpret_cast(NULL), + AccessT::arraycopy(src_obj, src_offset_in_bytes, static_cast(nullptr), + dst_obj, dst_offset_in_bytes, static_cast(nullptr), length); } @@ -303,7 +303,7 @@ public: static inline void arraycopy_to_native(arrayOop src_obj, size_t src_offset_in_bytes, T* dst, size_t length) { - AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast(NULL), + AccessT::arraycopy(src_obj, src_offset_in_bytes, static_cast(nullptr), NULL, 0, dst, length); } @@ -313,15 +313,15 @@ public: arrayOop dst_obj, size_t dst_offset_in_bytes, size_t length) { AccessT::arraycopy(NULL, 0, src, - dst_obj, dst_offset_in_bytes, reinterpret_cast(NULL), + dst_obj, dst_offset_in_bytes, static_cast(nullptr), length); } static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, arrayOop dst_obj, size_t dst_offset_in_bytes, size_t length) { - return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast(NULL), - dst_obj, dst_offset_in_bytes, reinterpret_cast(NULL), + return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, static_cast(nullptr), + dst_obj, dst_offset_in_bytes, static_cast(nullptr), length); } diff --git a/src/hotspot/share/oops/generateOopMap.cpp b/src/hotspot/share/oops/generateOopMap.cpp index 8f5dee06a43..9065b92b0cb 100644 --- a/src/hotspot/share/oops/generateOopMap.cpp +++ b/src/hotspot/share/oops/generateOopMap.cpp @@ -547,7 +547,13 @@ bool GenerateOopMap::jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int * case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: (*jmpFct)(this, bcs->dest(), data); - (*jmpFct)(this, bci + 3, data); + // Class files verified by the old verifier can have a conditional branch + // as their last bytecode, provided the conditional branch is unreachable + // during execution. Check if this instruction is the method's last bytecode + // and, if so, don't call the jmpFct. + if (bci + 3 < method()->code_size()) { + (*jmpFct)(this, bci + 3, data); + } break; case Bytecodes::_goto: diff --git a/src/hotspot/share/oops/symbol.hpp b/src/hotspot/share/oops/symbol.hpp index 474d05893e6..061a9353ff7 100644 --- a/src/hotspot/share/oops/symbol.hpp +++ b/src/hotspot/share/oops/symbol.hpp @@ -172,6 +172,16 @@ class Symbol : public MetaspaceObj { void set_permanent() NOT_CDS_RETURN; void make_permanent(); + static void maybe_increment_refcount(Symbol* s) { + if (s != NULL) { + s->increment_refcount(); + } + } + static void maybe_decrement_refcount(Symbol* s) { + if (s != NULL) { + s->decrement_refcount(); + } + } // Function char_at() returns the Symbol's selected u1 byte as a char type. // // Note that all multi-byte chars have the sign bit set on all their bytes. diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp index deed562a762..f80a6be9929 100644 --- a/src/hotspot/share/opto/addnode.cpp +++ b/src/hotspot/share/opto/addnode.cpp @@ -1082,6 +1082,85 @@ static bool can_overflow(const TypeInt* t, jint c) { (c > 0 && (java_add(t_hi, c) < t_hi))); } +// Ideal transformations for MaxINode +Node* MaxINode::Ideal(PhaseGVN* phase, bool can_reshape) { + // Force a right-spline graph + Node* l = in(1); + Node* r = in(2); + // Transform MaxI1(MaxI2(a, b), c) into MaxI1(a, MaxI2(b, c)) + // to force a right-spline graph for the rest of MaxINode::Ideal(). + if (l->Opcode() == Op_MaxI) { + assert(l != l->in(1), "dead loop in MaxINode::Ideal"); + r = phase->transform(new MaxINode(l->in(2), r)); + l = l->in(1); + set_req_X(1, l, phase); + set_req_X(2, r, phase); + return this; + } + + // Get left input & constant + Node* x = l; + jint x_off = 0; + if (x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant + x->in(2)->is_Con()) { + const Type* t = x->in(2)->bottom_type(); + if (t == Type::TOP) return NULL; // No progress + x_off = t->is_int()->get_con(); + x = x->in(1); + } + + // Scan a right-spline-tree for MAXs + Node* y = r; + jint y_off = 0; + // Check final part of MAX tree + if (y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant + y->in(2)->is_Con()) { + const Type* t = y->in(2)->bottom_type(); + if (t == Type::TOP) return NULL; // No progress + y_off = t->is_int()->get_con(); + y = y->in(1); + } + if (x->_idx > y->_idx && r->Opcode() != Op_MaxI) { + swap_edges(1, 2); + return this; + } + + const TypeInt* tx = phase->type(x)->isa_int(); + + if (r->Opcode() == Op_MaxI) { + assert(r != r->in(2), "dead loop in MaxINode::Ideal"); + y = r->in(1); + // Check final part of MAX tree + if (y->Opcode() == Op_AddI &&// Check for "y+c1" and collect constant + y->in(2)->is_Con()) { + const Type* t = y->in(2)->bottom_type(); + if (t == Type::TOP) return NULL; // No progress + y_off = t->is_int()->get_con(); + y = y->in(1); + } + + if (x->_idx > y->_idx) + return new MaxINode(r->in(1), phase->transform(new MaxINode(l, r->in(2)))); + + // Transform MAX2(x + c0, MAX2(x + c1, z)) into MAX2(x + MAX2(c0, c1), z) + // if x == y and the additions can't overflow. + if (x == y && tx != NULL && + !can_overflow(tx, x_off) && + !can_overflow(tx, y_off)) { + return new MaxINode(phase->transform(new AddINode(x, phase->intcon(MAX2(x_off, y_off)))), r->in(2)); + } + } else { + // Transform MAX2(x + c0, y + c1) into x + MAX2(c0, c1) + // if x == y and the additions can't overflow. + if (x == y && tx != NULL && + !can_overflow(tx, x_off) && + !can_overflow(tx, y_off)) { + return new AddINode(x, phase->intcon(MAX2(x_off, y_off))); + } + } + return NULL; +} + //============================================================================= //------------------------------Idealize--------------------------------------- // MINs show up in range-check loop limit calculations. Look for diff --git a/src/hotspot/share/opto/addnode.hpp b/src/hotspot/share/opto/addnode.hpp index 1e9c3a8b1df..c6a6138adb7 100644 --- a/src/hotspot/share/opto/addnode.hpp +++ b/src/hotspot/share/opto/addnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -299,6 +299,7 @@ public: virtual uint ideal_reg() const { return Op_RegI; } int max_opcode() const { return Op_MaxI; } int min_opcode() const { return Op_MinI; } + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------MinINode--------------------------------------- diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp index 79b634f8a68..3f99875a80d 100644 --- a/src/hotspot/share/opto/callGenerator.cpp +++ b/src/hotspot/share/opto/callGenerator.cpp @@ -39,6 +39,7 @@ #include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" +#include "runtime/os.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/opto/constantTable.cpp b/src/hotspot/share/opto/constantTable.cpp index c3bb5c97730..91452408c2b 100644 --- a/src/hotspot/share/opto/constantTable.cpp +++ b/src/hotspot/share/opto/constantTable.cpp @@ -36,7 +36,30 @@ bool ConstantTable::Constant::operator==(const Constant& other) { if (type() != other.type() ) return false; if (can_be_reused() != other.can_be_reused()) return false; if (is_array() || other.is_array()) { - return is_array() && other.is_array() && _v._array == other._v._array; + if (is_array() != other.is_array() || + get_array()->length() != other.get_array()->length()) { + return false; + } + for (int i = 0; i < get_array()->length(); i++) { + jvalue ele1 = get_array()->at(i); + jvalue ele2 = other.get_array()->at(i); + bool is_eq; + switch (type()) { + case T_BOOLEAN: is_eq = ele1.z == ele2.z; break; + case T_BYTE: is_eq = ele1.b == ele2.b; break; + case T_CHAR: is_eq = ele1.c == ele2.c; break; + case T_SHORT: is_eq = ele1.s == ele2.s; break; + case T_INT: is_eq = ele1.i == ele2.i; break; + case T_LONG: is_eq = ele1.j == ele2.j; break; + case T_FLOAT: is_eq = jint_cast(ele1.f) == jint_cast(ele2.f); break; + case T_DOUBLE: is_eq = jlong_cast(ele1.d) == jlong_cast(ele2.d); break; + default: ShouldNotReachHere(); is_eq = false; + } + if (!is_eq) { + return false; + } + } + return true; } // For floating point values we compare the bit pattern. switch (type()) { @@ -104,7 +127,7 @@ void ConstantTable::calculate_offsets_and_size() { // Align offset for type. int typesize = constant_size(con); assert(typesize <= 8 || con->is_array(), "sanity"); - offset = align_up(offset, MIN2(round_up_power_of_2(typesize), 8)); + offset = align_up(offset, con->alignment()); con->set_offset(offset); // set constant's offset if (con->type() == T_VOID) { @@ -127,7 +150,7 @@ bool ConstantTable::emit(CodeBuffer& cb) const { Constant con = _constants.at(i); address constant_addr = NULL; if (con.is_array()) { - constant_addr = _masm.array_constant(con.type(), con.get_array()); + constant_addr = _masm.array_constant(con.type(), con.get_array(), con.alignment()); } else { switch (con.type()) { case T_INT: constant_addr = _masm.int_constant( con.get_jint() ); break; @@ -229,12 +252,18 @@ ConstantTable::Constant ConstantTable::add(Metadata* metadata) { return con; } -ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType bt, GrowableArray* array) { - Constant con(bt, array); +ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType bt, + GrowableArray* array, int alignment) { + Constant con(bt, array, alignment); add(con); return con; } +ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType bt, + GrowableArray* array) { + return add(n, bt, array, array->length() * type2aelembytes(bt)); +} + ConstantTable::Constant ConstantTable::add(MachConstantNode* n, MachOper* oper) { jvalue value; BasicType type = oper->type()->basic_type(); diff --git a/src/hotspot/share/opto/constantTable.hpp b/src/hotspot/share/opto/constantTable.hpp index 1452a27d046..001193f6d0d 100644 --- a/src/hotspot/share/opto/constantTable.hpp +++ b/src/hotspot/share/opto/constantTable.hpp @@ -39,6 +39,7 @@ public: private: BasicType _type; bool _is_array; + int _alignment; union { jvalue _value; Metadata* _metadata; @@ -49,7 +50,7 @@ public: bool _can_be_reused; // true (default) if the value can be shared with other users. public: - Constant() : _type(T_ILLEGAL), _is_array(false), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; } + Constant() : _type(T_ILLEGAL), _is_array(false), _alignment(-1), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; } Constant(BasicType type, jvalue value, float freq = 0.0f, bool can_be_reused = true) : _type(type), _is_array(false), @@ -59,24 +60,28 @@ public: { assert(type != T_METADATA, "wrong constructor"); _v._value = value; + _alignment = type == T_VOID ? sizeof(jobject) : type2aelembytes(type); } Constant(Metadata* metadata, bool can_be_reused = true) : _type(T_METADATA), _is_array(false), + _alignment(sizeof(Metadata*)), _offset(-1), _freq(0.0f), _can_be_reused(can_be_reused) { _v._metadata = metadata; } - Constant(BasicType type, GrowableArray* array) : + Constant(BasicType type, GrowableArray* array, int alignment, bool can_be_reused = true) : _type(type), _is_array(true), + _alignment(alignment), _offset(-1), _freq(0.0f), - _can_be_reused(false) + _can_be_reused(can_be_reused) { assert(is_java_primitive(type), "not applicable for %s", type2name(type)); + assert(is_power_of_2(alignment), "invalid alignment %d", alignment); _v._array = new GrowableArray(array->length()); for (jvalue ele : *array) { _v._array->append(ele); @@ -87,6 +92,7 @@ public: BasicType type() const { return _type; } bool is_array() const { return _is_array; } + int alignment() const { return _alignment; } jint get_jint() const { return _v._value.i; } jlong get_jlong() const { return _v._value.j; } @@ -145,6 +151,7 @@ public: Constant add(MachConstantNode* n, BasicType type, jvalue value); Constant add(Metadata* metadata); Constant add(MachConstantNode* n, BasicType bt, GrowableArray* array); + Constant add(MachConstantNode* n, BasicType bt, GrowableArray* array, int alignment); Constant add(MachConstantNode* n, MachOper* oper); Constant add(MachConstantNode* n, jint i) { jvalue value; value.i = i; diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 1e8f8d7cc3e..0d10bce9a8e 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp @@ -35,6 +35,7 @@ #include "opto/machnode.hpp" #include "opto/runtime.hpp" #include "opto/chaitin.hpp" +#include "runtime/os.inline.hpp" #include "runtime/sharedRuntime.hpp" // Optimization - Graph Style diff --git a/src/hotspot/share/opto/machnode.cpp b/src/hotspot/share/opto/machnode.cpp index 9ba8b231acc..bccccc7b6e3 100644 --- a/src/hotspot/share/opto/machnode.cpp +++ b/src/hotspot/share/opto/machnode.cpp @@ -474,14 +474,15 @@ bool MachNode::rematerialize() const { } // Stretching lots of inputs - don't do it. - if (req() > 2) { + // A MachContant has the last input being the constant base + if (req() > (is_MachConstant() ? 3U : 2U)) { return false; } - if (req() == 2 && in(1) && in(1)->ideal_reg() == Op_RegFlags) { + if (req() >= 2 && in(1) && in(1)->ideal_reg() == Op_RegFlags) { // In(1) will be rematerialized, too. // Stretching lots of inputs - don't do it. - if (in(1)->req() > 2) { + if (in(1)->req() > (in(1)->is_MachConstant() ? 3U : 2U)) { return false; } } @@ -491,7 +492,7 @@ bool MachNode::rematerialize() const { uint idx = oper_input_base(); if (req() > idx) { const RegMask &rm = in_RegMask(idx); - if (rm.is_bound(ideal_reg())) { + if (rm.is_NotEmpty() && rm.is_bound(ideal_reg())) { return false; } } diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index 9ef4074f947..c5b85b4d9ce 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -41,7 +41,7 @@ #include "opto/runtime.hpp" #include "opto/type.hpp" #include "opto/vectornode.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "utilities/align.hpp" diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 0d5e74c470a..3a0fb784c31 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -4044,3 +4044,22 @@ JVM_ENTRY(void, JVM_VirtualThreadUnmountEnd(JNIEnv* env, jobject vthread, jboole fatal("Should only be called with JVMTI enabled"); #endif JVM_END + +/* + * Return the current class's class file version. The low order 16 bits of the + * returned jint contain the class's major version. The high order 16 bits + * contain the class's minor version. + */ +JVM_ENTRY(jint, JVM_GetClassFileVersion(JNIEnv* env, jclass current)) + oop mirror = JNIHandles::resolve_non_null(current); + if (java_lang_Class::is_primitive(mirror)) { + // return latest major version and minor version of 0. + return JVM_CLASSFILE_MAJOR_VERSION; + } + assert(!java_lang_Class::as_Klass(mirror)->is_array_klass(), "unexpected array class"); + + Klass* c = java_lang_Class::as_Klass(mirror); + assert(c->is_instance_klass(), "must be"); + InstanceKlass* ik = InstanceKlass::cast(c); + return (ik->minor_version() << 16) | ik->major_version(); +JVM_END diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 755bb5ae741..da029d433ae 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -1472,12 +1472,12 @@ WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o)) return features_string; WB_END -int WhiteBox::get_blob_type(const CodeBlob* code) { +CodeBlobType WhiteBox::get_blob_type(const CodeBlob* code) { guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); return CodeCache::get_code_heap(code)->code_blob_type(); } -CodeHeap* WhiteBox::get_code_heap(int blob_type) { +CodeHeap* WhiteBox::get_code_heap(CodeBlobType blob_type) { guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); return CodeCache::get_code_heap(blob_type); } @@ -1486,7 +1486,7 @@ struct CodeBlobStub { CodeBlobStub(const CodeBlob* blob) : name(os::strdup(blob->name())), size(blob->size()), - blob_type(WhiteBox::get_blob_type(blob)), + blob_type(static_cast(WhiteBox::get_blob_type(blob))), address((jlong) blob) { } ~CodeBlobStub() { os::free((void*) name); } const char* const name; @@ -1566,7 +1566,7 @@ WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jbo return result; WB_END -CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) { +CodeBlob* WhiteBox::allocate_code_blob(int size, CodeBlobType blob_type) { guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); BufferBlob* blob; int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob)); @@ -1590,7 +1590,7 @@ WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("WB_AllocateCodeBlob: size is negative: " INT32_FORMAT, size)); } - return (jlong) WhiteBox::allocate_code_blob(size, blob_type); + return (jlong) WhiteBox::allocate_code_blob(size, static_cast(blob_type)); WB_END WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr)) @@ -1605,7 +1605,7 @@ WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_t GrowableArray blobs; { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - CodeHeap* heap = WhiteBox::get_code_heap(blob_type); + CodeHeap* heap = WhiteBox::get_code_heap(static_cast(blob_type)); if (heap == NULL) { return NULL; } diff --git a/src/hotspot/share/prims/whitebox.hpp b/src/hotspot/share/prims/whitebox.hpp index 79461d5aadb..31cefdade74 100644 --- a/src/hotspot/share/prims/whitebox.hpp +++ b/src/hotspot/share/prims/whitebox.hpp @@ -46,6 +46,7 @@ public: }; class CodeBlob; +enum class CodeBlobType; class CodeHeap; class JavaThread; @@ -60,9 +61,9 @@ class WhiteBox : public AllStatic { Symbol* signature_symbol); static const char* lookup_jstring(const char* field_name, oop object); static bool lookup_bool(const char* field_name, oop object); - static int get_blob_type(const CodeBlob* code); - static CodeHeap* get_code_heap(int blob_type); - static CodeBlob* allocate_code_blob(int size, int blob_type); + static CodeBlobType get_blob_type(const CodeBlob* code); + static CodeHeap* get_code_heap(CodeBlobType blob_type); + static CodeBlob* allocate_code_blob(int size, CodeBlobType blob_type); static int array_bytes_to_length(size_t bytes); static void register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count); diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index b87d0398539..2fb4d8ccb27 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -42,6 +42,7 @@ Mutex* Patching_lock = NULL; Mutex* CompiledMethod_lock = NULL; Monitor* SystemDictionary_lock = NULL; +Mutex* InvokeMethodTable_lock = NULL; Mutex* SharedDictionary_lock = NULL; Monitor* ClassInitError_lock = NULL; Mutex* Module_lock = NULL; @@ -261,7 +262,7 @@ void mutex_init() { } def(JmethodIdCreation_lock , PaddedMutex , nosafepoint-2); // used for creating jmethodIDs. - + def(InvokeMethodTable_lock , PaddedMutex , safepoint); def(SharedDictionary_lock , PaddedMutex , safepoint); def(VMStatistic_lock , PaddedMutex , safepoint); def(SignatureHandlerLibrary_lock , PaddedMutex , safepoint); @@ -279,7 +280,6 @@ void mutex_init() { def(Terminator_lock , PaddedMonitor, safepoint, true); def(InitCompleted_lock , PaddedMonitor, nosafepoint); def(Notify_lock , PaddedMonitor, safepoint, true); - def(AdapterHandlerLibrary_lock , PaddedMutex , safepoint); def(Heap_lock , PaddedMonitor, safepoint); // Doesn't safepoint check during termination. def(JfieldIdCreation_lock , PaddedMutex , safepoint); @@ -320,7 +320,6 @@ void mutex_init() { #endif def(ContinuationRelativize_lock , PaddedMonitor, nosafepoint-3); - def(CodeHeapStateAnalytics_lock , PaddedMutex , safepoint); def(NMethodSweeperStats_lock , PaddedMutex , nosafepoint); def(ThreadsSMRDelete_lock , PaddedMonitor, nosafepoint-3); // Holds ConcurrentHashTableResize_lock @@ -355,7 +354,8 @@ void mutex_init() { defl(Threads_lock , PaddedMonitor, CompileThread_lock, true); defl(Heap_lock , PaddedMonitor, MultiArray_lock); - defl(Compile_lock , PaddedMutex , MethodCompileQueue_lock); + defl(Compile_lock , PaddedMutex , MethodCompileQueue_lock); + defl(AdapterHandlerLibrary_lock , PaddedMutex , InvokeMethodTable_lock); defl(PerfDataMemAlloc_lock , PaddedMutex , Heap_lock); defl(PerfDataManager_lock , PaddedMutex , Heap_lock); diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 6f57de9721f..e858a87d2c8 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -34,6 +34,7 @@ extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code extern Mutex* CompiledMethod_lock; // a lock used to guard a compiled method and OSR queues extern Monitor* SystemDictionary_lock; // a lock on the system dictionary +extern Mutex* InvokeMethodTable_lock; extern Mutex* SharedDictionary_lock; // a lock on the CDS shared dictionary extern Monitor* ClassInitError_lock; // a lock on the class initialization error table extern Mutex* Module_lock; // a lock on module and package related data structures diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp index fa5b1bc1d14..50ab95e1669 100644 --- a/src/hotspot/share/runtime/objectMonitor.cpp +++ b/src/hotspot/share/runtime/objectMonitor.cpp @@ -668,7 +668,7 @@ const char* ObjectMonitor::is_busy_to_string(stringStream* ss) { } else { // We report NULL instead of DEFLATER_MARKER here because is_busy() // ignores DEFLATER_MARKER values. - ss->print("owner=" INTPTR_FORMAT, NULL); + ss->print("owner=" INTPTR_FORMAT, NULL_WORD); } ss->print(", cxq=" INTPTR_FORMAT ", EntryList=" INTPTR_FORMAT, p2i(_cxq), p2i(_EntryList)); diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index bfd2fd1cb9a..97e26a9a229 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -37,9 +37,73 @@ class AgentLibrary; class frame; -// os defines the interface to operating system; this includes traditional -// OS services (time, I/O) as well as other functionality with system- -// dependent code. +// Rules for using and implementing methods declared in the "os" class +// =================================================================== +// +// The "os" class defines a number of the interfaces for porting HotSpot +// to different operating systems. For example, I/O, memory, timing, etc. +// Note that additional classes such as Semaphore, Mutex, etc., are used for +// porting specific groups of features. +// +// Structure of os*.{cpp, hpp} files +// +// - os.hpp +// +// (This file) declares the entire API of the "os" class. +// +// - os.inline.hpp +// +// To use any of the inline methods declared in the "os" class, this +// header file must be included. +// +// - src/hotspot/os//os_.hpp +// - src/hotspot/os/posix/os_posix.hpp +// +// These headers declare APIs that should be used only within the +// platform-specific source files for that particular OS. +// +// For example, os_linux.hpp declares the os::Linux class, which provides +// many methods that can be used by files under os/linux/ and os_cpu/linux_*/ +// +// os_posix.hpp can be used by platform-specific files for POSIX-like +// OSes such as aix, bsd and linux. +// +// Platform-independent source files should not include these header files +// (although sadly there are some rare exceptions ...) +// +// - os.cpp +// +// Platform-independent methods of the "os" class are defined +// in os.cpp. These are not part of the porting interface, but rather +// can be considered as convenience functions for accessing +// the porting interface. E.g., os::print_function_and_library_name(). +// +// The methods declared in os.hpp but not implemented in os.cpp are +// a part the HotSpot Porting APIs. They must be implemented in one of +// the following four files: +// +// - src/hotspot/os//os_.inline.hpp +// - src/hotspot/os_cpu/_/os__.inline.hpp +// - src/hotspot/os//os_.cpp +// - src/hotspot/os_cpu/_/os__.cpp +// +// The Porting APIs declared as "inline" in os.hpp MUST be +// implemented in one of the two .inline.hpp files, depending on +// whether the feature is specific to a particular CPU architecture +// for this OS. These two files are automatically included by +// os.inline.hpp. Platform-independent source files must not include +// these two files directly. +// +// If the full definition of an inline method is too complex to fit in a +// header file, the actual implementation can be deferred to another +// method defined in the .cpp files. +// +// The Porting APIs that are *not* declared as "inline" in os.hpp MUST +// be implemented in one of the two .cpp files above. These files +// also implement OS-specific APIs such as os::Linux, os::Posix, etc. +// +// (Note: on the POSIX-like platforms, some of the Porting APIs are implemented +// in os_posix.cpp instead). class Thread; class JavaThread; @@ -279,9 +343,9 @@ class os: AllStatic { // Interface for stack banging (predetect possible stack overflow for // exception processing) There are guard pages, and above that shadow // pages for stack overflow checking. - static bool uses_stack_guard_pages(); - static bool must_commit_stack_guard_pages(); - static void map_stack_shadow_pages(address sp); + inline static bool uses_stack_guard_pages(); + inline static bool must_commit_stack_guard_pages(); + inline static void map_stack_shadow_pages(address sp); static bool stack_shadow_pages_available(Thread *thread, const methodHandle& method, address sp); private: @@ -349,6 +413,7 @@ class os: AllStatic { const size_t size); static int vm_allocation_granularity(); + inline static size_t cds_core_region_alignment(); // Reserves virtual memory. static char* reserve_memory(size_t bytes, bool executable = false, MEMFLAGS flags = mtNone); @@ -632,6 +697,9 @@ class os: AllStatic { bool demangle = true, bool strip_arguments = false); + // Used only on PPC. + inline static void* resolve_function_descriptor(void* p); + // Find out whether the pc is in the static code for jvm.dll/libjvm.so. static bool address_is_in_vm(address addr); @@ -695,6 +763,9 @@ class os: AllStatic { static void print_date_and_time(outputStream* st, char* buf, size_t buflen); static void print_instructions(outputStream* st, address pc, int unitsize); + static void print_user_info(outputStream* st); + static void print_active_locale(outputStream* st); + // helper for output of seconds in days , hours and months static void print_dhm(outputStream* st, const char* startStr, long sec); @@ -870,25 +941,58 @@ class os: AllStatic { public: - // Platform dependent stuff -#ifndef _WINDOWS -# include "os_posix.hpp" + // File conventions + static const char* file_separator(); + static const char* line_separator(); + static const char* path_separator(); + + // Information about the protection of the page at address '0' on this os. + inline static bool zero_page_read_protected(); + + static void setup_fpu(); + static bool supports_sse(); + static juint cpu_microcode_revision(); + + static inline jlong rdtsc(); + + // Used to register dynamic code cache area with the OS + // Note: Currently only used in 64 bit Windows implementations + inline static bool register_code_area(char *low, char *high); + + // Platform-specific code for interacting with individual OSes. + // TODO: This is for compatibility only with current usage of os::Linux, etc. + // We can get rid of the following block if we rename such a class to something + // like ::LinuxUtils +#if defined(AIX) + class Aix; +#elif defined(BSD) + class Bsd; +#elif defined(LINUX) + class Linux; +#elif defined(_WINDOWS) + class win32; +#endif + + // Ditto - Posix-specific API. Ideally should be moved to something like ::PosixUtils. +#ifndef _WINDOWS + class Posix; +#endif + + // FIXME - some random stuff that was in os_windows.hpp +#ifdef _WINDOWS + // strtok_s is the Windows thread-safe equivalent of POSIX strtok_r +# define strtok_r strtok_s +# define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) +# define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO) #endif -#include OS_CPU_HEADER(os) -#include OS_HEADER(os) #ifndef OS_NATIVE_THREAD_CREATION_FAILED_MSG #define OS_NATIVE_THREAD_CREATION_FAILED_MSG "unable to create native thread: possibly out of memory or process/resource limits reached" #endif public: -#ifndef PLATFORM_PRINT_NATIVE_STACK - // No platform-specific code for printing the native stack. - static bool platform_print_native_stack(outputStream* st, const void* context, - char *buf, int buf_size) { - return false; - } -#endif + inline static bool platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size); // debugging support (mostly used by debug.cpp but also fatal error handler) static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address diff --git a/src/hotspot/share/runtime/os.inline.hpp b/src/hotspot/share/runtime/os.inline.hpp index dc591365430..3c6a4ffbaf4 100644 --- a/src/hotspot/share/runtime/os.inline.hpp +++ b/src/hotspot/share/runtime/os.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,5 +28,35 @@ #include "runtime/os.hpp" #include OS_HEADER_INLINE(os) +#include OS_CPU_HEADER_INLINE(os) + +// Below are inline functions that are rarely implemented by the platforms. +// Provide default empty implementation. + +#ifndef HAVE_PLATFORM_PRINT_NATIVE_STACK +inline bool os::platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size) { + return false; +} +#endif + +#ifndef HAVE_CDS_CORE_REGION_ALIGNMENT +inline size_t os::cds_core_region_alignment() { + return (size_t)os::vm_allocation_granularity(); +} +#endif + +#ifndef _WINDOWS +// Currently used only on Windows. +inline bool os::register_code_area(char *low, char *high) { + return true; +} +#endif + +#ifndef HAVE_FUNCTION_DESCRIPTORS +inline void* os::resolve_function_descriptor(void* p) { + return NULL; +} +#endif #endif // SHARE_RUNTIME_OS_INLINE_HPP diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index e1ba9eb9e03..e31074f99b6 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -2170,7 +2170,10 @@ JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboo ThreadsListHandle tlh; java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id); if (java_thread != NULL) { - return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0); + oop thread_obj = java_thread->threadObj(); + if (thread_obj != NULL && !thread_obj->is_a(vmClasses::BasicVirtualThread_klass())) { + return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0); + } } } return -1; diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index bffe2f37c68..1d1768536d5 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -44,7 +44,7 @@ #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/javaThread.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/safefetch.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubCodeGenerator.hpp" diff --git a/src/hotspot/share/utilities/hashtable.cpp b/src/hotspot/share/utilities/hashtable.cpp index 5e8cd7dfde1..8bf53d5fb5d 100644 --- a/src/hotspot/share/utilities/hashtable.cpp +++ b/src/hotspot/share/utilities/hashtable.cpp @@ -262,21 +262,18 @@ template class Hashtable; template class HashtableEntry; template class BasicHashtable; template class Hashtable; -template class Hashtable; template class Hashtable; template class Hashtable; template class Hashtable; template class Hashtable; template class Hashtable; template class Hashtable; -template class HashtableEntry; template class HashtableEntry; template class HashtableBucket; template class BasicHashtableEntry; template class BasicHashtableEntry; template class BasicHashtable; template class BasicHashtable; -template class BasicHashtable; template class BasicHashtable; template class BasicHashtable; template class BasicHashtable; diff --git a/src/hotspot/share/utilities/ostream.cpp b/src/hotspot/share/utilities/ostream.cpp index f16b21f2a92..c6a5967f3b9 100644 --- a/src/hotspot/share/utilities/ostream.cpp +++ b/src/hotspot/share/utilities/ostream.cpp @@ -1073,6 +1073,7 @@ bufferedStream::~bufferedStream() { #include #include #include +#include #include #elif defined(_WINDOWS) #include diff --git a/src/hotspot/share/utilities/ticks.cpp b/src/hotspot/share/utilities/ticks.cpp index b53c19d68e3..891accf57dc 100644 --- a/src/hotspot/share/utilities/ticks.cpp +++ b/src/hotspot/share/utilities/ticks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ #include "rdtsc_x86.hpp" #endif -#include OS_CPU_HEADER(os) - template inline double conversion(typename TimeSource::Type& value) { return (double)value * ((double)unit / (double)TimeSource::frequency()); diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index c92b8907998..0d027e4e48f 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -43,7 +43,7 @@ #include "runtime/frame.inline.hpp" #include "runtime/javaThread.inline.hpp" #include "runtime/init.hpp" -#include "runtime/os.hpp" +#include "runtime/os.inline.hpp" #include "runtime/osThread.hpp" #include "runtime/safefetch.hpp" #include "runtime/safepointMechanism.hpp" @@ -993,13 +993,11 @@ void VMError::report(outputStream* st, bool _verbose) { st->cr(); } -#ifndef _WIN32 STEP("printing user info") if (ExtensiveErrorReports && _verbose) { - os::Posix::print_user_info(st); + os::print_user_info(st); } -#endif STEP("printing all threads") @@ -1158,14 +1156,12 @@ void VMError::report(outputStream* st, bool _verbose) { st->cr(); } -#ifndef _WIN32 STEP("printing locale settings") if (_verbose) { - os::Posix::print_active_locale(st); + os::print_active_locale(st); st->cr(); } -#endif STEP("printing signal handlers") @@ -1349,10 +1345,10 @@ void VMError::print_vm_info(outputStream* st) { st->cr(); // STEP("printing locale settings") -#ifndef _WIN32 - os::Posix::print_active_locale(st); + + os::print_active_locale(st); st->cr(); -#endif + // STEP("printing signal handlers") diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index e6d61887a01..4bd31a0c0b6 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -4668,4 +4668,34 @@ public final class Class implements java.io.Serializable, } private native Class[] getPermittedSubclasses0(); + + /* + * Return the class's major and minor class file version packed into an int. + * The high order 16 bits contain the class's minor version. The low order + * 16 bits contain the class's major version. + * + * If the class is an array type then the class file version of its element + * type is returned. If the class is a primitive type then the latest class + * file major version is returned and zero is returned for the minor version. + */ + private int getClassFileVersion() { + Class c = isArray() ? elementType() : this; + return c.getClassFileVersion0(); + } + + private native int getClassFileVersion0(); + + /* + * Return the access flags as they were in the class's bytecode, including + * the original setting of ACC_SUPER. + * + * If the class is an array type then the access flags of the element type is + * returned. If the class is a primitive then ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC. + */ + private int getClassAccessFlagsRaw() { + Class c = isArray() ? elementType() : this; + return c.getClassAccessFlagsRaw0(); + } + + private native int getClassAccessFlagsRaw0(); } diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java index 1aaa0b55400..d10a1eece05 100644 --- a/src/java.base/share/classes/java/lang/Runtime.java +++ b/src/java.base/share/classes/java/lang/Runtime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,7 +36,6 @@ import java.util.Optional; import java.util.StringTokenizer; import jdk.internal.access.SharedSecrets; -import jdk.internal.loader.NativeLibrary; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; @@ -1075,7 +1074,7 @@ public class Runtime { m.group(VersionPattern.OPT_GROUP)); // empty '+' - if (!build.isPresent()) { + if (build.isEmpty()) { if (m.group(VersionPattern.PLUS_GROUP) != null) { if (optional.isPresent()) { if (pre.isPresent()) @@ -1087,7 +1086,7 @@ public class Runtime { + " build or optional components: '" + s + "'"); } } else { - if (optional.isPresent() && !pre.isPresent()) { + if (optional.isPresent() && pre.isEmpty()) { throw new IllegalArgumentException("optional component" + " must be preceded by a pre-release component" + " or '+': '" + s + "'"); @@ -1353,11 +1352,11 @@ public class Runtime { private int comparePre(Version obj) { Optional oPre = obj.pre(); - if (!pre.isPresent()) { + if (pre.isEmpty()) { if (oPre.isPresent()) return 1; } else { - if (!oPre.isPresent()) + if (oPre.isEmpty()) return -1; String val = pre.get(); String oVal = oPre.get(); @@ -1388,11 +1387,11 @@ public class Runtime { private int compareOptional(Version obj) { Optional oOpt = obj.optional(); - if (!optional.isPresent()) { + if (optional.isEmpty()) { if (oOpt.isPresent()) return -1; } else { - if (!oOpt.isPresent()) + if (oOpt.isEmpty()) return 1; return optional.get().compareTo(oOpt.get()); } diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 05023e84f61..0f12d2a1f44 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -67,6 +67,8 @@ import java.util.concurrent.Callable; import java.util.function.Supplier; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; + +import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.misc.Unsafe; import jdk.internal.util.StaticProperty; import jdk.internal.module.ModuleBootstrap; @@ -2554,12 +2556,20 @@ public final class System { } } - public T getCarrierThreadLocal(ThreadLocal local) { - return local.getCarrierThreadLocal(); + public T getCarrierThreadLocal(CarrierThreadLocal local) { + return ((ThreadLocal)local).getCarrierThreadLocal(); } - public void setCarrierThreadLocal(ThreadLocal local, T value) { - local.setCarrierThreadLocal(value); + public void setCarrierThreadLocal(CarrierThreadLocal local, T value) { + ((ThreadLocal)local).setCarrierThreadLocal(value); + } + + public void removeCarrierThreadLocal(CarrierThreadLocal local) { + ((ThreadLocal)local).removeCarrierThreadLocal(); + } + + public boolean isCarrierThreadLocalPresent(CarrierThreadLocal local) { + return ((ThreadLocal)local).isCarrierThreadLocalPresent(); } public Object[] extentLocalCache() { diff --git a/src/java.base/share/classes/java/lang/ThreadLocal.java b/src/java.base/share/classes/java/lang/ThreadLocal.java index 3510cd80890..7477b516345 100644 --- a/src/java.base/share/classes/java/lang/ThreadLocal.java +++ b/src/java.base/share/classes/java/lang/ThreadLocal.java @@ -29,6 +29,8 @@ import java.lang.ref.WeakReference; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; + +import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.misc.TerminatingThreadLocal; /** @@ -172,6 +174,7 @@ public class ThreadLocal { * thread-local variable. */ T getCarrierThreadLocal() { + assert this instanceof CarrierThreadLocal; return get(Thread.currentCarrierThread()); } @@ -193,14 +196,18 @@ public class ThreadLocal { } /** - * Returns {@code true} if there is a value in the current thread's copy of + * Returns {@code true} if there is a value in the current carrier thread's copy of * this thread-local variable, even if that values is {@code null}. * - * @return {@code true} if current thread has associated value in this + * @return {@code true} if current carrier thread has associated value in this * thread-local variable; {@code false} if not */ - boolean isPresent() { - Thread t = Thread.currentThread(); + boolean isCarrierThreadLocalPresent() { + assert this instanceof CarrierThreadLocal; + return isPresent(Thread.currentCarrierThread()); + } + + private boolean isPresent(Thread t) { ThreadLocalMap map = getMap(t); if (map != null && map != ThreadLocalMap.NOT_SUPPORTED) { return map.getEntry(this) != null; @@ -224,8 +231,8 @@ public class ThreadLocal { } else { createMap(t, value); } - if (this instanceof TerminatingThreadLocal) { - TerminatingThreadLocal.register((TerminatingThreadLocal) this); + if (this instanceof TerminatingThreadLocal ttl) { + TerminatingThreadLocal.register(ttl); } return value; } @@ -249,6 +256,7 @@ public class ThreadLocal { } void setCarrierThreadLocal(T value) { + assert this instanceof CarrierThreadLocal; set(Thread.currentCarrierThread(), value); } @@ -276,7 +284,16 @@ public class ThreadLocal { * @since 1.5 */ public void remove() { - ThreadLocalMap m = getMap(Thread.currentThread()); + remove(Thread.currentThread()); + } + + void removeCarrierThreadLocal() { + assert this instanceof CarrierThreadLocal; + remove(Thread.currentCarrierThread()); + } + + private void remove(Thread t) { + ThreadLocalMap m = getMap(t); if (m != null && m != ThreadLocalMap.NOT_SUPPORTED) { m.remove(this); } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index aa319c1607a..28e7b3e8dec 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -6780,7 +6780,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); loopReturnType + ")"); } - if (!pred.stream().filter(Objects::nonNull).findFirst().isPresent()) { + if (pred.stream().noneMatch(Objects::nonNull)) { throw newIllegalArgumentException("no predicate found", pred); } if (pred.stream().filter(Objects::nonNull).map(MethodHandle::type).map(MethodType::returnType). diff --git a/src/java.base/share/classes/java/lang/module/Resolver.java b/src/java.base/share/classes/java/lang/module/Resolver.java index b41e6d1c65e..3cd0254ba4e 100644 --- a/src/java.base/share/classes/java/lang/module/Resolver.java +++ b/src/java.base/share/classes/java/lang/module/Resolver.java @@ -867,7 +867,7 @@ final class Resolver { Set result = new HashSet<>(beforeModules); for (ModuleReference mref : afterModules) { String name = mref.descriptor().name(); - if (!beforeFinder.find(name).isPresent() + if (beforeFinder.find(name).isEmpty() && findInParent(name) == null) { result.add(mref); } diff --git a/src/java.base/share/classes/java/lang/reflect/Executable.java b/src/java.base/share/classes/java/lang/reflect/Executable.java index 421ecc35b97..52bdde3da11 100644 --- a/src/java.base/share/classes/java/lang/reflect/Executable.java +++ b/src/java.base/share/classes/java/lang/reflect/Executable.java @@ -25,16 +25,16 @@ package java.lang.reflect; -import java.lang.annotation.*; +import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.Objects; import java.util.StringJoiner; -import java.util.stream.Stream; import java.util.stream.Collectors; import jdk.internal.access.SharedSecrets; +import jdk.internal.vm.annotation.Stable; import sun.reflect.annotation.AnnotationParser; import sun.reflect.annotation.AnnotationSupport; import sun.reflect.annotation.TypeAnnotationParser; @@ -382,7 +382,7 @@ public abstract sealed class Executable extends AccessibleObject // Need to copy the cached array to prevent users from messing // with it. Since parameters are immutable, we can // shallow-copy. - return privateGetParameters().clone(); + return parameterData().parameters.clone(); } private Parameter[] synthesizeAllParams() { @@ -421,46 +421,40 @@ public abstract sealed class Executable extends AccessibleObject } } - private Parameter[] privateGetParameters() { - // Use tmp to avoid multiple writes to a volatile. - Parameter[] tmp = parameters; - - if (tmp == null) { - - // Otherwise, go to the JVM to get them - try { - tmp = getParameters0(); - } catch(IllegalArgumentException e) { - // Rethrow ClassFormatErrors - throw new MalformedParametersException("Invalid constant pool index"); - } - - // If we get back nothing, then synthesize parameters - if (tmp == null) { - hasRealParameterData = false; - tmp = synthesizeAllParams(); - } else { - hasRealParameterData = true; - verifyParameters(tmp); - } - - parameters = tmp; - } - - return tmp; - } boolean hasRealParameterData() { - // If this somehow gets called before parameters gets - // initialized, force it into existence. - if (parameters == null) { - privateGetParameters(); - } - return hasRealParameterData; + return parameterData().isReal; } - private transient volatile boolean hasRealParameterData; - private transient volatile Parameter[] parameters; + private ParameterData parameterData() { + ParameterData parameterData = this.parameterData; + if (parameterData != null) { + return parameterData; + } + + Parameter[] tmp; + // Go to the JVM to get them + try { + tmp = getParameters0(); + } catch (IllegalArgumentException e) { + // Rethrow ClassFormatErrors + throw new MalformedParametersException("Invalid constant pool index"); + } + + // If we get back nothing, then synthesize parameters + if (tmp == null) { + tmp = synthesizeAllParams(); + parameterData = new ParameterData(tmp, false); + } else { + verifyParameters(tmp); + parameterData = new ParameterData(tmp, true); + } + return this.parameterData = parameterData; + } + + private transient @Stable ParameterData parameterData; + + record ParameterData(@Stable Parameter[] parameters, boolean isReal) {} private native Parameter[] getParameters0(); native byte[] getTypeAnnotationBytes0(); diff --git a/src/java.base/share/classes/java/nio/file/attribute/FileTime.java b/src/java.base/share/classes/java/nio/file/attribute/FileTime.java index 2f3399bcaef..0ceb0fac0bb 100644 --- a/src/java.base/share/classes/java/nio/file/attribute/FileTime.java +++ b/src/java.base/share/classes/java/nio/file/attribute/FileTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, 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 @@ -228,6 +228,7 @@ public final class FileTime * @since 1.8 */ public Instant toInstant() { + Instant instant = this.instant; if (instant == null) { long secs = 0L; int nanos = 0; @@ -269,6 +270,8 @@ public final class FileTime instant = Instant.MAX; else instant = Instant.ofEpochSecond(secs, nanos); + + this.instant = instant; } return instant; } @@ -409,6 +412,7 @@ public final class FileTime */ @Override public String toString() { + String valueAsString = this.valueAsString; if (valueAsString == null) { long secs = 0L; int nanos = 0; @@ -469,6 +473,7 @@ public final class FileTime } sb.append('Z'); valueAsString = sb.toString(); + this.valueAsString = valueAsString; } return valueAsString; } diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java index cd8b2b6048f..21128fa980d 100644 --- a/src/java.base/share/classes/java/util/Optional.java +++ b/src/java.base/share/classes/java/util/Optional.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -212,7 +212,7 @@ public final class Optional { */ public Optional filter(Predicate predicate) { Objects.requireNonNull(predicate); - if (!isPresent()) { + if (isEmpty()) { return this; } else { return predicate.test(value) ? this : empty(); @@ -254,7 +254,7 @@ public final class Optional { */ public Optional map(Function mapper) { Objects.requireNonNull(mapper); - if (!isPresent()) { + if (isEmpty()) { return empty(); } else { return Optional.ofNullable(mapper.apply(value)); @@ -282,7 +282,7 @@ public final class Optional { */ public Optional flatMap(Function> mapper) { Objects.requireNonNull(mapper); - if (!isPresent()) { + if (isEmpty()) { return empty(); } else { @SuppressWarnings("unchecked") @@ -331,7 +331,7 @@ public final class Optional { * @since 9 */ public Stream stream() { - if (!isPresent()) { + if (isEmpty()) { return Stream.empty(); } else { return Stream.of(value); diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 99e395d2dfc..bc1aeedc7af 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -27,7 +27,6 @@ package jdk.internal.access; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.module.ModuleDescriptor; import java.lang.reflect.Executable; @@ -45,6 +44,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.RejectedExecutionException; import java.util.stream.Stream; +import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.module.ServicesCatalog; import jdk.internal.reflect.ConstantPool; import jdk.internal.vm.Continuation; @@ -456,12 +456,23 @@ public interface JavaLangAccess { /** * Returns the value of the current carrier thread's copy of a thread-local. */ - T getCarrierThreadLocal(ThreadLocal local); + T getCarrierThreadLocal(CarrierThreadLocal local); /** * Sets the value of the current carrier thread's copy of a thread-local. */ - void setCarrierThreadLocal(ThreadLocal local, T value); + void setCarrierThreadLocal(CarrierThreadLocal local, T value); + + /** + * Removes the value of the current carrier thread's copy of a thread-local. + */ + void removeCarrierThreadLocal(CarrierThreadLocal local); + + /** + * Returns {@code true} if there is a value in the current carrier thread's copy of + * thread-local, even if that values is {@code null}. + */ + boolean isCarrierThreadLocalPresent(CarrierThreadLocal local); /** * Returns the current thread's extent locals cache diff --git a/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java b/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java new file mode 100644 index 00000000000..b14ecaffa2e --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.internal.misc; + +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; + +/** + * A {@link ThreadLocal} variant which binds its value to current thread's + * carrier thread. + */ +public class CarrierThreadLocal extends ThreadLocal { + + @Override + public T get() { + return JLA.getCarrierThreadLocal(this); + } + + @Override + public void set(T value) { + JLA.setCarrierThreadLocal(this, value); + } + + @Override + public void remove() { + JLA.removeCarrierThreadLocal(this); + } + + public boolean isPresent() { + return JLA.isCarrierThreadLocalPresent(this); + } + + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); +} diff --git a/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java b/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java index 800bdd68ecc..eeb1a77e226 100644 --- a/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java +++ b/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java @@ -29,11 +29,12 @@ import java.util.Collections; import java.util.IdentityHashMap; /** - * A thread-local variable that is notified when a thread terminates and - * it has been initialized in the terminating thread (even if it was + * A per-carrier-thread-local variable that is notified when a thread terminates and + * it has been initialized in the terminating carrier thread or a virtual thread + * that had the terminating carrier thread as its carrier thread (even if it was * initialized with a null value). */ -public class TerminatingThreadLocal extends ThreadLocal { +public class TerminatingThreadLocal extends CarrierThreadLocal { @Override public void set(T value) { @@ -79,8 +80,7 @@ public class TerminatingThreadLocal extends ThreadLocal { * @param tl the ThreadLocal to register */ public static void register(TerminatingThreadLocal tl) { - if (!Thread.currentThread().isVirtual()) - REGISTRY.get().add(tl); + REGISTRY.get().add(tl); } /** @@ -89,16 +89,15 @@ public class TerminatingThreadLocal extends ThreadLocal { * @param tl the ThreadLocal to unregister */ private static void unregister(TerminatingThreadLocal tl) { - if (!Thread.currentThread().isVirtual()) - REGISTRY.get().remove(tl); + REGISTRY.get().remove(tl); } /** - * a per-thread registry of TerminatingThreadLocal(s) that have been registered - * but later not unregistered in a particular thread. + * a per-carrier-thread registry of TerminatingThreadLocal(s) that have been registered + * but later not unregistered in a particular carrier-thread. */ - public static final ThreadLocal>> REGISTRY = - new ThreadLocal<>() { + public static final CarrierThreadLocal>> REGISTRY = + new CarrierThreadLocal<>() { @Override protected Collection> initialValue() { return Collections.newSetFromMap(new IdentityHashMap<>(4)); diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java index b94aeaa0079..ddb06be3775 100644 --- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java @@ -38,7 +38,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -395,7 +394,7 @@ public final class ModuleBootstrap { if (isPatched) { patcher.patchedModules() .stream() - .filter(mn -> !cf.findModule(mn).isPresent()) + .filter(mn -> cf.findModule(mn).isEmpty()) .forEach(mn -> warnUnknownModule(PATCH_MODULE, mn)); } @@ -427,7 +426,7 @@ public final class ModuleBootstrap { if (upgradeModulePath != null && upgradeModulePath.find(name).isPresent()) fail(name + ": cannot be loaded from upgrade module path"); - if (!systemModuleFinder.find(name).isPresent()) + if (systemModuleFinder.find(name).isEmpty()) fail(name + ": cannot be loaded from application module path"); } } @@ -658,7 +657,7 @@ public final class ModuleBootstrap { // the key is $MODULE String mn = e.getKey(); Optional om = bootLayer.findModule(mn); - if (!om.isPresent()) { + if (om.isEmpty()) { warnUnknownModule(ADD_READS, mn); continue; } @@ -728,7 +727,7 @@ public final class ModuleBootstrap { // The exporting module is in the boot layer Module m; Optional om = bootLayer.findModule(mn); - if (!om.isPresent()) { + if (om.isEmpty()) { warnUnknownModule(option, mn); continue; } diff --git a/src/java.base/share/classes/sun/launcher/LauncherHelper.java b/src/java.base/share/classes/sun/launcher/LauncherHelper.java index 8c4634b89e9..22a889a3025 100644 --- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java +++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java @@ -726,7 +726,7 @@ public final class LauncherHelper { // main module is in the boot layer ModuleLayer layer = ModuleLayer.boot(); Optional om = layer.findModule(mainModule); - if (!om.isPresent()) { + if (om.isEmpty()) { // should not happen throw new InternalError("Module " + mainModule + " not in boot Layer"); } @@ -735,7 +735,7 @@ public final class LauncherHelper { // get main class if (mainClass == null) { Optional omc = m.getDescriptor().mainClass(); - if (!omc.isPresent()) { + if (omc.isEmpty()) { abort(null, "java.launcher.module.error1", mainModule); } mainClass = omc.get(); @@ -1023,7 +1023,7 @@ public final class LauncherHelper { // find the module with the FX launcher Optional om = ModuleLayer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME); - if (!om.isPresent()) { + if (om.isEmpty()) { abort(null, "java.launcher.cls.error5"); } diff --git a/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java b/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java index 08443c0e50c..ad49e4c366e 100644 --- a/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java +++ b/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java @@ -133,11 +133,11 @@ public abstract class ExtendedSocketOptions { } /** Sets the value of a socket option, for the given socket. */ - public abstract void setOption(FileDescriptor fd, SocketOption option, Object value) + public abstract void setOption(FileDescriptor fd, SocketOption option, Object value, boolean isIPv6) throws SocketException; /** Returns the value of a socket option, for the given socket. */ - public abstract Object getOption(FileDescriptor fd, SocketOption option) + public abstract Object getOption(FileDescriptor fd, SocketOption option, boolean isIPv6) throws SocketException; protected ExtendedSocketOptions(Set> options) { @@ -206,7 +206,7 @@ public abstract class ExtendedSocketOptions { } @Override - public void setOption(FileDescriptor fd, SocketOption option, Object value) + public void setOption(FileDescriptor fd, SocketOption option, Object value, boolean isIPv6) throws SocketException { throw new UnsupportedOperationException( @@ -214,7 +214,7 @@ public abstract class ExtendedSocketOptions { } @Override - public Object getOption(FileDescriptor fd, SocketOption option) + public Object getOption(FileDescriptor fd, SocketOption option, boolean isIPv6) throws SocketException { throw new UnsupportedOperationException( diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index 1983544e80a..6614627be5f 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -900,7 +900,15 @@ public class HttpClient extends NetworkClient { responses.findValue("Keep-Alive")); /* default should be larger in case of proxy */ keepAliveConnections = p.findInt("max", usingProxy?50:5); + if (keepAliveConnections < 0) { + keepAliveConnections = usingProxy?50:5; + } keepAliveTimeout = p.findInt("timeout", -1); + if (keepAliveTimeout < -1) { + // if the server specified a negative (invalid) value + // then we set to -1, which is equivalent to no value + keepAliveTimeout = -1; + } } } else if (b[7] != '0') { /* diff --git a/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java b/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java index be33a173a52..a2319d23e0e 100644 --- a/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java +++ b/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java @@ -27,8 +27,7 @@ package sun.nio.ch; import java.nio.ByteBuffer; -import jdk.internal.access.JavaLangAccess; -import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.ref.CleanerFactory; /** @@ -46,7 +45,6 @@ import jdk.internal.ref.CleanerFactory; */ class IOVecWrapper { - private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); // Miscellaneous constants private static final int BASE_OFFSET = 0; @@ -83,8 +81,8 @@ class IOVecWrapper { } } - // per thread IOVecWrapper - private static final ThreadLocal cached = new ThreadLocal<>(); + // per carrier-thread IOVecWrapper + private static final CarrierThreadLocal cached = new CarrierThreadLocal<>(); private IOVecWrapper(int size) { this.size = size; @@ -97,7 +95,7 @@ class IOVecWrapper { } static IOVecWrapper get(int size) { - IOVecWrapper wrapper = JLA.getCarrierThreadLocal(cached); + IOVecWrapper wrapper = cached.get(); if (wrapper != null && wrapper.size < size) { // not big enough; eagerly release memory wrapper.vecArray.free(); @@ -106,7 +104,7 @@ class IOVecWrapper { if (wrapper == null) { wrapper = new IOVecWrapper(size); CleanerFactory.cleaner().register(wrapper, new Deallocator(wrapper.vecArray)); - JLA.setCarrierThreadLocal(cached, wrapper); + cached.set(wrapper); } return wrapper; } diff --git a/src/java.base/share/classes/sun/nio/ch/Net.java b/src/java.base/share/classes/sun/nio/ch/Net.java index 80a9aed6c09..839f9ccde76 100644 --- a/src/java.base/share/classes/sun/nio/ch/Net.java +++ b/src/java.base/share/classes/sun/nio/ch/Net.java @@ -402,9 +402,10 @@ public class Net { // only simple values supported by this method Class type = name.type(); + boolean isIPv6 = (family == StandardProtocolFamily.INET6); if (extendedOptions.isOptionSupported(name)) { - extendedOptions.setOption(fd, name, value); + extendedOptions.setOption(fd, name, value, isIPv6); return; } @@ -451,7 +452,6 @@ public class Net { } boolean mayNeedConversion = (family == UNSPEC); - boolean isIPv6 = (family == StandardProtocolFamily.INET6); setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6); } @@ -467,7 +467,8 @@ public class Net { Class type = name.type(); if (extendedOptions.isOptionSupported(name)) { - return extendedOptions.getOption(fd, name); + boolean isIPv6 = (family == StandardProtocolFamily.INET6); + return extendedOptions.getOption(fd, name, isIPv6); } // only simple values supported by this method diff --git a/src/java.base/share/classes/sun/nio/ch/Util.java b/src/java.base/share/classes/sun/nio/ch/Util.java index 708426f4da6..3a040484638 100644 --- a/src/java.base/share/classes/sun/nio/ch/Util.java +++ b/src/java.base/share/classes/sun/nio/ch/Util.java @@ -38,14 +38,11 @@ import java.util.Collection; import java.util.Iterator; import java.util.Set; -import jdk.internal.access.JavaLangAccess; -import jdk.internal.access.SharedSecrets; import jdk.internal.misc.TerminatingThreadLocal; import jdk.internal.misc.Unsafe; import sun.security.action.GetPropertyAction; public class Util { - private static JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); // -- Caches -- @@ -55,8 +52,8 @@ public class Util { // The max size allowed for a cached temp buffer, in bytes private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize(); - // Per-thread cache of temporary direct buffers - private static ThreadLocal bufferCache = new TerminatingThreadLocal<>() { + // Per-carrier-thread cache of temporary direct buffers + private static TerminatingThreadLocal bufferCache = new TerminatingThreadLocal<>() { @Override protected BufferCache initialValue() { return new BufferCache(); @@ -230,7 +227,7 @@ public class Util { return ByteBuffer.allocateDirect(size); } - BufferCache cache = JLA.getCarrierThreadLocal(bufferCache); + BufferCache cache = bufferCache.get(); ByteBuffer buf = cache.get(size); if (buf != null) { return buf; @@ -257,7 +254,7 @@ public class Util { .alignedSlice(alignment); } - BufferCache cache = JLA.getCarrierThreadLocal(bufferCache); + BufferCache cache = bufferCache.get(); ByteBuffer buf = cache.get(size); if (buf != null) { if (buf.alignmentOffset(0, alignment) == 0) { @@ -294,7 +291,7 @@ public class Util { } assert buf != null; - BufferCache cache = JLA.getCarrierThreadLocal(bufferCache); + BufferCache cache = bufferCache.get(); if (!cache.offerFirst(buf)) { // cache is full free(buf); @@ -316,7 +313,7 @@ public class Util { } assert buf != null; - BufferCache cache = JLA.getCarrierThreadLocal(bufferCache); + BufferCache cache = bufferCache.get(); if (!cache.offerLast(buf)) { // cache is full free(buf); diff --git a/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java b/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java index ddb0607e350..9b93cce9114 100644 --- a/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java +++ b/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java @@ -25,8 +25,6 @@ package sun.nio.fs; -import jdk.internal.access.JavaLangAccess; -import jdk.internal.access.SharedSecrets; import jdk.internal.misc.TerminatingThreadLocal; import jdk.internal.misc.Unsafe; @@ -35,12 +33,12 @@ import jdk.internal.misc.Unsafe; */ class NativeBuffers { - private static JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final int TEMP_BUF_POOL_SIZE = 3; - private static ThreadLocal threadLocal = new TerminatingThreadLocal<>() { + // per-carrier-thread cache of NativeBuffer(s) + private static final TerminatingThreadLocal threadLocal = new TerminatingThreadLocal<>() { @Override protected void threadTerminated(NativeBuffer[] buffers) { // threadLocal may be initialized but with initialValue of null @@ -73,7 +71,7 @@ class NativeBuffers { */ static NativeBuffer getNativeBufferFromCache(int size) { // return from cache if possible - NativeBuffer[] buffers = JLA.getCarrierThreadLocal(threadLocal); + NativeBuffer[] buffers = threadLocal.get(); if (buffers != null) { for (int i=0; i 0) { - sign = '+'; - } else { - offset = -offset; - sign = '-'; - } - sprintf(buf, (const char *)"GMT%c%02d:%02d", - sign, (int)(offset/3600), (int)((offset%3600)/60)); - return strdup(buf); -} - #else - -char * -getGMTOffsetID() -{ - time_t offset; - char sign, buf[32]; - offset = timezone; - - if (offset == 0) { + struct tm gmt; + if (gmtime_r(&clock, &gmt) == NULL) { return strdup("GMT"); } - /* Note that the time offset direction is opposite. */ - if (offset > 0) { - sign = '-'; - } else { - offset = -offset; - sign = '+'; + if(localtm.tm_hour == gmt.tm_hour && localtm.tm_min == gmt.tm_min) { + return strdup("GMT"); } - sprintf(buf, (const char *)"GMT%c%02d:%02d", - sign, (int)(offset/3600), (int)((offset%3600)/60)); +#endif + + if (strftime(offset, 6, "%z", &localtm) != 5) { + return strdup("GMT"); + } + + sprintf(buf, (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2], + offset[3], offset[4]); return strdup(buf); } -#endif /* MACOSX */ diff --git a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java index 98584cd9a27..f567c7f3b1b 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java @@ -760,6 +760,51 @@ public interface Elements { return null; } + /** + * {@return {@code true} if the executable element can be + * determined to be a canonical constructor of a record, {@code + * false} otherwise} + * Note that in some cases there may be insufficient information + * to determine if a constructor is a canonical constructor, such + * as if the executable element is built backed by a class + * file. In such cases, {@code false} is returned. + * + * @implSpec + * The default implementation of this method unconditionally + * returns {@code false}. + * + * @param e the executable being examined + * @jls 8.10.4.1 Normal Canonical Constructors + * @since 20 + */ + default boolean isCanonicalConstructor(ExecutableElement e) { + return false; + } + + /** + * {@return {@code true} if the executable element can be + * determined to be a compact constructor of a record, {@code + * false} otherwise} + * By definition, a compact constructor is also a {@linkplain + * #isCanonicalConstructor(ExecutableElement) canonical + * constructor}. + * Note that in some cases there may be insufficient information + * to determine if a constructor is a compact constructor, such as + * if the executable element is built backed by a class file. In + * such cases, {@code false} is returned. + * + * @implSpec + * The default implementation of this method unconditionally + * returns {@code false}. + * + * @param e the executable being examined + * @jls 8.10.4.2 Compact Canonical Constructors + * @since 20 + */ + default boolean isCompactConstructor(ExecutableElement e) { + return false; + } + /** * {@return the file object for this element or {@code null} if * there is no such file object} diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java index 3ddd144be78..02d1c335747 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java @@ -1229,8 +1229,6 @@ public class MotifLookAndFeel extends BasicLookAndFeel // selected. "PopupMenu.selectedWindowInputMapBindings", new Object[] { "ESCAPE", "cancel", - "TAB", "cancel", - "shift TAB", "cancel", "DOWN", "selectNext", "KP_DOWN", "selectNext", "UP", "selectPrevious", diff --git a/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/src/java.desktop/share/classes/javax/imageio/ImageIO.java index e89877f25c3..b40b48b2af3 100644 --- a/src/java.desktop/share/classes/javax/imageio/ImageIO.java +++ b/src/java.desktop/share/classes/javax/imageio/ImageIO.java @@ -1464,6 +1464,8 @@ public final class ImageIO { BufferedImage bi; try (stream) { bi = reader.read(0, param); + } catch (RuntimeException e) { + throw new IIOException(e.toString(), e); } finally { reader.dispose(); } diff --git a/src/java.desktop/share/classes/javax/swing/JTabbedPane.java b/src/java.desktop/share/classes/javax/swing/JTabbedPane.java index 1649b26e5f5..3b73a98a0d6 100644 --- a/src/java.desktop/share/classes/javax/swing/JTabbedPane.java +++ b/src/java.desktop/share/classes/javax/swing/JTabbedPane.java @@ -1598,6 +1598,11 @@ public class JTabbedPane extends JComponent boolean selectedPage = (getSelectedIndex() == index); if (selectedPage) { + if (this.visComp != null && this.visComp.isVisible() + && !this.visComp.equals(component)) { + // previous component visibility is set to false + this.visComp.setVisible(false); + } this.visComp = component; } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java index 52c7ab078c3..a4d7a6b4eee 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java @@ -721,6 +721,11 @@ public class SynthLookAndFeel extends BasicLookAndFeel { "KP_RIGHT", "selectParent", }); + table.put("Menu.shortcutKeys", + new int[] { + SwingUtilities2.getSystemMnemonicKeyMask(), + }); + // enabled antialiasing depending on desktop settings flushUnreferenced(); SwingUtilities2.putAATextInfo(useLAFConditions(), table); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 94f06f8990f..9b0dbf6e4ea 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2940,7 +2940,7 @@ public class Attr extends JCTree.Visitor { && ((tree.constructorType != null && inferenceContext.free(tree.constructorType)) || (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) { final ResultInfo resultInfoForClassDefinition = this.resultInfo; - Env dupLocalEnv = localEnv.dup(localEnv.tree, localEnv.info.dup(localEnv.info.scope.dupUnshared())); + Env dupLocalEnv = copyEnv(localEnv); inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type), instantiatedContext -> { tree.constructorType = instantiatedContext.asInstType(tree.constructorType); @@ -4473,7 +4473,11 @@ public class Attr extends JCTree.Visitor { sym.name != names._class) { // If the qualified item is not a type and the selected item is static, report // a warning. Make allowance for the class of an array type e.g. Object[].class) - chk.warnStatic(tree, Warnings.StaticNotQualifiedByType(sym.kind.kindName(), sym.owner)); + if (!sym.owner.isAnonymous()) { + chk.warnStatic(tree, Warnings.StaticNotQualifiedByType(sym.kind.kindName(), sym.owner)); + } else { + chk.warnStatic(tree, Warnings.StaticNotQualifiedByType2(sym.kind.kindName())); + } } // If we are selecting an instance member via a `super', ... diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java index a691f44cdab..6ffc7a342c8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -727,6 +727,16 @@ public class JavacElements implements Elements { return (msym.flags() & Flags.AUTOMATIC_MODULE) != 0; } + @Override @DefinedBy(Api.LANGUAGE_MODEL) + public boolean isCompactConstructor(ExecutableElement e) { + return (((MethodSymbol)e).flags() & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0; + } + + @Override @DefinedBy(Api.LANGUAGE_MODEL) + public boolean isCanonicalConstructor(ExecutableElement e) { + return (((MethodSymbol)e).flags() & Flags.RECORD) != 0; + } + @Override @DefinedBy(Api.LANGUAGE_MODEL) public JavaFileObject getFileObjectOf(Element e) { Symbol sym = (Symbol) e; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 39f0e508854..f0a0429db86 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -2010,6 +2010,10 @@ compiler.warn.big.major.version=\ compiler.warn.static.not.qualified.by.type=\ static {0} should be qualified by type name, {1}, instead of by an expression +# 0: kind name +compiler.warn.static.not.qualified.by.type2=\ + static {0} should not be used as a member of an anonymous class + # 0: string compiler.warn.source.no.bootclasspath=\ bootstrap class path not set in conjunction with -source {0} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java index bb00f15091f..665680d0840 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java @@ -25,8 +25,6 @@ package sun.security.ec; -import java.io.IOException; -import java.math.BigInteger; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java index 200ed63634f..3cfb74c8115 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java @@ -31,19 +31,13 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivilegedAction; import java.security.Provider; import java.security.ProviderException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import sun.security.ec.ed.EdDSAAlgorithmParameters; import sun.security.ec.ed.EdDSAKeyFactory; import sun.security.ec.ed.EdDSAKeyPairGenerator; import sun.security.ec.ed.EdDSASignature; import sun.security.util.CurveDB; -import sun.security.util.KnownOIDs; import sun.security.util.NamedCurve; import static sun.security.util.SecurityConstants.PROVIDER_VER; diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java index 0042ec3e059..f1f3c88c1be 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java @@ -28,7 +28,6 @@ package sun.security.ec; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyRep; -import java.security.PublicKey; import java.security.interfaces.XECPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.NamedParameterSpec; diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java index 92b2f709c34..8a8e1bb5338 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, 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 @@ -50,11 +50,8 @@ class Request { os = rawout; do { startLine = readLine(); - if (startLine == null) { - return; - } /* skip blank lines */ - } while (startLine == null ? false : startLine.equals ("")); + } while ("".equals(startLine)); } diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 6581544de31..71b09bd6fac 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -37,21 +37,6 @@ 10 s - - true - 10 s - - - - true - 10 s - - - - true - 10 s - - true true diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 2a82e05b944..070e5592edd 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -37,21 +37,6 @@ 10 s - - true - 10 s - - - - true - 10 s - - - - true - 10 s - - true true diff --git a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java index 183e0fe66fa..5d295bcb5bf 100644 --- a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java +++ b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java @@ -108,13 +108,13 @@ class LinuxSocketOptions extends PlatformSocketOptions { } @Override - void setIpDontFragment(int fd, final boolean value) throws SocketException { - setIpDontFragment0(fd, value); + void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException { + setIpDontFragment0(fd, value, isIPv6); } @Override - boolean getIpDontFragment(int fd) throws SocketException { - return getIpDontFragment0(fd); + boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException { + return getIpDontFragment0(fd, isIPv6); } @Override @@ -130,11 +130,11 @@ class LinuxSocketOptions extends PlatformSocketOptions { private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException; - private static native void setIpDontFragment0(int fd, boolean value) throws SocketException; + private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; private static native int getTcpkeepAliveProbes0(int fd) throws SocketException; private static native int getTcpKeepAliveTime0(int fd) throws SocketException; private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; - private static native boolean getIpDontFragment0(int fd) throws SocketException; + private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; private static native void setQuickAck0(int fd, boolean on) throws SocketException; private static native boolean getQuickAck0(int fd) throws SocketException; private static native long getSoPeerCred0(int fd) throws SocketException; diff --git a/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c b/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c index af65a8b6d6d..61b59365c1f 100644 --- a/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c +++ b/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c @@ -244,34 +244,18 @@ JNIEXPORT jint JNICALL Java_jdk_net_LinuxSocketOptions_getIncomingNapiId0 return optval; } -static int socketFamily(jint fd) { - struct sockaddr_storage st; - struct sockaddr *sa = (struct sockaddr *)&st; - socklen_t sa_len = sizeof(st); - - if (getsockname(fd, sa, &sa_len) == 0) { - return sa->sa_family; - } - return -1; -} - /* * Class: jdk_net_LinuxSocketOptions * Method: setIpDontFragment0 - * Signature: (IZ)V + * Signature: (IZZ)V */ JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setIpDontFragment0 -(JNIEnv *env, jobject unused, jint fd, jboolean optval) { +(JNIEnv *env, jobject unused, jint fd, jboolean optval, jboolean isIPv6) { jint rv, optsetting; - jint family = socketFamily(fd); - if (family == -1) { - handleError(env, family, "get socket family failed"); - return; - } optsetting = optval ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; - if (family == AF_INET) { + if (!isIPv6) { rv = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &optsetting, sizeof (optsetting)); } else { rv = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &optsetting, sizeof (optsetting)); @@ -282,18 +266,13 @@ JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setIpDontFragment0 /* * Class: jdk_net_LinuxSocketOptions * Method: getIpDontFragment0 - * Signature: (I)Z; + * Signature: (IZ)Z; */ JNIEXPORT jboolean JNICALL Java_jdk_net_LinuxSocketOptions_getIpDontFragment0 -(JNIEnv *env, jobject unused, jint fd) { +(JNIEnv *env, jobject unused, jint fd, jboolean isIPv6) { jint optlevel, optname, optval, rv; - jint family = socketFamily(fd); - if (family == -1) { - handleError(env, family, "get socket family failed"); - return JNI_FALSE; - } - if (family == AF_INET) { + if (!isIPv6) { optlevel = IPPROTO_IP; optname = IP_MTU_DISCOVER; } else { diff --git a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java index 0b79e863652..d7d2c6c3deb 100644 --- a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java +++ b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java @@ -84,13 +84,13 @@ class MacOSXSocketOptions extends PlatformSocketOptions { } @Override - void setIpDontFragment(int fd, final boolean value) throws SocketException { - setIpDontFragment0(fd, value); + void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException { + setIpDontFragment0(fd, value, isIPv6); } @Override - boolean getIpDontFragment(int fd) throws SocketException { - return getIpDontFragment0(fd); + boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException { + return getIpDontFragment0(fd, isIPv6); } @Override @@ -106,11 +106,11 @@ class MacOSXSocketOptions extends PlatformSocketOptions { private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException; private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException; - private static native void setIpDontFragment0(int fd, boolean value) throws SocketException; + private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; private static native int getTcpkeepAliveProbes0(int fd) throws SocketException; private static native int getTcpKeepAliveTime0(int fd) throws SocketException; private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; - private static native boolean getIpDontFragment0(int fd) throws SocketException; + private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; private static native long getSoPeerCred0(int fd) throws SocketException; private static native boolean keepAliveOptionsSupported0(); private static native boolean ipDontFragmentSupported0(); diff --git a/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c b/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c index fdb00ac4315..bb3181d7953 100644 --- a/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c +++ b/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c @@ -178,17 +178,6 @@ JNIEXPORT jint JNICALL Java_jdk_net_MacOSXSocketOptions_getTcpKeepAliveIntvl0 return optval; } -static int socketFamily(jint fd) { - struct sockaddr_storage st; - struct sockaddr* sa = (struct sockaddr *)&st; - socklen_t sa_len = sizeof(st); - - if (getsockname(fd, sa, &sa_len) == 0) { - return sa->sa_family; - } - return -1; -} - /* * Class: jdk_net_MacOSXSocketOptions * Method: ipDontFragmentSupported0 @@ -198,22 +187,22 @@ JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_ipDontFragmentSuppor (JNIEnv *env, jobject unused) { jint rv, fd, value; fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd == -1) - return JNI_FALSE; - value = 1; - rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value)); - close(fd); - if (rv == -1) { - return JNI_FALSE; + if (fd != -1) { + value = 1; + rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value)); + close(fd); + if (rv == -1) { + return JNI_FALSE; + } } fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd == -1) - return JNI_FALSE; - value = 1; - rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value)); - close(fd); - if (rv == -1) { - return JNI_FALSE; + if (fd != -1) { + value = 1; + rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value)); + close(fd); + if (rv == -1) { + return JNI_FALSE; + } } return JNI_TRUE; } @@ -221,19 +210,14 @@ JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_ipDontFragmentSuppor /* * Class: jdk_net_MacOSXSocketOptions * Method: setIpDontFragment0 - * Signature: (IZ)V + * Signature: (IZZ)V */ JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setIpDontFragment0 -(JNIEnv *env, jobject unused, jint fd, jboolean optval) { +(JNIEnv *env, jobject unused, jint fd, jboolean optval, jboolean isIPv6) { jint rv; - jint family = socketFamily(fd); jint value = optval ? 1 : 0; - if (family == -1) { - handleError(env, family, "get socket family failed"); - return; - } - if (family == AF_INET) { + if (!isIPv6) { rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value)); } else { rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value)); @@ -244,18 +228,13 @@ JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setIpDontFragment0 /* * Class: jdk_net_MacOSXSocketOptions * Method: getIpDontFragment0 - * Signature: (I)Z; + * Signature: (IZ)Z; */ JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_getIpDontFragment0 -(JNIEnv *env, jobject unused, jint fd) { +(JNIEnv *env, jobject unused, jint fd, jboolean isIPv6) { jint optval, rv; socklen_t sz = sizeof (optval); - jint family = socketFamily(fd); - if (family == -1) { - handleError(env, family, "get socket family failed"); - return 0; - } - if (family == AF_INET) { + if (!isIPv6) { rv = getsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &optval, &sz); } else { rv = getsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &optval, &sz); diff --git a/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java b/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java index 2a7814db16a..fccac928b16 100644 --- a/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java +++ b/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java @@ -28,6 +28,7 @@ package jdk.net; import java.io.FileDescriptor; import java.net.SocketException; import java.net.SocketOption; +import java.net.StandardProtocolFamily; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; @@ -209,6 +210,9 @@ public final class ExtendedSocketOptions { * sizes to the {@link java.net.NetworkInterface#getMTU() local MTU}. Depending * on the implementation and the network interface, packets larger than the MTU * may be sent or dropped silently or dropped with an exception thrown. + * For {@link StandardProtocolFamily#INET6 IPv6} sockets it is + * system dependent whether the option also applies to datagrams + * sent to IPv4 addresses. * * @apiNote * For IPv4 this option sets the DF (Do not Fragment) flag in the IP packet @@ -263,10 +267,9 @@ public final class ExtendedSocketOptions { new sun.net.ext.ExtendedSocketOptions(extendedOptions) { @Override - @SuppressWarnings("removal") public void setOption(FileDescriptor fd, SocketOption option, - Object value) + Object value, boolean isIPv6) throws SocketException { if (fd == null || !fd.valid()) @@ -277,7 +280,7 @@ public final class ExtendedSocketOptions { } else if (option == TCP_KEEPCOUNT) { setTcpkeepAliveProbes(fd, (Integer) value); } else if (option == IP_DONTFRAGMENT) { - setIpDontFragment(fd, (Boolean) value); + setIpDontFragment(fd, (Boolean) value, isIPv6); } else if (option == TCP_KEEPIDLE) { setTcpKeepAliveTime(fd, (Integer) value); } else if (option == TCP_KEEPINTERVAL) { @@ -295,9 +298,8 @@ public final class ExtendedSocketOptions { } @Override - @SuppressWarnings("removal") public Object getOption(FileDescriptor fd, - SocketOption option) + SocketOption option, boolean isIPv6) throws SocketException { if (fd == null || !fd.valid()) @@ -308,7 +310,7 @@ public final class ExtendedSocketOptions { } else if (option == TCP_KEEPCOUNT) { return getTcpkeepAliveProbes(fd); } else if (option == IP_DONTFRAGMENT) { - return getIpDontFragment(fd); + return getIpDontFragment(fd, isIPv6); } else if (option == TCP_KEEPIDLE) { return getTcpKeepAliveTime(fd); } else if (option == TCP_KEEPINTERVAL) { @@ -352,9 +354,9 @@ public final class ExtendedSocketOptions { platformSocketOptions.setTcpKeepAliveTime(fdAccess.get(fd), value); } - private static void setIpDontFragment(FileDescriptor fd, boolean value) + private static void setIpDontFragment(FileDescriptor fd, boolean value, boolean isIPv6) throws SocketException { - platformSocketOptions.setIpDontFragment(fdAccess.get(fd), value); + platformSocketOptions.setIpDontFragment(fdAccess.get(fd), value, isIPv6); } private static void setTcpKeepAliveIntvl(FileDescriptor fd, int value) @@ -366,8 +368,8 @@ public final class ExtendedSocketOptions { return platformSocketOptions.getTcpkeepAliveProbes(fdAccess.get(fd)); } - private static boolean getIpDontFragment(FileDescriptor fd) throws SocketException { - return platformSocketOptions.getIpDontFragment(fdAccess.get(fd)); + private static boolean getIpDontFragment(FileDescriptor fd, boolean isIPv6) throws SocketException { + return platformSocketOptions.getIpDontFragment(fdAccess.get(fd), isIPv6); } private static int getTcpKeepAliveTime(FileDescriptor fd) throws SocketException { @@ -462,11 +464,11 @@ public final class ExtendedSocketOptions { throw new UnsupportedOperationException("unsupported TCP_KEEPINTVL option"); } - void setIpDontFragment(int fd, final boolean value) throws SocketException { + void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException { throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option"); } - boolean getIpDontFragment(int fd) throws SocketException { + boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException { throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option"); } diff --git a/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java b/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java index 75c284ea574..b1f34515e3e 100644 --- a/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java +++ b/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java @@ -42,17 +42,17 @@ class WindowsSocketOptions extends PlatformSocketOptions { } @Override - void setIpDontFragment(int fd, final boolean value) throws SocketException { - setIpDontFragment0(fd, value); + void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException { + setIpDontFragment0(fd, value, isIPv6); } @Override - boolean getIpDontFragment(int fd) throws SocketException { - return getIpDontFragment0(fd); + boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException { + return getIpDontFragment0(fd, isIPv6); } - private static native void setIpDontFragment0(int fd, boolean value) throws SocketException; - private static native boolean getIpDontFragment0(int fd) throws SocketException; + private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException; + private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException; static { if (System.getSecurityManager() == null) { diff --git a/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c b/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c index 298bc99f95b..f0a2c9f2572 100644 --- a/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c +++ b/src/jdk.net/windows/native/libextnet/WindowsSocketOptions.c @@ -43,32 +43,16 @@ static void handleError(JNIEnv *env, jint rv, const char *errmsg) { } } -static int socketFamily(jint fd) { - WSAPROTOCOL_INFO info; - socklen_t sa_len = sizeof(info); - - if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL_INFO, (char *)&info, &sa_len) == 0) { - return info.iAddressFamily; - } - return -1; -} - /* * Class: jdk_net_WindowsSocketOptions * Method: setIpDontFragment0 - * Signature: (IZ)V + * Signature: (IZZ)V */ JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0 -(JNIEnv *env, jobject unused, jint fd, jboolean optval) { +(JNIEnv *env, jobject unused, jint fd, jboolean optval, jboolean isIPv6) { int rv, opt; - jint family = socketFamily(fd); - if (family == -1) { - handleError(env, family, "get socket family failed"); - return; - } - - if (family == AF_INET) { + if (!isIPv6) { opt = optval ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; rv = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&opt, sizeof(int)); if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) { @@ -81,7 +65,7 @@ JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0 if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) { /* IPV6_MTU_DISCOVER not supported on W 2016 and older, can use old option */ opt = optval; - rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAGMENT, (char *)&opt, sizeof(int)); + rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, (char *)&opt, sizeof(int)); } } handleError(env, rv, "set option IP_DONTFRAGMENT failed"); @@ -90,18 +74,13 @@ JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0 /* * Class: jdk_net_WindowsSocketOptions * Method: getIpDontFragment0 - * Signature: (I)Z; + * Signature: (IZ)Z; */ JNIEXPORT jboolean JNICALL Java_jdk_net_WindowsSocketOptions_getIpDontFragment0 -(JNIEnv *env, jobject unused, jint fd) { +(JNIEnv *env, jobject unused, jint fd, jboolean isIPv6) { int optval, rv, sz = sizeof(optval); - jint family = socketFamily(fd); - if (family == -1) { - handleError(env, family, "get socket family failed"); - return JNI_FALSE; - } - if (family == AF_INET) { + if (!isIPv6) { rv = getsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&optval, &sz); if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) { sz = sizeof(optval); @@ -115,7 +94,7 @@ JNIEXPORT jboolean JNICALL Java_jdk_net_WindowsSocketOptions_getIpDontFragment0 rv = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (char *)&optval, &sz); if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) { sz = sizeof(optval); - rv = getsockopt(fd, IPPROTO_IP, IP_DONTFRAGMENT, (char *)&optval, &sz); + rv = getsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, (char *)&optval, &sz); handleError(env, rv, "get option IP_DONTFRAGMENT failed"); return optval; } diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/FolderNode.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/FolderNode.java index 4fb3838864b..6e92f8ef8bc 100644 --- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/FolderNode.java +++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/FolderNode.java @@ -59,6 +59,10 @@ public class FolderNode extends AbstractNode { folder.getChangedEvent().addListener(this); } + public Folder getFolder() { + return folder; + } + @Override protected Node[] createNodes(FolderElement e) { if (e instanceof InputGraph) { @@ -137,6 +141,11 @@ public class FolderNode extends AbstractNode { } } + public boolean isRootNode() { + Folder folder = getFolder(); + return (folder != null && folder instanceof GraphDocument); + } + @Override public Image getOpenedIcon(int i) { return getIcon(i); @@ -149,4 +158,8 @@ public class FolderNode extends AbstractNode { public static GraphNode getGraphNode(InputGraph graph) { return graphNode.get(graph); } + + public Folder getFolder() { + return children.getFolder(); + } } diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java index 5d8c6b02c32..104b662ecf6 100644 --- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java +++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java @@ -37,8 +37,7 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; +import javax.swing.*; import javax.swing.border.Border; import org.openide.ErrorManager; import org.openide.actions.GarbageCollectAction; @@ -71,6 +70,9 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM private FolderNode root; private Server server; private Server binaryServer; + private SaveAllAction saveAllAction; + private RemoveAllAction removeAllAction; + private OutlineTopComponent() { initComponents(); @@ -94,25 +96,37 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM } private void initToolbar() { - Toolbar toolbar = new Toolbar(); Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N toolbar.setBorder(b); this.add(toolbar, BorderLayout.NORTH); toolbar.add(ImportAction.get(ImportAction.class)); - toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup())); - toolbar.add(SaveAllAction.get(SaveAllAction.class)); + + saveAllAction = SaveAllAction.get(SaveAllAction.class); + saveAllAction.setEnabled(false); + toolbar.add(saveAllAction); toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup())); - toolbar.add(RemoveAllAction.get(RemoveAllAction.class)); + + removeAllAction = RemoveAllAction.get(RemoveAllAction.class); + removeAllAction.setEnabled(false); + toolbar.add(removeAllAction); toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter()); for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) { tb.setVisible(false); } + + document.getChangedEvent().addListener(g -> documentChanged()); + } + + private void documentChanged() { + boolean enableButton = !document.getElements().isEmpty(); + saveAllAction.setEnabled(enableButton); + removeAllAction.setEnabled(enableButton); } private void initReceivers() { diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java index 9ee4595c927..e1b3a62f0eb 100644 --- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java +++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, 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 @@ package com.sun.hotspot.igv.coordinator.actions; +import com.sun.hotspot.igv.coordinator.FolderNode; import javax.swing.Action; import org.openide.nodes.Node; import org.openide.util.HelpCtx; @@ -72,6 +73,14 @@ public final class RemoveAction extends NodeAction { @Override protected boolean enable(Node[] nodes) { - return nodes.length > 0; + if (nodes.length > 0) { + for (Node n : nodes) { + if ((n instanceof FolderNode) && ((FolderNode) n).isRootNode()) { + return false; + } + } + return true; + } + return false; } } diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java index a1789093122..a1abf62d3a5 100644 --- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java +++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, 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,9 @@ package com.sun.hotspot.igv.coordinator.actions; +import com.sun.hotspot.igv.coordinator.FolderNode; +import com.sun.hotspot.igv.coordinator.OutlineTopComponent; +import com.sun.hotspot.igv.data.Folder; import com.sun.hotspot.igv.data.GraphDocument; import com.sun.hotspot.igv.data.Group; import com.sun.hotspot.igv.data.serialization.Printer; @@ -49,13 +52,18 @@ public final class SaveAsAction extends NodeAction { @Override protected void performAction(Node[] activatedNodes) { - + final OutlineTopComponent component = OutlineTopComponent.findInstance(); GraphDocument doc = new GraphDocument(); - for (Node n : activatedNodes) { - Group group = n.getLookup().lookup(Group.class); - doc.addElement(group); + for (Node node : activatedNodes) { + if (node instanceof FolderNode) { + FolderNode folderNode = (FolderNode) node; + Folder folder = folderNode.getFolder(); + if (folder instanceof Group) { + Group group = (Group) folder; + doc.addElement(group); + } + } } - save(doc); } @@ -115,12 +123,14 @@ public final class SaveAsAction extends NodeAction { @Override protected boolean enable(Node[] nodes) { - - int cnt = 0; - for (Node n : nodes) { - cnt += n.getLookup().lookupAll(Group.class).size(); + if (nodes.length > 0) { + for (Node n : nodes) { + if (!(n instanceof FolderNode) || ((FolderNode) n).isRootNode()) { + return false; + } + } + return true; } - - return cnt > 0; + return false; } } diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml index 52570b3a105..78ebc84b534 100644 --- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml +++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml @@ -158,6 +158,12 @@ + + + + + + diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index 71ffa850913..f3f8259f94d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -103,7 +103,6 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh private PredSuccAction predSuccAction; private ShowEmptyBlocksAction showEmptyBlocksAction; private SelectionModeAction selectionModeAction; - private PanModeAction panModeAction; private boolean notFirstTime; private JComponent satelliteComponent; private JPanel centerPanel; @@ -320,19 +319,9 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh toolBar.add(redoAction); toolBar.addSeparator(); - ButtonGroup interactionButtons = new ButtonGroup(); - - panModeAction = new PanModeAction(); - panModeAction.setSelected(true); - button = new JToggleButton(panModeAction); - button.setSelected(true); - interactionButtons.add(button); - toolBar.add(button); - panModeAction.addPropertyChangeListener(this); - selectionModeAction = new SelectionModeAction(); button = new JToggleButton(selectionModeAction); - interactionButtons.add(button); + button.setSelected(false); toolBar.add(button); selectionModeAction.addPropertyChangeListener(this); @@ -579,11 +568,12 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh } else if (evt.getSource() == this.hideDuplicatesAction) { boolean b = (Boolean) hideDuplicatesAction.getValue(HideDuplicatesAction.STATE); this.getModel().setHideDuplicates(b); - } else if (evt.getSource() == this.selectionModeAction || evt.getSource() == this.panModeAction) { - if (panModeAction.isSelected()) { - scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING); - } else if (selectionModeAction.isSelected()) { + } else if (evt.getSource() == this.selectionModeAction) { + boolean b = (Boolean) selectionModeAction.getValue(SelectionModeAction.STATE); + if (b) { scene.setInteractionMode(DiagramViewer.InteractionMode.SELECTION); + } else { + scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING); } } else { assert false : "Unknown event source"; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/PanModeAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/PanModeAction.java deleted file mode 100644 index 1c615e40f41..00000000000 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/PanModeAction.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011, 2015, 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 com.sun.hotspot.igv.view.actions; - -import java.awt.event.ActionEvent; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.ImageIcon; -import org.openide.util.ImageUtilities; - -public class PanModeAction extends AbstractAction { - - private boolean state; - - public PanModeAction() { - putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource()))); - putValue(SELECTED_KEY, false); - putValue(Action.SHORT_DESCRIPTION, "Panning mode"); - } - - public boolean isSelected() { - return (Boolean)getValue(SELECTED_KEY); - } - - public void setSelected(boolean b) { - if (isSelected() != b) { - this.putValue(SELECTED_KEY, b); - } - } - - protected String iconResource() { - return "com/sun/hotspot/igv/view/images/pan_mode.png"; - } - - @Override - public void actionPerformed(ActionEvent e) { - } -} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/SelectionModeAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/SelectionModeAction.java index 168d2b8c4c3..1fdb218b3a1 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/SelectionModeAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/SelectionModeAction.java @@ -31,27 +31,28 @@ import org.openide.util.ImageUtilities; public class SelectionModeAction extends AbstractAction { + private boolean state; + + public static final String STATE = "state"; + public SelectionModeAction() { putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource()))); - putValue(SELECTED_KEY, false); putValue(Action.SHORT_DESCRIPTION, "Selection mode"); + state = false; + putValue(STATE, false); } - public boolean isSelected() { - return (Boolean)getValue(SELECTED_KEY); + @Override + public void actionPerformed(ActionEvent ev) { + setState(!state); } - public void setSelected(boolean b) { - if (isSelected() != b) { - this.putValue(SELECTED_KEY, b); - } + public void setState(boolean b) { + this.putValue(STATE, b); + this.state = b; } protected String iconResource() { return "com/sun/hotspot/igv/view/images/selection_mode.png"; } - - @Override - public void actionPerformed(ActionEvent e) { - } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/pan_mode.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/pan_mode.png deleted file mode 100644 index e2125ce36cf..00000000000 Binary files a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/pan_mode.png and /dev/null differ diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp index 7cca5e850b0..151e51ecb0a 100644 --- a/test/hotspot/gtest/runtime/test_os.cpp +++ b/test/hotspot/gtest/runtime/test_os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,9 @@ #include "unittest.hpp" #include "runtime/frame.inline.hpp" #include "runtime/threads.hpp" +#ifdef _WIN32 +#include "os_windows.hpp" +#endif static size_t small_page_size() { return os::vm_page_size(); diff --git a/test/hotspot/gtest/runtime/test_os_linux.cpp b/test/hotspot/gtest/runtime/test_os_linux.cpp index 939e3672f52..b58f3576031 100644 --- a/test/hotspot/gtest/runtime/test_os_linux.cpp +++ b/test/hotspot/gtest/runtime/test_os_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "runtime/os.hpp" #include "utilities/align.hpp" #include "concurrentTestRunner.inline.hpp" +#include "os_linux.hpp" #include "unittest.hpp" namespace { diff --git a/test/hotspot/gtest/utilities/test_resourceHash.cpp b/test/hotspot/gtest/utilities/test_resourceHash.cpp index bc0c7f85d12..22c30fdb1e5 100644 --- a/test/hotspot/gtest/utilities/test_resourceHash.cpp +++ b/test/hotspot/gtest/utilities/test_resourceHash.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "classfile/symbolTable.hpp" #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "unittest.hpp" @@ -287,3 +288,161 @@ TEST_VM_F(GenericResourceHashtableTest, bad_hash_no_rm) { TEST_VM_F(GenericResourceHashtableTest, identity_hash_no_rm) { Runner, 1, ResourceObj::C_HEAP>::test(512); } + +// Simple ResourceHashtable whose key is a Symbol* and value is an int +// This test is to show that you need to manipulate the refcount of the Symbol to store +// in the table. +class SimpleResourceHashtableDeleteTest : public ::testing::Test { + public: + ResourceHashtable _simple_test_table; + + class SimpleDeleter : public StackObj { + public: + bool do_entry(Symbol*& key, int value) { + // We need to decrement the refcount for the key in the delete function. + // Since we incremented the key, in this case, we should decrement it. + key->decrement_refcount(); + return true; + } + }; +}; + +TEST_VM_F(SimpleResourceHashtableDeleteTest, simple_remove) { + TempNewSymbol s = SymbolTable::new_symbol("abcdefg_simple"); + int s_orig_count = s->refcount(); + // Need to increment a Symbol* when you keep it in a table. + s->increment_refcount(); + _simple_test_table.put(s, 55); + ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table"; + + // Deleting this value from a hashtable + _simple_test_table.remove(s); + // Now decrement the refcount for s since it's no longer in the table. + s->decrement_refcount(); + ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start"; +} + +TEST_VM_F(SimpleResourceHashtableDeleteTest, simple_delete) { + TempNewSymbol s = SymbolTable::new_symbol("abcdefg_simple"); + int s_orig_count = s->refcount(); + // Need to increment a Symbol* when you keep it in a table. + s->increment_refcount(); + _simple_test_table.put(s, 66); + ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table"; + + // Use unlink to remove the matching (or all) values from the table. + SimpleDeleter deleter; + _simple_test_table.unlink(&deleter); + ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start"; +} + +// More complicated ResourceHashtable with Symbol* as the key. Since the *same* Symbol is part +// of the value, it's not necessary to maniuplate the refcount of the key, but you must in the value. +class ResourceHashtableDeleteTest : public ::testing::Test { + public: + class TestValue : public CHeapObj { + Symbol* _s; + public: + // Never have ctors and dtors fix refcounts without copy ctors and assignment operators! + // Unless it's declared and used as a CHeapObj with + // NONCOPYABLE(TestValue) + TestValue(Symbol* name) : _s(name) { _s->increment_refcount(); } + TestValue(const TestValue& tv) { _s = tv.s(); _s->increment_refcount(); } + + // Refcounting with assignment operators is tricky. See TempNewSymbol for more information. + // (1) A copy (from) of the argument is created to be passed by value to operator=. This increments + // the refcount of the symbol. + // (2) Exchange the values this->_s and from._s as a trivial pointer exchange. No reference count + // manipulation occurs. this->_s is the desired new value, with its refcount incremented appropriately + // (by the copy that created from). + // (3) The operation completes and from goes out of scope, calling its destructor. This decrements the + // refcount for from._s, which is the _old_ value of this->_s. + TestValue& operator=(TestValue tv) { swap(_s, tv._s); return *this; } + + ~TestValue() { _s->decrement_refcount(); } + Symbol* s() const { return _s; } + }; + + // ResourceHashtable whose value is a *copy* of TestValue. + ResourceHashtable _test_table; + + class Deleter : public StackObj { + public: + bool do_entry(Symbol*& key, TestValue& value) { + // Since we didn't increment the key, we shouldn't decrement it. + // Calling delete on the hashtable Node which contains value will + // decrement the refcount. That's actually best since the whole + // entry will be gone at once. + return true; + } + }; + + // ResourceHashtable whose value is a pointer to TestValue. + ResourceHashtable _ptr_test_table; + + class PtrDeleter : public StackObj { + public: + bool do_entry(Symbol*& key, TestValue*& value) { + // If the hashtable value is a pointer, need to delete it from here. + // This will also potentially make the refcount of the Key = 0, but the + // next thing that happens is that the hashtable node is deleted so this is ok. + delete value; + return true; + } + }; +}; + + +TEST_VM_F(ResourceHashtableDeleteTest, value_remove) { + TempNewSymbol s = SymbolTable::new_symbol("abcdefg"); + int s_orig_count = s->refcount(); + { + TestValue tv(s); + // Since TestValue contains the pointer to the key, it will handle the + // refcounting. + _test_table.put(s, tv); + ASSERT_EQ(s->refcount(), s_orig_count + 2) << "refcount incremented by copy"; + } + ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented in table"; + + // Deleting this value from a hashtable calls the destructor! + _test_table.remove(s); + // Removal should make the refcount be the original refcount. + ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started"; +} + +TEST_VM_F(ResourceHashtableDeleteTest, value_delete) { + TempNewSymbol d = SymbolTable::new_symbol("defghijklmnop"); + int d_orig_count = d->refcount(); + { + TestValue tv(d); + // Same as above, but the do_entry does nothing because the value is deleted when the + // hashtable node is deleted. + _test_table.put(d, tv); + ASSERT_EQ(d->refcount(), d_orig_count + 2) << "refcount incremented by copy"; + } + ASSERT_EQ(d->refcount(), d_orig_count + 1) << "refcount incremented in table"; + Deleter deleter; + _test_table.unlink(&deleter); + ASSERT_EQ(d->refcount(), d_orig_count) << "refcount should be as we started"; +} + +TEST_VM_F(ResourceHashtableDeleteTest, check_delete_ptr) { + TempNewSymbol s = SymbolTable::new_symbol("abcdefg_ptr"); + int s_orig_count = s->refcount(); + { + TestValue* tv = new TestValue(s); + // Again since TestValue contains the pointer to the key Symbol, it will + // handle the refcounting. + _ptr_test_table.put(s, tv); + ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented by allocation"; + } + ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented in table"; + + // Deleting this pointer value from a hashtable must call the destructor in the + // do_entry function. + PtrDeleter deleter; + _ptr_test_table.unlink(&deleter); + // Removal should make the refcount be the original refcount. + ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started"; +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/MaxMinINodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/MaxMinINodeIdealizationTests.java new file mode 100644 index 00000000000..691c41c6a72 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/MaxMinINodeIdealizationTests.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022, Arm 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. + */ +package compiler.c2.irTests; + +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8290248 + * @summary Test that Ideal transformations of MaxINode and MinINode are + * being performed as expected. + * @library /test/lib / + * @run driver compiler.c2.irTests.MaxMinINodeIdealizationTests + */ + +public class MaxMinINodeIdealizationTests { + public static void main(String[] args) { + TestFramework.run(); + } + + @Run(test = {"testMax1", "testMax2", "testMax3", "testMin1", "testMin2", "testMin3"}) + public void runMethod() { + int a = RunInfo.getRandom().nextInt(); + int min = Integer.MIN_VALUE; + int max = Integer.MAX_VALUE; + + assertResult(a); + assertResult(0); + assertResult(min); + assertResult(max); + } + + @DontCompile + public void assertResult(int a) { + Asserts.assertEQ(Math.max(((a >> 1) + 100), Math.max(((a >> 1) + 150), 200)), testMax1(a)); + Asserts.assertEQ(Math.max(((a >> 1) + 10), ((a >> 1) + 11)) , testMax2(a)); + Asserts.assertEQ(Math.max(a, a) , testMax3(a)); + + Asserts.assertEQ(Math.min(((a >> 1) + 100), Math.min(((a >> 1) + 150), 200)), testMin1(a)); + Asserts.assertEQ(Math.min(((a >> 1) + 10), ((a >> 1) + 11)) , testMin2(a)); + Asserts.assertEQ(Math.min(a, a) , testMin3(a)); + } + + // The transformations in test*1 and test*2 can happen only if the compiler has enough information + // to determine that the two addition operations can not overflow. + + // Transform max(x + c0, max(y + c1, z)) to max(add(x, c2), z) if x == y, where c2 = MAX2(c0, c1). + // c0,c1,c2 are constants. x,y,z can be any valid c2 nodes. In this example, x and y are + // RShiftI nodes and z is a ConI. + @Test + @IR(counts = {IRNode.Max_I, "1", + IRNode.ADD , "1", + }) + public int testMax1(int i) { + return Math.max(((i >> 1) + 100), Math.max(((i >> 1) + 150), 200)); + } + + // Similarly, transform min(x + c0, min(y + c1, z)) to min(add(x, c2), z) if x == y, where c2 = MIN2(c0, c1). + @Test + @IR(counts = {IRNode.Min_I, "1", + IRNode.ADD , "1", + }) + public int testMin1(int i) { + return Math.min(((i >> 1) + 100), Math.min(((i >> 1) + 150), 200)); + } + + // Transform max(x + c0, y + c1) to add(x, c2) if x == y, where c2 = MAX2(c0, c1). + // c0,c1,c2 are constants. x and y can be any valid c2 nodes. If they are equal, this + // transformation would take place. In this example, x and y are same RShiftI nodes. + @Test + @IR(failOn = {IRNode.Max_I}) + @IR(counts = {IRNode.ADD, "1"}) + public int testMax2(int i) { + return Math.max((i >> 1) + 10, (i >> 1) + 11); + } + + // Similarly, transform min(x + c0, y + c1) to add(x, c2) if x == y, where c2 = MIN2(c0, c1). + @Test + @IR(failOn = {IRNode.Min_I}) + @IR(counts = {IRNode.ADD, "1"}) + public int testMin2(int i) { + return Math.min((i >> 1) + 10, (i >> 1) + 11); + } + + // Return the same node without generating a MaxINode/MinINode when a node is compared with itself. + // In this test, an integer is being compared with itself but it can be any valid c2 node. + @Test + @IR(failOn = {IRNode.Max_I}) + public int testMax3(int i) { + return Math.max(i, i); + } + + @Test + @IR(failOn = {IRNode.Min_I}) + public int testMin3(int i) { + return Math.min(i, i); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 16775e8bde9..cbcbb7ecd21 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -211,6 +211,8 @@ public class IRNode { public static final String VECTOR_BLEND = START + "VectorBlend" + MID + END; public static final String REVERSE_BYTES_V = START + "ReverseBytesV" + MID + END; + public static final String Min_I = START + "MinI" + MID + END; + public static final String Max_I = START + "MaxI" + MID + END; public static final String Min_V = START + "MinV" + MID + END; public static final String Max_V = START + "MaxV" + MID + END; diff --git a/test/hotspot/jtreg/runtime/ClassFile/ClassAccessFlagsRawTest.java b/test/hotspot/jtreg/runtime/ClassFile/ClassAccessFlagsRawTest.java new file mode 100644 index 00000000000..687bdf2ef57 --- /dev/null +++ b/test/hotspot/jtreg/runtime/ClassFile/ClassAccessFlagsRawTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, 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 8291360 + * @summary Test getting a class's raw access flags using java.lang.Class API + * @modules java.base/java.lang:open + * @compile classAccessFlagsRaw.jcod + * @run main/othervm ClassAccessFlagsRawTest + */ + +import java.lang.reflect.*; + +public class ClassAccessFlagsRawTest { + + static Method m; + + public static void testIt(String className, int expectedResult) throws Exception { + Class testClass = Class.forName(className); + int flags = (int)m.invoke(testClass); + if (flags != expectedResult) { + throw new RuntimeException( + "expected 0x" + Integer.toHexString(expectedResult) + ", got 0x" + Integer.toHexString(flags) + " for class " + className); + } + } + + public static void main(String argv[]) throws Throwable { + Class cl = java.lang.Class.class; + m = cl.getDeclaredMethod("getClassAccessFlagsRaw", new Class[0]); + m.setAccessible(true); + + testIt("SUPERset", 0x21); // ACC_SUPER 0x20 + ACC_PUBLIC 0x1 + testIt("SUPERnotset", Modifier.PUBLIC); + + // test primitive array. should return ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC. + int flags = (int)m.invoke((new int[3]).getClass()); + if (flags != (Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC)) { + throw new RuntimeException( + "expected 0x411, got 0x" + Integer.toHexString(flags) + " for primitive array"); + } + + // test object array. should return flags of component. + flags = (int)m.invoke((new SUPERnotset[2]).getClass()); + if (flags != Modifier.PUBLIC) { + throw new RuntimeException( + "expected 0x1, got 0x" + Integer.toHexString(flags) + " for object array"); + } + + // test multi-dimensional object array. should return flags of component. + flags = (int)m.invoke((new SUPERnotset[4][2]).getClass()); + if (flags != Modifier.PUBLIC) { + throw new RuntimeException( + "expected 0x1, got 0x" + Integer.toHexString(flags) + " for object array"); + } + } +} diff --git a/test/hotspot/jtreg/runtime/ClassFile/ClassFileVersionTest.java b/test/hotspot/jtreg/runtime/ClassFile/ClassFileVersionTest.java new file mode 100644 index 00000000000..86c09c25f04 --- /dev/null +++ b/test/hotspot/jtreg/runtime/ClassFile/ClassFileVersionTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022, 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 8291360 + * @summary Test getting the class file version for java.lang.Class API + * @modules java.base/java.lang:open + * @compile classFileVersions.jcod + * @run main/othervm --enable-preview ClassFileVersionTest + */ + +import java.lang.reflect.*; + +public class ClassFileVersionTest { + + static Method m; + + public static void testIt(String className, int expectedResult) throws Exception { + Class testClass = Class.forName(className); + int ver = (int)m.invoke(testClass); + if (ver != expectedResult) { + int exp_minor = (expectedResult >> 16) & 0x0000FFFF; + int exp_major = expectedResult & 0x0000FFFF; + int got_minor = (ver >> 16) & 0x0000FFFF; + int got_major = ver & 0x0000FFFF; + throw new RuntimeException( + "Expected " + exp_minor + ":" + exp_major + " but got " + got_minor + ":" + got_major); + } + } + + public static void main(String argv[]) throws Throwable { + Class cl = java.lang.Class.class; + m = cl.getDeclaredMethod("getClassFileVersion", new Class[0]); + m.setAccessible(true); + + testIt("Version64", 64); + testIt("Version59", 59); + testIt("Version45_3", 0x3002D); // 3:45 + // test minor version of 65535. + testIt("Version64_65535", 0xFFFF0040); // 0xFFFF0040 = 65535:64 + + // test primitive array. should return latest version. + int ver = (int)m.invoke((new int[3]).getClass()); + if (ver != 64) { + int got_minor = (ver >> 16) & 0x0000FFFF; + int got_major = ver & 0x0000FFFF; + throw new RuntimeException( + "Expected 0:64, but got " + got_minor + ":" + got_major + " for primitive array"); + } + + // test object array. should return class file version of component. + ver = (int)m.invoke((new Version59[2]).getClass()); + if (ver != 59) { + int got_minor = (ver >> 16) & 0x0000FFFF; + int got_major = ver & 0x0000FFFF; + throw new RuntimeException( + "Expected 0:59, but got " + got_minor + ":" + got_major + " for object array"); + } + + // test multi-dimensional object array. should return class file version of component. + ver = (int)m.invoke((new Version59[3][2]).getClass()); + if (ver != 59) { + int got_minor = (ver >> 16) & 0x0000FFFF; + int got_major = ver & 0x0000FFFF; + throw new RuntimeException( + "Expected 0:59, but got " + got_minor + ":" + got_major + " for object array"); + } + } +} diff --git a/test/hotspot/jtreg/runtime/ClassFile/classAccessFlagsRaw.jcod b/test/hotspot/jtreg/runtime/ClassFile/classAccessFlagsRaw.jcod new file mode 100644 index 00000000000..bb1f66db79d --- /dev/null +++ b/test/hotspot/jtreg/runtime/ClassFile/classAccessFlagsRaw.jcod @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2022, 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. + * + */ + +// Class with ACC_SUPER set +class SUPERset { + 0xCAFEBABE; + 0; // minor version + 64; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 ""; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "SUPERset"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x48 + Utf8 "LineNumberTable"; // #10 at 0x4F + Utf8 "hi"; // #11 at 0x61 + Utf8 "SourceFile"; // #12 at 0x66 + Utf8 "SUPERset.java"; // #13 at 0x73 + } // Constant Pool + + 0x0021; // access [ ACC_PUBLIC ACC_SUPER ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // Fields + } // Fields + + [2] { // Methods + { // method at 0x90 + 0x0001; // access + #5; // name_index : + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 29) { // Code at 0x98 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xAF + [1] { // line_number_table + 0 1; // at 0xBB + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method at 0xBB + 0x0009; // access + #11; // name_index : hi + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 25) { // Code at 0xC3 + 0; // max_stack + 0; // max_locals + Bytes[1]{ + 0xB1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xD6 + [1] { // line_number_table + 0 2; // at 0xE2 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [1] { // Attributes + Attr(#12, 2) { // SourceFile at 0xE4 + #13; + } // end SourceFile + } // Attributes +} // end class SUPERset + + +// Class with ACC_SUPER not set +class SUPERnotset { + 0xCAFEBABE; + 0; // minor version + 64; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 ""; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "SUPERnotset"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x48 + Utf8 "LineNumberTable"; // #10 at 0x4F + Utf8 "hi"; // #11 at 0x61 + Utf8 "SourceFile"; // #12 at 0x66 + Utf8 "SUPERnotset.java"; // #13 at 0x73 + } // Constant Pool + + 0x0001; // access [ ACC_PUBLIC ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // Fields + } // Fields + + [2] { // Methods + { // method at 0x90 + 0x0001; // access + #5; // name_index : + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 29) { // Code at 0x98 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xAF + [1] { // line_number_table + 0 1; // at 0xBB + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method at 0xBB + 0x0009; // access + #11; // name_index : hi + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 25) { // Code at 0xC3 + 0; // max_stack + 0; // max_locals + Bytes[1]{ + 0xB1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xD6 + [1] { // line_number_table + 0 2; // at 0xE2 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [1] { // Attributes + Attr(#12, 2) { // SourceFile at 0xE4 + #13; + } // end SourceFile + } // Attributes +} // end class SUPERnotset diff --git a/test/hotspot/jtreg/runtime/ClassFile/classFileVersions.jcod b/test/hotspot/jtreg/runtime/ClassFile/classFileVersions.jcod new file mode 100644 index 00000000000..27f0afd98e2 --- /dev/null +++ b/test/hotspot/jtreg/runtime/ClassFile/classFileVersions.jcod @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2022, 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. + * + */ + +// Class with major version 64 and minor version 0 +class Version64 { + 0xCAFEBABE; + 0; // minor version + 64; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 ""; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "Version64"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x48 + Utf8 "LineNumberTable"; // #10 at 0x4F + Utf8 "hi"; // #11 at 0x61 + Utf8 "SourceFile"; // #12 at 0x66 + Utf8 "Version64.java"; // #13 at 0x73 + } // Constant Pool + + 0x0021; // access [ ACC_PUBLIC ACC_SUPER ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // Fields + } // Fields + + [2] { // Methods + { // method at 0x90 + 0x0001; // access + #5; // name_index : + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 29) { // Code at 0x98 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xAF + [1] { // line_number_table + 0 1; // at 0xBB + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method at 0xBB + 0x0009; // access + #11; // name_index : hi + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 25) { // Code at 0xC3 + 0; // max_stack + 0; // max_locals + Bytes[1]{ + 0xB1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xD6 + [1] { // line_number_table + 0 2; // at 0xE2 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [1] { // Attributes + Attr(#12, 2) { // SourceFile at 0xE4 + #13; + } // end SourceFile + } // Attributes +} // end class Version64 + + +// Class with major version 59 and minor version 0 +class Version59 { + 0xCAFEBABE; + 0; // minor version + 59; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 ""; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "Version59"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x48 + Utf8 "LineNumberTable"; // #10 at 0x4F + Utf8 "hi"; // #11 at 0x61 + Utf8 "SourceFile"; // #12 at 0x66 + Utf8 "Version59.java"; // #13 at 0x73 + } // Constant Pool + + 0x0021; // access [ ACC_PUBLIC ACC_SUPER ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // Fields + } // Fields + + [2] { // Methods + { // method at 0x90 + 0x0001; // access + #5; // name_index : + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 29) { // Code at 0x98 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xAF + [1] { // line_number_table + 0 1; // at 0xBB + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method at 0xBB + 0x0009; // access + #11; // name_index : hi + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 25) { // Code at 0xC3 + 0; // max_stack + 0; // max_locals + Bytes[1]{ + 0xB1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xD6 + [1] { // line_number_table + 0 2; // at 0xE2 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [1] { // Attributes + Attr(#12, 2) { // SourceFile at 0xE4 + #13; + } // end SourceFile + } // Attributes +} // end class Version59 + + +// Class with major version 64 and minor version 65535 +class Version64_65535 { + 0xCAFEBABE; + 65535; // minor version + 64; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 ""; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "Version64_65535"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x48 + Utf8 "LineNumberTable"; // #10 at 0x4F + Utf8 "hi"; // #11 at 0x61 + Utf8 "SourceFile"; // #12 at 0x66 + Utf8 "Version64_65535.java"; // #13 at 0x73 + } // Constant Pool + + 0x0021; // access [ ACC_PUBLIC ACC_SUPER ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // Fields + } // Fields + + [2] { // Methods + { // method at 0x90 + 0x0001; // access + #5; // name_index : + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 29) { // Code at 0x98 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xAF + [1] { // line_number_table + 0 1; // at 0xBB + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method at 0xBB + 0x0009; // access + #11; // name_index : hi + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 25) { // Code at 0xC3 + 0; // max_stack + 0; // max_locals + Bytes[1]{ + 0xB1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xD6 + [1] { // line_number_table + 0 2; // at 0xE2 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [1] { // Attributes + Attr(#12, 2) { // SourceFile at 0xE4 + #13; + } // end SourceFile + } // Attributes +} // end class Version64_65535 + + +// Class with major version 45 and minor version 3 +class Version45_3 { + 0xCAFEBABE; + 3; // minor version + 45; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 ""; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "Version45_3"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x48 + Utf8 "LineNumberTable"; // #10 at 0x4F + Utf8 "hi"; // #11 at 0x61 + Utf8 "SourceFile"; // #12 at 0x66 + Utf8 "Version45_3.java"; // #13 at 0x73 + } // Constant Pool + + 0x0021; // access [ ACC_PUBLIC ACC_SUPER ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // Fields + } // Fields + + [2] { // Methods + { // method at 0x90 + 0x0001; // access + #5; // name_index : + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 29) { // Code at 0x98 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xAF + [1] { // line_number_table + 0 1; // at 0xBB + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method at 0xBB + 0x0009; // access + #11; // name_index : hi + #6; // descriptor_index : ()V + [1] { // Attributes + Attr(#9, 25) { // Code at 0xC3 + 0; // max_stack + 0; // max_locals + Bytes[1]{ + 0xB1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xD6 + [1] { // line_number_table + 0 2; // at 0xE2 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [1] { // Attributes + Attr(#12, 2) { // SourceFile at 0xE4 + #13; + } // end SourceFile + } // Attributes +} // end class Version45_3 diff --git a/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java b/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java new file mode 100644 index 00000000000..b556e0d0211 --- /dev/null +++ b/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022, 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 8291459 + * @summary Test that GenerateOopMap does not crash if last bytecode is a conditional branch + * @library /test/lib / + * @requires vm.flagless + * @compile if_icmpleIsLastOpcode.jasm + * @run driver TestGenerateOopMapCrash + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +// This test was copied from compiler test TestLinkageErrorInGenerateOopMap.java. +public class TestGenerateOopMapCrash { + + public static void main(String args[]) throws Exception { + if (args.length == 0) { + // Spawn new VM instance to execute test + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:-TieredCompilation", + "-XX:CompileCommand=dontinline,if_icmpleIsLastOpcode.m*", + "-Xmx64m", + TestGenerateOopMapCrash.class.getName(), + "run"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } else { + // Execute test + if_icmpleIsLastOpcode.test(); + } + } +} diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.hpp b/test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm similarity index 54% rename from src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.hpp rename to test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm index a5611d555cb..07365f7e6b5 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.hpp +++ b/test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm @@ -1,7 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * Copyright (c) 2022, 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,15 +22,31 @@ * */ -#ifndef OS_CPU_BSD_AARCH64_OS_BSD_AARCH64_HPP -#define OS_CPU_BSD_AARCH64_OS_BSD_AARCH64_HPP +// Old class file with a method whose last bytecode is an unreachable +// conditional branch. +public class if_icmpleIsLastOpcode version 49:0 { + public static Method m1:"()I" stack 1 locals 0 { + iconst_0; + ireturn; + } - static void setup_fpu(); + public static Method m2:"(I)V" stack 1 locals 1 { + return; + } - static bool is_allocatable(size_t bytes); - - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - -#endif // OS_CPU_BSD_AARCH64_OS_BSD_AARCH64_HPP + public static Method test:"()V" stack 2 locals 1 { + iconst_0; + istore_0; + Loop: stack_frame_type append; + locals_map int; + iload_0; + invokestatic Method if_icmpleIsLastOpcode."m1":"()I"; + invokestatic Method if_icmpleIsLastOpcode."m2":"(I)V"; + iinc 0, 1; + ldc 100000; + if_icmple Loop; + return; + ldc 100000; + if_icmple Loop; + } +} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadInfo/thrinfo001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadInfo/thrinfo001/TestDescription.java index f42db7b1eee..fbd4bd50f36 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadInfo/thrinfo001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadInfo/thrinfo001/TestDescription.java @@ -41,6 +41,7 @@ * Fixed according to the 4480280 bug. * Ported from JVMDI. * + * @requires vm.jvmti & vm.continuations * @library /vmTestbase * /test/lib * @build nsk.jvmti.GetThreadInfo.thrinfo001 diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefineVirtual/StressRedefineVirtual.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefineVirtual/StressRedefineVirtual.java index c042b3ca221..5e8f76bcc42 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefineVirtual/StressRedefineVirtual.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefineVirtual/StressRedefineVirtual.java @@ -27,6 +27,7 @@ * * @key randomness * + * @requires vm.jvmti & vm.continuations * @library /vmTestbase * /test/lib * @build nsk.jvmti.RedefineClasses.StressRedefine diff --git a/test/jdk/ProblemList-Xcomp.txt b/test/jdk/ProblemList-Xcomp.txt index df1b9da12b0..7569ca406e9 100644 --- a/test/jdk/ProblemList-Xcomp.txt +++ b/test/jdk/ProblemList-Xcomp.txt @@ -29,3 +29,8 @@ java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all java/lang/ref/ReferenceEnqueue.java 8284236 generic-all + +java/lang/Integer/BitTwiddle.java 8291649 generic-x64 +java/lang/Long/BitTwiddle.java 8291649 generic-x64 +java/util/zip/TestCRC32C.java 8291649 generic-x64 +java/util/zip/TestChecksum.java 8291649 generic-x64 diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 5f3df8ec1a2..d49bcfc2795 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -222,7 +222,6 @@ java/awt/Window/LocationAtScreenCorner/LocationAtScreenCorner.java 8203371 linux java/awt/font/TextLayout/TextLayoutBounds.java 8169188 generic-all java/awt/image/BufferedImage/ICMColorDataTest/ICMColorDataTest.java 8233028 generic-all java/awt/image/DrawImage/IncorrectAlphaSurface2SW.java 8056077 linux-all -java/awt/image/multiresolution/MultiresolutionIconTest.java 8169187,8252812 macosx-all,windows-all,linux-x64 java/awt/print/Headless/HeadlessPrinterJob.java 8196088 windows-all sun/awt/datatransfer/SuplementaryCharactersTransferTest.java 8011371 generic-all sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all @@ -495,6 +494,7 @@ java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java 8151492 generic- java/lang/invoke/LFCaching/LFGarbageCollectedTest.java 8078602 generic-all java/lang/invoke/lambda/LambdaFileEncodingSerialization.java 8249079 linux-x64 java/lang/invoke/RicochetTest.java 8251969 generic-all +java/lang/ProcessBuilder/PipelineLeaksFD.java 8291760 linux-all ############################################################################ diff --git a/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java b/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java index 7011bad27fb..9bda4745ce4 100644 --- a/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java +++ b/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -128,7 +128,7 @@ public class MultiresolutionIconTest extends JFrame { private boolean checkPressedColor(int x, int y, Color ok) { - r.mouseMove(x, y); + r.mouseMove(x+5, y+5); r.waitForIdle(); r.mousePress(InputEvent.BUTTON1_DOWN_MASK); r.waitForIdle(100); @@ -217,6 +217,10 @@ public class MultiresolutionIconTest extends JFrame { public static void main(String[] args) throws Exception { for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) { + // skip AquaL&F because Aqua icon darkening fails the test + if (LF.getName().equalsIgnoreCase("Mac OS X")) { + continue; + } System.out.println("\nL&F: " + LF.getName()); (new MultiresolutionIconTest(LF)).doTest(); } diff --git a/test/jdk/java/beans/XMLEncoder/Test4625418.java b/test/jdk/java/beans/XMLEncoder/Test4625418.java index 6a1b8bbf268..485a079ad4d 100644 --- a/test/jdk/java/beans/XMLEncoder/Test4625418.java +++ b/test/jdk/java/beans/XMLEncoder/Test4625418.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2022, 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 - * @bug 4625418 8239965 + * @bug 4625418 8239965 8290488 * @summary Tests XML encoding * @author Sergey Malenkov * @run main/timeout=360 Test4625418 @@ -107,7 +107,7 @@ public final class Test4625418 implements ExceptionListener { "Cp861", "Cp862", "Cp863", - "Cp864", + //"Cp864", "Cp865", "Cp866", "Cp868", @@ -180,7 +180,7 @@ public final class Test4625418 implements ExceptionListener { "IBM861", "IBM862", "IBM863", - "IBM864", + //"IBM864", "IBM865", "IBM866", "IBM868", diff --git a/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java b/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java index 74c21c540d8..5dafdc181cd 100644 --- a/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java +++ b/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,29 +30,93 @@ import org.testng.annotations.Test; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -/* @test +/* + * @test id=G1 + * @requires vm.gc.G1 * @bug 8277072 * @library /test/lib/ - * @summary ObjectStreamClass caches keep ClassLoaders alive - * @run testng/othervm -Xmx10m -XX:SoftRefLRUPolicyMSPerMB=1 ObjectStreamClassCaching + * @summary ObjectStreamClass caches keep ClassLoaders alive (G1 GC) + * @run testng/othervm -Xmx64m -XX:+UseG1GC ObjectStreamClassCaching + */ + +/* + * @test id=Parallel + * @requires vm.gc.Parallel + * @bug 8277072 + * @library /test/lib/ + * @summary ObjectStreamClass caches keep ClassLoaders alive (Parallel GC) + * @run testng/othervm -Xmx64m -XX:+UseParallelGC ObjectStreamClassCaching + */ + +/* + * @test id=Z + * @requires vm.gc.Z + * @bug 8277072 + * @library /test/lib/ + * @summary ObjectStreamClass caches keep ClassLoaders alive (Z GC) + * @run testng/othervm -Xmx64m -XX:+UseZGC ObjectStreamClassCaching + */ + +/* + * @test id=Shenandoah + * @requires vm.gc.Shenandoah + * @bug 8277072 + * @library /test/lib/ + * @summary ObjectStreamClass caches keep ClassLoaders alive (Shenandoah GC) + * @run testng/othervm -Xmx64m -XX:+UseShenandoahGC ObjectStreamClassCaching + */ + +/* + * @test id=Serial + * @requires vm.gc.Serial + * @bug 8277072 + * @library /test/lib/ + * @summary ObjectStreamClass caches keep ClassLoaders alive (Serial GC) + * @run testng/othervm -Xmx64m -XX:+UseSerialGC ObjectStreamClassCaching */ public class ObjectStreamClassCaching { + /** + * Test methods execute in same VM and are ordered by name. + * We test effectiveness 1st which is sensitive to previous allocations when ZGC is used. + */ @Test - public void testCachingEffectiveness() throws Exception { - var ref = lookupObjectStreamClass(TestClass.class); + public void test1CacheEffectiveness() throws Exception { + var list = new ArrayList<>(); + var ref1 = lookupObjectStreamClass(TestClass1.class); + var ref2 = newWeakRef(); + boolean oome = false; + try { + while (!ref2.refersTo(null)) { + list.add(new byte[1024 * 1024 * 1]); // 1 MiB chunks + System.out.println("1MiB allocated..."); + Thread.sleep(5L); + } + } catch (OutOfMemoryError e) { + // release + list = null; + oome = true; + } + assertFalse(oome, "WeakReference was not cleared although memory was pressed hard"); + assertFalse(ref1.refersTo(null), + "Cache lost entry together with WeakReference being cleared although memory was not under pressure"); System.gc(); Thread.sleep(100L); - // to trigger any ReferenceQueue processing... - lookupObjectStreamClass(AnotherTestClass.class); - assertFalse(ref.refersTo(null), - "Cache lost entry although memory was not under pressure"); } @Test - public void testCacheReleaseUnderMemoryPressure() throws Exception { - var ref = lookupObjectStreamClass(TestClass.class); - pressMemoryHard(ref); + public void test2CacheReleaseUnderMemoryPressure() throws Exception { + var list = new ArrayList<>(); + var ref = lookupObjectStreamClass(TestClass2.class); + try { + while (!ref.refersTo(null)) { + list.add(new byte[1024 * 1024 * 4]); // 4 MiB chunks + System.out.println("4MiB allocated..."); + } + } catch (OutOfMemoryError e) { + // release + list = null; + } System.gc(); Thread.sleep(100L); assertTrue(ref.refersTo(null), @@ -60,24 +124,18 @@ public class ObjectStreamClassCaching { } // separate method so that the looked-up ObjectStreamClass is not kept on stack - private static WeakReference lookupObjectStreamClass(Class cl) { + private static Reference lookupObjectStreamClass(Class cl) { return new WeakReference<>(ObjectStreamClass.lookup(cl)); } - private static void pressMemoryHard(Reference ref) { - try { - var list = new ArrayList<>(); - while (!ref.refersTo(null)) { - list.add(new byte[1024 * 1024 * 64]); // 64 MiB chunks - } - } catch (OutOfMemoryError e) { - // release - } + // separate method so that the new Object() is not kept on stack + private static Reference newWeakRef() { + return new WeakReference<>(new Object()); + } + + static class TestClass1 implements Serializable { + } + + static class TestClass2 implements Serializable { } } - -class TestClass implements Serializable { -} - -class AnotherTestClass implements Serializable { -} diff --git a/test/jdk/java/lang/management/ThreadMXBean/VirtualThreads.java b/test/jdk/java/lang/management/ThreadMXBean/VirtualThreads.java index 748f36518e5..b986a8cab4f 100644 --- a/test/jdk/java/lang/management/ThreadMXBean/VirtualThreads.java +++ b/test/jdk/java/lang/management/ThreadMXBean/VirtualThreads.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8284161 + * @bug 8284161 8290562 * @summary Test java.lang.management.ThreadMXBean with virtual threads * @enablePreview * @modules java.base/java.lang:+open java.management @@ -63,32 +63,56 @@ public class VirtualThreads { */ @Test public void testGetAllThreadIds() throws Exception { - runInVirtualThread(() -> { - long currentTid = Thread.currentThread().getId(); + Thread vthread = Thread.startVirtualThread(LockSupport::park); + try { long[] tids = ManagementFactory.getThreadMXBean().getAllThreadIds(); - boolean found = Arrays.stream(tids).anyMatch(tid -> tid == currentTid); - assertFalse(found); - }); + + // current thread should be included + long currentTid = Thread.currentThread().threadId(); + assertTrue(Arrays.stream(tids).anyMatch(tid -> tid == currentTid)); + + // virtual thread should not be included + long vtid = vthread.threadId(); + assertFalse(Arrays.stream(tids).anyMatch(tid -> tid == vtid)); + } finally { + LockSupport.unpark(vthread); + } } /** - * Test that ThreadMXBean::getThreadInfo returns null for a virual thread. + * Test that ThreadMXBean.getThreadInfo(long) returns null for a virtual thread. */ @Test public void testGetThreadInfo1() throws Exception { + Thread vthread = Thread.startVirtualThread(LockSupport::park); + try { + long tid = vthread.threadId(); + ThreadInfo info = ManagementFactory.getThreadMXBean().getThreadInfo(tid); + assertTrue(info == null); + } finally { + LockSupport.unpark(vthread); + } + } + + /** + * Test that ThreadMXBean.getThreadInfo(long) returns null when invoked by a virtual + * thread with its own thread id. + */ + @Test + public void testGetThreadInfo2() throws Exception { runInVirtualThread(() -> { - long tid = Thread.currentThread().getId(); + long tid = Thread.currentThread().threadId(); ThreadInfo info = ManagementFactory.getThreadMXBean().getThreadInfo(tid); assertTrue(info == null); }); } /** - * Test that ThreadMXBean::getThreadInfo on a carrier thread. The stack - * frames of the virtual thread should not be returned. + * Test ThreadMXBean.getThreadInfo(long) with the thread id of a carrier thread. + * The stack frames of the virtual thread should not be returned. */ @Test - public void testGetThreadInfo2() throws Exception { + public void testGetThreadInfo3() throws Exception { if (!supportsCustomScheduler()) throw new SkipException("No support for custom schedulers"); try (ExecutorService pool = Executors.newFixedThreadPool(1)) { @@ -129,26 +153,77 @@ public class VirtualThreads { } /** - * Test that getThreadCpuTime returns -1 for a virual thread.. + * Test that ThreadMXBean.getThreadInfo(long[]) returns a null ThreadInfo for + * elements that correspond to a virtual thread. */ @Test - public void testGetThreadCpuTime() throws Exception { + public void testGetThreadInfo4() throws Exception { + Thread vthread = Thread.startVirtualThread(LockSupport::park); + try { + long tid0 = Thread.currentThread().threadId(); + long tid1 = vthread.threadId(); + long[] tids = new long[] { tid0, tid1 }; + ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(tids); + assertTrue(infos[0].getThreadId() == tid0); + assertTrue(infos[1] == null); + } finally { + LockSupport.unpark(vthread); + } + } + + /** + * Test that ThreadMXBean.getThreadCpuTime(long) returns -1 for a virtual thread. + */ + @Test + public void testGetThreadCpuTime1() { + Thread vthread = Thread.startVirtualThread(LockSupport::park); + try { + long tid = vthread.threadId(); + long cpuTime = ManagementFactory.getThreadMXBean().getThreadCpuTime(tid); + assertTrue(cpuTime == -1L); + } finally { + LockSupport.unpark(vthread); + } + } + + /** + * Test that ThreadMXBean.getThreadCpuTime(long) returns -1 when invoked by a + * virtual thread with its own thread id. + */ + @Test + public void testGetThreadCpuTime2() throws Exception { runInVirtualThread(() -> { - long tid = Thread.currentThread().getId(); + long tid = Thread.currentThread().threadId(); long cpuTime = ManagementFactory.getThreadMXBean().getThreadCpuTime(tid); assertTrue(cpuTime == -1L); }); } /** - * Test that getThreadUserTime returns -1 for a virual thread. + * Test that ThreadMXBean.getThreadUserTime(long) returns -1 for a virtual thread. */ @Test - public void testGetThreadUserTime() throws Exception { + public void testGetThreadUserTime1() { + Thread vthread = Thread.startVirtualThread(LockSupport::park); + try { + long tid = vthread.threadId(); + long userTime = ManagementFactory.getThreadMXBean().getThreadUserTime(tid); + assertTrue(userTime == -1L); + } finally { + LockSupport.unpark(vthread); + } + } + + /** + * Test that ThreadMXBean.getThreadUserTime(long) returns -1 when invoked by a + * virtual thread with its own thread id. + */ + @Test + public void testGetThreadUserTime2() throws Exception { runInVirtualThread(() -> { - long tid = Thread.currentThread().getId(); - long cpuTime = ManagementFactory.getThreadMXBean().getThreadUserTime(tid); - assertTrue(cpuTime == -1L); + long tid = Thread.currentThread().threadId(); + long userTime = ManagementFactory.getThreadMXBean().getThreadUserTime(tid); + assertTrue(userTime == -1L); }); } diff --git a/test/jdk/java/time/nontestng/java/time/zone/zoneProvider/custom/CustomTimeZoneNameProvider.java b/test/jdk/java/time/nontestng/java/time/zone/zoneProvider/custom/CustomTimeZoneNameProvider.java index 741ad9a7a84..b3944c9454d 100644 --- a/test/jdk/java/time/nontestng/java/time/zone/zoneProvider/custom/CustomTimeZoneNameProvider.java +++ b/test/jdk/java/time/nontestng/java/time/zone/zoneProvider/custom/CustomTimeZoneNameProvider.java @@ -73,7 +73,7 @@ public class CustomTimeZoneNameProvider extends TimeZoneNameProvider { @Override public Locale[] getAvailableLocales() { return new Locale[]{ - Locale.getDefault() + Locale.getDefault(Locale.Category.FORMAT) }; } } diff --git a/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java b/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java new file mode 100644 index 00000000000..234f6fdba7b --- /dev/null +++ b/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022, 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 8285838 + * @library /test/lib + * @summary This test will ensure that daylight savings rules are followed + * appropriately when setting a custom timezone ID via the TZ env variable. + * @requires os.family != "windows" + * @run main/othervm CustomTzIDCheckDST + */ +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.SimpleTimeZone; +import java.time.DayOfWeek; +import java.time.ZonedDateTime; +import java.time.temporal.TemporalAdjusters; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +public class CustomTzIDCheckDST { + private static String CUSTOM_TZ = "MEZ-1MESZ,M3.5.0,M10.5.0"; + public static void main(String args[]) throws Throwable { + if (args.length == 0) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(List.of("CustomTzIDCheckDST", "runTZTest")); + pb.environment().put("TZ", CUSTOM_TZ); + OutputAnalyzer output = ProcessTools.executeProcess(pb); + output.shouldHaveExitValue(0); + } else { + runTZTest(); + } + } + + /* TZ code will always be set to "MEZ-1MESZ,M3.5.0,M10.5.0". + * This ensures the transition periods for Daylights Savings should be at March's last + * Sunday and October's last Sunday. + */ + private static void runTZTest() { + Date time = new Date(); + if (new SimpleTimeZone(3600000, "MEZ-1MESZ", Calendar.MARCH, -1, Calendar.SUNDAY, 0, + Calendar.OCTOBER, -1, Calendar.SUNDAY, 0).inDaylightTime(time)) { + // We are in Daylight savings period. + if (time.toString().endsWith("GMT+02:00 " + Integer.toString(time.getYear() + 1900))) + return; + } else { + if (time.toString().endsWith("GMT+01:00 " + Integer.toString(time.getYear() + 1900))) + return; + } + + // Reaching here means time zone did not match up as expected. + throw new RuntimeException("Got unexpected timezone information: " + time); + } + + private static ZonedDateTime getLastSundayOfMonth(ZonedDateTime date) { + return date.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY)); + } +} diff --git a/test/jdk/javax/imageio/ReadImageNoIAETest.java b/test/jdk/javax/imageio/ReadImageNoIAETest.java new file mode 100644 index 00000000000..ffdcc8c5774 --- /dev/null +++ b/test/jdk/javax/imageio/ReadImageNoIAETest.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022, 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 8272998 + * @summary ImageIO.read() should only throw IOException from decoding + */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class ReadImageNoIAETest { + + static final byte[] data = { + (byte)0xff, (byte)0xd8, (byte)0xff, (byte)0xe0, (byte)0x00, (byte)0x10, + (byte)0x4a, (byte)0x46, (byte)0x49, (byte)0x46, (byte)0x00, (byte)0x01, + (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xdb, (byte)0x00, (byte)0x43, + (byte)0x00, (byte)0x08, (byte)0x06, (byte)0x06, (byte)0x07, (byte)0x06, + (byte)0x05, (byte)0x08, (byte)0x07, (byte)0x07, (byte)0x07, (byte)0x09, + (byte)0x09, (byte)0x08, (byte)0x0a, (byte)0x0c, (byte)0x14, (byte)0x0d, + (byte)0x0c, (byte)0x0b, (byte)0x0b, (byte)0x0c, (byte)0x19, (byte)0x12, + (byte)0x13, (byte)0x0f, (byte)0x14, (byte)0x1d, (byte)0x1a, (byte)0x1f, + (byte)0x1e, (byte)0x1d, (byte)0x1a, (byte)0x1c, (byte)0x1c, (byte)0x20, + (byte)0x24, (byte)0x2e, (byte)0x27, (byte)0x20, (byte)0x22, (byte)0x2c, + (byte)0x23, (byte)0x1c, (byte)0x1c, (byte)0x28, (byte)0x37, (byte)0x29, + (byte)0x2c, (byte)0x30, (byte)0x31, (byte)0x34, (byte)0x34, (byte)0x34, + (byte)0x1f, (byte)0x27, (byte)0x39, (byte)0x3d, (byte)0x38, (byte)0x32, + (byte)0x3c, (byte)0x2e, (byte)0x33, (byte)0x34, (byte)0x32, (byte)0xff, + (byte)0xdb, (byte)0x00, (byte)0x43, (byte)0x01, (byte)0x09, (byte)0x09, + (byte)0x09, (byte)0x0c, (byte)0x0b, (byte)0x0c, (byte)0x18, (byte)0x0d, + (byte)0x0d, (byte)0x18, (byte)0x32, (byte)0x21, (byte)0x1c, (byte)0x21, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, (byte)0x32, + (byte)0x32, (byte)0x32, (byte)0xff, (byte)0xc0, (byte)0x00, (byte)0x11, + (byte)0x08, (byte)0xc0, (byte)0x05, (byte)0x6d, (byte)0x05, (byte)0x03, + (byte)0x01, (byte)0x22, (byte)0x00, (byte)0x02, (byte)0x11, (byte)0x01, + (byte)0x03, (byte)0x11, (byte)0x01, (byte)0xff, (byte)0xc4, (byte)0x00, + (byte)0x1f, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x05, (byte)0x01, + (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, + (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09, (byte)0x0a, (byte)0x0b, + (byte)0xff, (byte)0xc4, (byte)0x00, (byte)0xb5, (byte)0x10, (byte)0x00, + (byte)0x02, (byte)0x01, (byte)0x03, (byte)0x03, (byte)0x02, (byte)0x04, + (byte)0x03, (byte)0x05, (byte)0x05, (byte)0x04, (byte)0x04, (byte)0x00, + (byte)0x00, (byte)0x01, (byte)0x7d, (byte)0x01, (byte)0x02, (byte)0x03, + (byte)0x00, (byte)0x04, (byte)0x11, (byte)0x05, (byte)0x12, (byte)0x21, + (byte)0x31, (byte)0x41, (byte)0x06, (byte)0x13, (byte)0x51, (byte)0x61, + (byte)0x07, (byte)0x22, (byte)0x71, (byte)0x14, (byte)0x32, (byte)0x81, + (byte)0x91, (byte)0xa1, (byte)0x08, (byte)0x23, (byte)0x42, (byte)0xb1, + (byte)0xc1, (byte)0x15, (byte)0x52, (byte)0xd1, (byte)0xf0, (byte)0x24, + (byte)0x33, (byte)0x62, (byte)0x72, (byte)0x82, (byte)0x09, (byte)0x0a, + (byte)0x16, (byte)0x17, (byte)0x18, (byte)0x19, (byte)0x1a, (byte)0x25, + (byte)0x26, (byte)0x27, (byte)0x28, (byte)0x29, (byte)0x2a, (byte)0x34, + (byte)0x35, (byte)0x36, (byte)0x37, (byte)0x38, (byte)0x39, (byte)0x3a, + (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x48, + (byte)0x49, (byte)0x4a, (byte)0x53, (byte)0x54, (byte)0x55, (byte)0x56, + (byte)0x57, (byte)0x58, (byte)0x59, (byte)0x5a, (byte)0x63, (byte)0x64, + (byte)0x65, (byte)0x66, (byte)0x67, (byte)0x68, (byte)0x69, (byte)0x6a, + (byte)0x73, (byte)0x74, (byte)0x75, (byte)0x76, (byte)0x77, (byte)0x78, + (byte)0x79, (byte)0x7a, (byte)0x83, (byte)0x84, (byte)0x85, (byte)0x86, + (byte)0x87, (byte)0x88, (byte)0x89, (byte)0x8a, (byte)0x92, (byte)0x93, + (byte)0x94, (byte)0x95, (byte)0x96, (byte)0x97, (byte)0x98, (byte)0x99, + (byte)0x9a, (byte)0xa2, (byte)0xa3, (byte)0xa4, (byte)0xa5, (byte)0xa6, + (byte)0xa7, (byte)0xa8, (byte)0xa9, (byte)0xaa, (byte)0xb2, (byte)0xb3, + (byte)0xb4, (byte)0xb5, (byte)0xb6, (byte)0xb7, (byte)0xb8, (byte)0xb9, + (byte)0xba, (byte)0xc2, (byte)0xc3, (byte)0xc4, (byte)0xc5, (byte)0xc6, + (byte)0xc7, (byte)0xc8, (byte)0xc9, (byte)0xca, (byte)0xd2, (byte)0xd3, + (byte)0xd4, (byte)0xd5, (byte)0xd6, (byte)0xd7, (byte)0xd8, (byte)0xd9, + (byte)0xda, (byte)0xe1, (byte)0xe2, (byte)0xe3, (byte)0xe4, (byte)0xe5, + (byte)0xe6, (byte)0xe7, (byte)0xe8, (byte)0xe9, (byte)0xea, (byte)0xf1, + (byte)0xf2, (byte)0xf3, (byte)0xf4, (byte)0xf5, (byte)0xf6, (byte)0xf7, + (byte)0xf8, (byte)0xf9, (byte)0xfa, (byte)0xff, (byte)0xc4, (byte)0x00, + (byte)0x1f, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0x01, + (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, + (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, + (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09, (byte)0x0a, (byte)0x0b, + (byte)0xff, (byte)0xc4, (byte)0x00, (byte)0xb5, (byte)0x11, (byte)0x00, + (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x04, (byte)0x03, + (byte)0x04, (byte)0x07, (byte)0x05, (byte)0x04, (byte)0x04, (byte)0x00, + (byte)0x01, (byte)0x02, (byte)0x77, (byte)0x00, (byte)0x01, (byte)0x02, + (byte)0x03, (byte)0x11, (byte)0x04, (byte)0x05, (byte)0x21, (byte)0x31, + (byte)0x06, (byte)0x12, (byte)0x41, (byte)0x51, (byte)0x07, (byte)0x61, + (byte)0x71, (byte)0x13, (byte)0x22, (byte)0x32, (byte)0x81, (byte)0x08, + (byte)0x14, (byte)0x42, (byte)0x91, (byte)0xa1, (byte)0xb1, (byte)0xc1, + (byte)0x09, (byte)0x23, (byte)0x33, (byte)0x52, (byte)0xf0, (byte)0x15, + (byte)0x62, (byte)0x72, (byte)0xd1, (byte)0x0a, (byte)0x16, (byte)0x24, + (byte)0x34, (byte)0xe1, (byte)0x25, (byte)0xf1, (byte)0x17, (byte)0x18, + (byte)0x19, (byte)0x1a, (byte)0x26, (byte)0x27, (byte)0x28, (byte)0x29, + (byte)0x2a, (byte)0x35, (byte)0x36, (byte)0x37, (byte)0x38, (byte)0x39, + (byte)0x3a, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, + (byte)0x48, (byte)0x49, (byte)0x4a, (byte)0x53, (byte)0x54, (byte)0x55, + (byte)0x56, (byte)0x57, (byte)0x58, (byte)0x59, (byte)0x5a, (byte)0x63, + (byte)0x64, (byte)0x65, (byte)0x66, (byte)0x67, (byte)0x68, (byte)0x69, + (byte)0x6a, (byte)0x73, (byte)0x74, (byte)0x75, (byte)0x76, (byte)0x77, + (byte)0x78, (byte)0x79, (byte)0x7a, (byte)0x82, (byte)0x83, (byte)0x84, + (byte)0x85, (byte)0x86, (byte)0x87, (byte)0x88, (byte)0x89, (byte)0x8a, + (byte)0x92, (byte)0x93, (byte)0x94, (byte)0x95, (byte)0x96, (byte)0x97, + (byte)0x98, (byte)0x99, (byte)0x9a, (byte)0xa2, (byte)0xa3, (byte)0xa4, + (byte)0xa5, (byte)0xa6, (byte)0xa7, (byte)0xa8, (byte)0xa9, (byte)0xaa, + (byte)0xb2, (byte)0xb3, (byte)0xb4, (byte)0xb5, (byte)0xb6, (byte)0xb7, + (byte)0xb8, (byte)0xb9, (byte)0xba, (byte)0xc2, (byte)0xc3, (byte)0xc4, + (byte)0xc5, (byte)0xc6, (byte)0xc7, (byte)0xc8, (byte)0xc9, (byte)0xca, + (byte)0xd2, (byte)0xd3, (byte)0xd4, (byte)0xd5, (byte)0xd6, (byte)0xd7, + (byte)0xd8, (byte)0xd9, (byte)0xda, (byte)0xe2, (byte)0xe3, (byte)0xe4, + (byte)0xe5, (byte)0xe6, (byte)0xe7, (byte)0xe8, (byte)0xe9, (byte)0xea, + (byte)0xf2, (byte)0xf3, (byte)0xf4, (byte)0xf5, (byte)0xf6, (byte)0xf7, + (byte)0xf8, (byte)0xf9, (byte)0xfa, (byte)0xff, (byte)0xda, (byte)0x00, + (byte)0x0c, (byte)0x03, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x11, + (byte)0x03, (byte)0x11, (byte)0x00, (byte)0x3f, (byte)0x00, (byte)0xe2, + (byte)0xe8, (byte)0xa2, (byte)0x8a, (byte)0xf9, (byte)0x93, (byte)0xf7, + (byte)0x13, (byte)0xff, (byte)0xd9 + }; + + public static void main(String[] arg) { + boolean io_exception = false; + try { + ImageIO.read(new ByteArrayInputStream(data)); + } catch (IOException e) { + io_exception = true; + } + if (!io_exception) { + throw new RuntimeException("No expected IOException"); + } + } +} diff --git a/test/jdk/javax/swing/JTabbedPane/TabbedPaneBug.java b/test/jdk/javax/swing/JTabbedPane/TabbedPaneBug.java new file mode 100644 index 00000000000..5ba2432ee09 --- /dev/null +++ b/test/jdk/javax/swing/JTabbedPane/TabbedPaneBug.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, 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.awt.AWTException; +import java.awt.Color; +import java.awt.Robot; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 8259687 + * @key headful + * @summary Tests whether the selected tab's component is on the top and visible. + * @run main TabbedPaneBug + */ +public class TabbedPaneBug { + + private static final int FIRST = 0; + private static final int SECOND = 1; + private static JFrame window; + private static JTabbedPane tabs; + private static final JPanel firstTab = new JPanel(); + private static final JPanel secondTab = new JPanel(); + + public static void main(String[] args) throws AWTException, + InterruptedException, InvocationTargetException { + try { + Robot robot = new Robot(); + robot.setAutoDelay(200); + SwingUtilities.invokeAndWait(() -> createAndShowGUI()); + + robot.waitForIdle(); + robot.mouseMove(window.getWidth()/2, window.getHeight()/2); + robot.delay(500); + Color actualColor = robot.getPixelColor(window.getWidth()/2, + window.getHeight()/2); + robot.delay(200); + + if (actualColor.equals(Color.RED)) { + throw new RuntimeException("The second (selected) component" + + " is not on the top!!"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (window != null) { + window.dispose(); + } + }); + } + + } + + private static void createAndShowGUI() { + window = new JFrame("Tabbed Pane Bug"); + tabs = new JTabbedPane(); + + firstTab.setBackground(Color.RED); + secondTab.setBackground(Color.GREEN); + + tabs.addChangeListener((e) -> { + if (tabs.getSelectedComponent() == null) { + switch (tabs.getSelectedIndex()) { + case FIRST: + tabs.setComponentAt(tabs.getSelectedIndex(), firstTab); + break; + case SECOND: + tabs.setComponentAt(tabs.getSelectedIndex(), secondTab); + break; + default: + } + } + }); + + tabs.addTab("First", null); + tabs.addTab("Second", null); + + tabs.setSelectedIndex(SECOND); + window.add(tabs); + window.setSize(200, 200); + window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + window.setVisible(true); + } +} diff --git a/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java b/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java index 6b60d6d54d5..8ef3e5cb180 100644 --- a/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java +++ b/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,39 +26,44 @@ import jdk.internal.misc.TerminatingThreadLocal; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /* * @test - * @bug 8202788 + * @bug 8202788 8291897 * @summary TerminatingThreadLocal unit test * @modules java.base/jdk.internal.misc - * @run main TestTerminatingThreadLocal + * @requires vm.continuations + * @enablePreview + * @run main/othervm -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=2 TestTerminatingThreadLocal */ public class TestTerminatingThreadLocal { public static void main(String[] args) { - ttlTestSet(42, 112); + ttlTestSet(42, 112); ttlTestSet(null, 112); - ttlTestSet(42, null); + ttlTestSet(42, null); + + ttlTestVirtual(666, ThreadLocal::get, 666); } static void ttlTestSet(T v0, T v1) { - ttlTest(v0, ttl -> { } ); - ttlTest(v0, ttl -> { ttl.get(); }, v0); - ttlTest(v0, ttl -> { ttl.get(); ttl.remove(); } ); - ttlTest(v0, ttl -> { ttl.get(); ttl.set(v1); }, v1); - ttlTest(v0, ttl -> { ttl.set(v1); }, v1); - ttlTest(v0, ttl -> { ttl.set(v1); ttl.remove(); } ); - ttlTest(v0, ttl -> { ttl.set(v1); ttl.remove(); ttl.get(); }, v0); - ttlTest(v0, ttl -> { ttl.get(); ttl.remove(); ttl.set(v1); }, v1); + ttlTestPlatform(v0, ttl -> { } ); + ttlTestPlatform(v0, ttl -> { ttl.get(); }, v0); + ttlTestPlatform(v0, ttl -> { ttl.get(); ttl.remove(); } ); + ttlTestPlatform(v0, ttl -> { ttl.get(); ttl.set(v1); }, v1); + ttlTestPlatform(v0, ttl -> { ttl.set(v1); }, v1); + ttlTestPlatform(v0, ttl -> { ttl.set(v1); ttl.remove(); } ); + ttlTestPlatform(v0, ttl -> { ttl.set(v1); ttl.remove(); ttl.get(); }, v0); + ttlTestPlatform(v0, ttl -> { ttl.get(); ttl.remove(); ttl.set(v1); }, v1); } + @SafeVarargs - static void ttlTest(T initialValue, - Consumer> ttlOps, - T... expectedTerminatedValues) - { + static void ttlTestPlatform(T initialValue, + Consumer> ttlOps, + T... expectedTerminatedValues) { List terminatedValues = new CopyOnWriteArrayList<>(); TerminatingThreadLocal ttl = new TerminatingThreadLocal<>() { @@ -73,7 +78,7 @@ public class TestTerminatingThreadLocal { } }; - Thread thread = new Thread(() -> ttlOps.accept(ttl)); + Thread thread = new Thread(() -> ttlOps.accept(ttl), "ttl-test-platform"); thread.start(); try { thread.join(); @@ -87,4 +92,96 @@ public class TestTerminatingThreadLocal { " but got: " + terminatedValues); } } + + @SafeVarargs + static void ttlTestVirtual(T initialValue, + Consumer> ttlOps, + T... expectedTerminatedValues) { + List terminatedValues = new CopyOnWriteArrayList<>(); + + TerminatingThreadLocal ttl = new TerminatingThreadLocal<>() { + @Override + protected void threadTerminated(T value) { + terminatedValues.add(value); + } + + @Override + protected T initialValue() { + return initialValue; + } + }; + + var lock = new Lock(); + + var blockerThread = Thread.startVirtualThread(() -> { + // force compensation in carrier thread pool which will spin another + // carrier thread so that we can later observe it being terminated... + synchronized (lock) { + while (!lock.unblock) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + // keep thread running in a non-blocking-fashion which keeps + // it bound to carrier thread + while (!lock.unspin) { + Thread.onSpinWait(); + } + }); + + Thread thread = Thread + .ofVirtual() + .allowSetThreadLocals(false) + .inheritInheritableThreadLocals(false) + .name("ttl-test-virtual") + .unstarted(() -> ttlOps.accept(ttl)); + thread.start(); + try { + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + if (!terminatedValues.isEmpty()) { + throw new AssertionError("Unexpected terminated values after virtual thread.join(): " + + terminatedValues); + } + + // we now unblock the blocker thread but keep it running + synchronized (lock) { + lock.unblock = true; + lock.notify(); + } + + // carrier thread pool has a 30 second keep-alive time to terminate excessive carrier + // threads. Since blockerThread is still pinning one of them we hope for the other + // thread to be terminated... + try { + TimeUnit.SECONDS.sleep(31); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + if (!terminatedValues.equals(Arrays.asList(expectedTerminatedValues))) { + throw new AssertionError("Expected terminated values: " + + Arrays.toString(expectedTerminatedValues) + + " but got: " + terminatedValues); + } + + // we now terminate the blocker thread + lock.unspin = true; + try { + blockerThread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + static class Lock { + boolean unblock; + volatile boolean unspin; + } } diff --git a/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java index 4cadc4dfc75..1f5884c4b46 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -48,18 +48,12 @@ public final class TestTableStatisticsEvent { try (Recording recording = new Recording()) { recording.enable(EventNames.SymbolTableStatistics); recording.enable(EventNames.StringTableStatistics); - recording.enable(EventNames.PlaceholderTableStatistics); - recording.enable(EventNames.LoaderConstraintsTableStatistics); - recording.enable(EventNames.ProtectionDomainCacheTableStatistics); recording.start(); recording.stop(); List events = Events.fromRecording(recording); verifyTable(events, EventNames.SymbolTableStatistics); verifyTable(events, EventNames.StringTableStatistics); - verifyTable(events, EventNames.PlaceholderTableStatistics); - verifyTable(events, EventNames.LoaderConstraintsTableStatistics); - verifyTable(events, EventNames.ProtectionDomainCacheTableStatistics); } } diff --git a/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java b/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java new file mode 100644 index 00000000000..6ba25724123 --- /dev/null +++ b/test/jdk/sun/net/www/http/KeepAliveCache/B8291637.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022, 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 8291637 + * @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637 timeout + * @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637 max + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; + +public class B8291637 { + static CompletableFuture passed = new CompletableFuture<>(); + + static class Server extends Thread { + final ServerSocket serverSocket; + final int port; + final String param; // the parameter to test "max" or "timeout" + volatile Socket s; + + public Server(String param) throws IOException { + serverSocket = new ServerSocket(0); + port = serverSocket.getLocalPort(); + setDaemon(true); + this.param = param; + } + + public int getPort() { + return port; + } + + public void close() { + try { + serverSocket.close(); + if (s != null) + s.close(); + } catch (IOException e) {} + } + + static void readRequest(Socket s) throws IOException { + InputStream is = s.getInputStream(); + is.read(); + while (is.available() > 0) + is.read(); + } + + public void run() { + try { + while (true) { + s = serverSocket.accept(); + readRequest(s); + OutputStream os = s.getOutputStream(); + String resp = "" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 11\r\n" + + "Connection: Keep-Alive\r\n" + + "Keep-Alive: " + param + "=-10\r\n" + // invalid negative value + "\r\n" + + "Hello World"; + os.write(resp.getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + InputStream is = s.getInputStream(); + long l1 = System.currentTimeMillis(); + is.read(); + long l2 = System.currentTimeMillis(); + long diff = (l2 - l1) / 1000; + /* + * timeout is set to 20 seconds. If bug is still present + * then the timeout will occur the first time the keep alive + * thread wakes up which is after 5 seconds. This allows + * very large leeway with slow running hardware. + * + * Same behavior should occur in case of max=-1 with the bug + */ + if (diff < 19) { + passed.complete(false); + } else { + passed.complete(true); + } + System.out.println("Time diff = " + diff); + } + } catch (Throwable t) { + System.err.println("Server exception terminating: " + t); + passed.completeExceptionally(t); + } + } + } + + public static void main(String[] args) throws Exception { + Server server = new Server(args[0]); + int port = server.getPort(); + server.start(); + URL url = new URL("http://127.0.0.1:" + Integer.toString(port) + "/"); + HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); + InputStream i = urlc.getInputStream(); + int c,count=0; + byte[] buf = new byte[256]; + while ((c=i.read(buf)) != -1) { + count+=c; + } + i.close(); + System.out.println("Read " + count ); + try { + if (!passed.get()) { + throw new RuntimeException("Test failed"); + } else { + System.out.println("Test passed"); + } + } finally { + server.close(); + } + } +} diff --git a/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java b/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java index b0d6b0d1c1a..83491ad4e38 100644 --- a/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java +++ b/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java @@ -40,6 +40,7 @@ import static java.net.Proxy.NO_PROXY; public class KeepAliveProperty { static volatile boolean pass = false; + static Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); static class Server extends Thread { final ServerSocket server; @@ -138,7 +139,6 @@ public class KeepAliveProperty { public static void main(String args[]) throws Exception { // exercise the logging code - Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); logger.setLevel(Level.FINEST); ConsoleHandler h = new ConsoleHandler(); h.setLevel(Level.FINEST); @@ -171,6 +171,7 @@ public class KeepAliveProperty { if (!expectClose) throw e; } + s.join(); if (!pass) throw new RuntimeException("Failed in server"); diff --git a/test/jdk/sun/nio/cs/mapping/Cp864.c2b-irreversible b/test/jdk/sun/nio/cs/mapping/Cp864.c2b-irreversible new file mode 100644 index 00000000000..2b4e57b3364 --- /dev/null +++ b/test/jdk/sun/nio/cs/mapping/Cp864.c2b-irreversible @@ -0,0 +1 @@ +0025 0025 diff --git a/test/langtools/tools/javac/4880220/T4880220.error.out b/test/langtools/tools/javac/4880220/T4880220.error.out index c4efa186be5..ddb3565b361 100644 --- a/test/langtools/tools/javac/4880220/T4880220.error.out +++ b/test/langtools/tools/javac/4880220/T4880220.error.out @@ -4,6 +4,8 @@ T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variab T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C +T4880220.java:39:12: compiler.warn.static.not.qualified.by.type2: kindname.method +T4880220.java:40:20: compiler.warn.static.not.qualified.by.type2: kindname.variable - compiler.err.warnings.and.werror 1 error -6 warnings +8 warnings diff --git a/test/langtools/tools/javac/4880220/T4880220.java b/test/langtools/tools/javac/4880220/T4880220.java index f127a80a8f6..f0428ae0c6c 100644 --- a/test/langtools/tools/javac/4880220/T4880220.java +++ b/test/langtools/tools/javac/4880220/T4880220.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 4880220 + * @bug 4880220 8285935 * @summary Add a warning when accessing a static method via an reference * * @compile/ref=T4880220.empty.out T4880220.java @@ -31,6 +31,15 @@ public class T4880220 { Class good_2 = C[].class; } + void m3() { + var obj = new Object() { + static void foo() {} + static int i = 0; + }; + obj.foo(); + int j = obj.i; + } + C c() { return new C(); } diff --git a/test/langtools/tools/javac/4880220/T4880220.warn.out b/test/langtools/tools/javac/4880220/T4880220.warn.out index beca4a385b0..cd39a9f6f14 100644 --- a/test/langtools/tools/javac/4880220/T4880220.warn.out +++ b/test/langtools/tools/javac/4880220/T4880220.warn.out @@ -4,4 +4,6 @@ T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variab T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C -6 warnings +T4880220.java:39:12: compiler.warn.static.not.qualified.by.type2: kindname.method +T4880220.java:40:20: compiler.warn.static.not.qualified.by.type2: kindname.variable +8 warnings diff --git a/test/langtools/tools/javac/diags/examples/StaticNotQualifiedByType.java b/test/langtools/tools/javac/diags/examples/StaticNotQualifiedByType.java index 4f255f9bb9a..0d34d4c348b 100644 --- a/test/langtools/tools/javac/diags/examples/StaticNotQualifiedByType.java +++ b/test/langtools/tools/javac/diags/examples/StaticNotQualifiedByType.java @@ -22,12 +22,20 @@ */ // key: compiler.warn.static.not.qualified.by.type +// key: compiler.warn.static.not.qualified.by.type2 // options: -Xlint:static class StaticNotQualifiedByType { int m(Other other) { return other.i; } + + void m2() { + var obj = new Object() { + static void foo() {} + }; + obj.foo(); + } } class Other { diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.hpp b/test/langtools/tools/javac/generics/diamond/ScopeCopyCanGetAlteredTest.java similarity index 54% rename from src/hotspot/os_cpu/bsd_x86/os_bsd_x86.hpp rename to test/langtools/tools/javac/generics/diamond/ScopeCopyCanGetAlteredTest.java index fc5c613d4c3..1f6528b0dd8 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.hpp +++ b/test/langtools/tools/javac/generics/diamond/ScopeCopyCanGetAlteredTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -19,26 +19,33 @@ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. - * */ -#ifndef OS_CPU_BSD_X86_OS_BSD_X86_HPP -#define OS_CPU_BSD_X86_OS_BSD_X86_HPP +/* + * @test + * @bug 8260892 + * @summary Compilation fails: lambda parameter not visible in body when generics involved + * @compile ScopeCopyCanGetAlteredTest.java + */ -// Core region alignment is 16K to be able to run binaries built on MacOS x64 -// on MacOS aarch64. -#if defined(__APPLE__) && defined(COMPATIBLE_CDS_ALIGNMENT) -#define CDS_CORE_REGION_ALIGNMENT (16*K) -#endif +import java.util.function.Function; +import java.util.function.IntFunction; - static void setup_fpu(); - static bool supports_sse(); - static juint cpu_microcode_revision(); +class ScopeCopyCanGetAlteredTest { + interface GenericOp { + A apply(IntFunction func1, Function func2); + } - static jlong rdtsc(); + static GenericOp foo(IntFunction> f) { + return null; + } - // Used to register dynamic code cache area with the OS - // Note: Currently only used in 64 bit Windows implementations - static bool register_code_area(char *low, char *high) { return true; } - -#endif // OS_CPU_BSD_X86_OS_BSD_X86_HPP + static GenericOp bar() { + return foo((int arg) -> new GenericOp<>() { + @Override + public A apply(IntFunction func1, Function func2) { + return func2.apply(func1.apply(arg)); + } + }); + } +} diff --git a/test/langtools/tools/javac/processing/model/util/elements/TestRecordPredicates.java b/test/langtools/tools/javac/processing/model/util/elements/TestRecordPredicates.java new file mode 100644 index 00000000000..48cb2f76d58 --- /dev/null +++ b/test/langtools/tools/javac/processing/model/util/elements/TestRecordPredicates.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2022, 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 8289249 + * @summary Test Elements.{isCompactConstructor, isCanonicalConstructor} + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor TestRecordPredicates + * @compile -processor TestRecordPredicates -proc:only TestRecordPredicates.java + */ + +import java.lang.annotation.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import static javax.lang.model.SourceVersion.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; + +/** + * Test Elements.{isCompactConstructor, isCanonicalConstructor}. + */ +public class TestRecordPredicates extends JavacTestingAbstractProcessor { + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + // Test null handling + Elements vacuousElements = new VacuousElements(); + expectFalse( () -> vacuousElements.isCompactConstructor(null)); + expectFalse( () -> vacuousElements.isCanonicalConstructor(null)); + + expectNpe( () -> elements.isCompactConstructor(null)); + expectNpe( () -> elements.isCanonicalConstructor(null)); + + for (var typeElt : + ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(ExpectedPredicates.class))) { + ExpectedPredicates ep = typeElt.getAnnotation(ExpectedPredicates.class); + for (ExecutableElement ctor : ElementFilter.constructorsIn(typeElt.getEnclosedElements())) { + boolean isCompact = elements.isCompactConstructor(ctor); + if (isCompact != ep.isCompact()) { + messager.printError("Unexpected isCompact value on ", ctor); + } + + boolean isCanonical = elements.isCanonicalConstructor(ctor); + if (isCanonical != ep.isCanonical()) { + messager.printError("Unexpected isCanonical value on ", ctor); + } + + if (isCompact && !isCanonical) { + messager.printError("Compact constructors not reported as canonical ", ctor); + } + } + } + } + return true; + } + + private void expectNpe(java.util.function.BooleanSupplier bs) { + try { + bs.getAsBoolean(); + messager.printError("Did not get expected NPE"); + } catch (NullPointerException npe) { + ; // Expected + } + } + + private void expectFalse(java.util.function.BooleanSupplier bs) { + try { + boolean result = bs.getAsBoolean(); + if (result) { + messager.printError("Unexpected true result"); + } + } catch (NullPointerException npe) { + messager.printError("Unexpected NPE thrown"); + } + } + + + /** + * Annotation the class, not just constructor, since many of the + * constructors that are of interest are implicitly declared. + */ + @Retention(RetentionPolicy.RUNTIME) + @interface ExpectedPredicates { + boolean isCompact() default false; + boolean isCanonical() default false; + } + + @ExpectedPredicates(isCompact=true, isCanonical=true) + record RecordCompactCtor(int foo, double bar) {} + + // Example from JLS 8.10.4.2 + @ExpectedPredicates(isCompact=true, isCanonical=true) + record Rational(int num, int denom) { + private static int gcd(int a, int b) { + if (b == 0) return Math.abs(a); + else return gcd(b, a % b); + } + + // Compact ctor + Rational { + int gcd = gcd(num, denom); + num /= gcd; + denom /= gcd; + } + } + + // Example from JLS 8.10.4.2 + @ExpectedPredicates(isCanonical=true) + record RationalAlt(int num, int denom) { + private static int gcd(int a, int b) { + if (b == 0) return Math.abs(a); + else return gcd(b, a % b); + } + + // Non-compact ctor + RationalAlt(int num, int denom) { + int gcd = gcd(num, denom); + num /= gcd; + denom /= gcd; + this.num = num; + this.denom = denom; + } + } + + // Only constructors on records can be compact or canonical. + @ExpectedPredicates + enum MetaSyntax { + FOO, + BAR; + } + + @ExpectedPredicates + class NestedClass { + // A default constructor is neither compact nor canonical. + } + + @ExpectedPredicates + static class StaticNestedClass { + // A default constructor is neither compact nor canonical. + } + + @ExpectedPredicates + static class AnotherNestedClass { + // Non-default constructor + public AnotherNestedClass() {} + } +} diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index e9a40794cd5..754a1328026 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -82,9 +82,6 @@ public class EventNames { public final static String OldObjectSample = PREFIX + "OldObjectSample"; public final static String SymbolTableStatistics = PREFIX + "SymbolTableStatistics"; public final static String StringTableStatistics = PREFIX + "StringTableStatistics"; - public final static String PlaceholderTableStatistics = PREFIX + "PlaceholderTableStatistics"; - public final static String LoaderConstraintsTableStatistics = PREFIX + "LoaderConstraintsTableStatistics"; - public final static String ProtectionDomainCacheTableStatistics = PREFIX + "ProtectionDomainCacheTableStatistics"; public static final String RedefineClasses = PREFIX + "RedefineClasses"; public static final String RetransformClasses = PREFIX + "RetransformClasses"; public static final String ClassRedefinition = PREFIX + "ClassRedefinition"; diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java b/test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java index 25323962bbe..2cc422191ef 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,13 +24,16 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OperationsPerInvocation; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.TimeUnit; @@ -42,6 +45,9 @@ import java.util.concurrent.atomic.AtomicReference; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class Atomic { public AtomicInteger aInteger; diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java b/test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java index 43e08d97b6f..48bf505691c 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,11 +24,14 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -43,6 +46,9 @@ import java.util.function.IntUnaryOperator; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class AtomicIntegerUpdateAndGet { private PaddedAtomicInteger count; diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java index 6669b955b3c..d8641235af2 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +23,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; @@ -43,6 +46,9 @@ import java.util.concurrent.TimeUnit; */ @OutputTimeUnit(TimeUnit.MINUTES) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 2) +@Measurement(iterations = 5, time = 2) +@Fork(3) public class ForkJoinPoolForking { /** @@ -56,58 +62,63 @@ public class ForkJoinPoolForking { * FJP could be faster than baseline, because the baseline is single-threaded. */ - @Param("0") - private int workers; - @Param("10000000") private int size; - @Param("10") - private int threshold; + /** Encapsulate all the state depended on only by actual test. This avoids running baselines for every parameter value. */ + @State(Scope.Benchmark) + public static class TestState { + @Param("0") + private int workers; + + @Param({"1", "2", "3", "4", "5", "6", "7", "8"}) + private int threshold; + + private ForkJoinPool fjpSync; + private ForkJoinPool fjpAsync; + + @Setup + public void setup() { + if (workers == 0) { + workers = Runtime.getRuntime().availableProcessors(); + } + fjpSync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false); + fjpAsync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); + } + + + @TearDown + public void teardown() { + fjpSync.shutdownNow(); + fjpAsync.shutdownNow(); + } + } private Problem problem; - private ForkJoinPool fjpSync; - private ForkJoinPool fjpAsync; @Setup public void setup() { problem = new Problem(size); - if (workers == 0) { - workers = Runtime.getRuntime().availableProcessors(); - } - fjpSync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false); - fjpAsync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); - } - - @TearDown - public void teardown() { - fjpSync.shutdownNow(); - fjpAsync.shutdownNow(); } @Benchmark - public long baselineRaw() { - return problem.solve(); + public Long testExplicit_Sync(TestState state) throws ExecutionException, InterruptedException { + return state.fjpSync.invoke(new ExplicitTask(problem, 0, problem.size(), state.threshold)); } @Benchmark - public Long testExplicit_Sync() throws ExecutionException, InterruptedException { - return fjpSync.invoke(new ExplicitTask(problem, 0, problem.size(), threshold)); + public Long testExplicit_Async(TestState state) throws ExecutionException, InterruptedException { + return state.fjpAsync.invoke(new ExplicitTask(problem, 0, problem.size(), state.threshold)); } @Benchmark - public Long testExplicit_Async() throws ExecutionException, InterruptedException { - return fjpAsync.invoke(new ExplicitTask(problem, 0, problem.size(), threshold)); + public Long testStandard_Sync(TestState state) throws ExecutionException, InterruptedException { + return state.fjpSync.invoke(new StandardTask(problem, 0, problem.size(), state.threshold)); } @Benchmark - public Long testStandard_Sync() throws ExecutionException, InterruptedException { - return fjpSync.invoke(new StandardTask(problem, 0, problem.size(), threshold)); - } - - @Benchmark - public Long testStandard_Async() throws ExecutionException, InterruptedException { - return fjpAsync.invoke(new StandardTask(problem, 0, problem.size(), threshold)); + public Long testStandard_Async(TestState state) throws ExecutionException, InterruptedException { + return state.fjpAsync.invoke(new StandardTask(problem, 0, problem.size(), state.threshold)); } private static class ExplicitTask extends RecursiveTask { @@ -173,6 +184,4 @@ public class ForkJoinPoolForking { return res; } } - - } diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java index 1a77d46680e..b97e63d4f40 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +23,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; import java.util.ArrayList; import java.util.List; @@ -48,6 +51,9 @@ import java.util.concurrent.TimeUnit; */ @OutputTimeUnit(TimeUnit.SECONDS) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 2) +@Measurement(iterations = 5, time = 2) +@Fork(3) public class ForkJoinPoolRawCallable { /** diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java index 79a3d6f2ac0..726247405a5 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +23,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; @@ -41,6 +44,9 @@ import java.util.concurrent.TimeUnit; */ @OutputTimeUnit(TimeUnit.MINUTES) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 2) +@Measurement(iterations = 5, time = 2) +@Fork(3) public class ForkJoinPoolThresholdAutoQueued { /** @@ -54,31 +60,40 @@ public class ForkJoinPoolThresholdAutoQueued { * versus sequential version. */ - @Param("0") - private int workers; - @Param("10000000") private int size; - @Param({"1", "2", "3", "4", "5", "6", "7", "8"}) - private int threshold; + /** Encapsulate all the state depended on only by actual test. This avoids running baselines for every parameter value. */ + @State(Scope.Benchmark) + public static class TestState { + + @Param("0") + private int workers; + + @Param({"1", "2", "3", "4", "5", "6", "7", "8"}) + private int threshold; + + private ForkJoinPool fjp; + + @Setup + public void setup() { + if (workers == 0) { + workers = Runtime.getRuntime().availableProcessors(); + } + fjp = new ForkJoinPool(workers); + } + + @TearDown + public void teardown() { + fjp.shutdownNow(); + } + } - private ForkJoinPool fjp; private Problem problem; @Setup public void setup() { - if (workers == 0) { - workers = Runtime.getRuntime().availableProcessors(); - } - problem = new Problem(size); - fjp = new ForkJoinPool(workers); - } - - @TearDown - public void teardown() { - fjp.shutdownNow(); } @Benchmark @@ -87,8 +102,8 @@ public class ForkJoinPoolThresholdAutoQueued { } @Benchmark - public Long test() throws ExecutionException, InterruptedException { - return fjp.invoke(new AutoQueuedTask(threshold, problem, 0, problem.size())); + public Long test(TestState state) throws ExecutionException, InterruptedException { + return state.fjp.invoke(new AutoQueuedTask(state.threshold, problem, 0, problem.size())); } private static class AutoQueuedTask extends RecursiveTask { diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java index 1985c4500f7..e4c243a2ca0 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +23,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; @@ -41,6 +44,9 @@ import java.util.concurrent.TimeUnit; */ @OutputTimeUnit(TimeUnit.MINUTES) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 2) +@Measurement(iterations = 5, time = 2) +@Fork(3) public class ForkJoinPoolThresholdAutoSurplus { /** @@ -54,31 +60,40 @@ public class ForkJoinPoolThresholdAutoSurplus { * versus sequential version. */ - @Param("0") - private int workers; - @Param("10000000") private int size; - @Param({"1", "2", "3", "4", "5", "6", "7", "8"}) - private int threshold; + /** Encapsulate all the state depended on only by actual test. This avoids running baselines for every parameter value. */ + @State(Scope.Benchmark) + public static class TestState { + + @Param("0") + private int workers; + + @Param({"1", "2", "3", "4", "5", "6", "7", "8"}) + private int threshold; + + private ForkJoinPool fjp; + + @Setup + public void setup() { + if (workers == 0) { + workers = Runtime.getRuntime().availableProcessors(); + } + fjp = new ForkJoinPool(workers); + } + + @TearDown + public void teardown() { + fjp.shutdownNow(); + } + } - private ForkJoinPool fjp; private Problem problem; @Setup public void setup() { - if (workers == 0) { - workers = Runtime.getRuntime().availableProcessors(); - } - problem = new Problem(size); - fjp = new ForkJoinPool(workers); - } - - @TearDown - public void teardown() { - fjp.shutdownNow(); } @Benchmark @@ -87,8 +102,8 @@ public class ForkJoinPoolThresholdAutoSurplus { } @Benchmark - public Long test() throws ExecutionException, InterruptedException { - return fjp.invoke(new AutoQueuedTask(threshold, problem, 0, problem.size())); + public Long test(TestState state) throws ExecutionException, InterruptedException { + return state.fjp.invoke(new AutoQueuedTask(state.threshold, problem, 0, problem.size())); } private static class AutoQueuedTask extends RecursiveTask { @@ -122,7 +137,4 @@ public class ForkJoinPoolThresholdAutoSurplus { return res; } } - - - } diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java index 898550f5725..137e50c1108 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +23,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; @@ -41,6 +44,9 @@ import java.util.concurrent.TimeUnit; */ @OutputTimeUnit(TimeUnit.MINUTES) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 2) +@Measurement(iterations = 5, time = 2) +@Fork(3) public class ForkJoinPoolThresholdStatic { /** @@ -56,31 +62,40 @@ public class ForkJoinPoolThresholdStatic { * versus sequential version. */ - @Param("0") - private int workers; - @Param("10000000") private int size; - @Param({"1", "5", "10", "50", "100", "500", "1000", "5000", "10000", "50000", "100000", "500000", "1000000", "5000000", "10000000"}) - private int threshold; + /** Encapsulate all the state depended on only by actual test. This avoids running baselines for every parameter value. */ + @State(Scope.Benchmark) + public static class TestState { + + @Param("0") + private int workers; + + @Param({"1", "5", "10", "100", "1000", "10000", "100000", "1000000", "10000000"}) + private int threshold; + + private ForkJoinPool fjp; + + @Setup + public void setup() { + if (workers == 0) { + workers = Runtime.getRuntime().availableProcessors(); + } + fjp = new ForkJoinPool(workers); + } + + @TearDown + public void teardown() { + fjp.shutdownNow(); + } + } - private ForkJoinPool fjp; private Problem problem; @Setup public void setup() { - if (workers == 0) { - workers = Runtime.getRuntime().availableProcessors(); - } - problem = new Problem(size); - fjp = new ForkJoinPool(workers); - } - - @TearDown - public void teardown() { - fjp.shutdownNow(); } @Benchmark @@ -89,8 +104,8 @@ public class ForkJoinPoolThresholdStatic { } @Benchmark - public Long test() throws ExecutionException, InterruptedException { - return fjp.invoke(new AdjustableThreshTask(threshold, problem, 0, problem.size())); + public Long test(TestState state) throws ExecutionException, InterruptedException { + return state.fjp.invoke(new AdjustableThreshTask(state.threshold, problem, 0, problem.size())); } private static class AdjustableThreshTask extends RecursiveTask { diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/Locks.java b/test/micro/org/openjdk/bench/java/util/concurrent/Locks.java index cc089047588..72aa6f9b155 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/Locks.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/Locks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,11 +24,14 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.io.IOException; @@ -44,6 +47,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class Locks { private ReentrantLock reentrantLock; diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java index cc7dac9cdc7..283606f53ef 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +24,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -39,6 +42,9 @@ import java.util.concurrent.atomic.AtomicLong; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class Maps { private SimpleRandom rng; private Map map; diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java b/test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java index 9505760dd52..ddf3f69c83d 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,8 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; @@ -31,6 +33,7 @@ import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.ArrayBlockingQueue; @@ -47,6 +50,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class ProducerConsumer { @Param("100") diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/Queues.java b/test/micro/org/openjdk/bench/java/util/concurrent/Queues.java index 9c324ad1fca..533754419bc 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/Queues.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/Queues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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,12 +24,15 @@ package org.openjdk.bench.java.util.concurrent; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.ArrayBlockingQueue; @@ -41,6 +44,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class Queues { @Param("100") diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java b/test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java index d3c733d3471..5aaae923947 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(3) public class ThreadLocalRandomNextInt { @State(Scope.Benchmark) diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java new file mode 100644 index 00000000000..9f717908569 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.concurrent.TimeUnit; +import jdk.incubator.vector.DoubleVector; +import jdk.incubator.vector.FloatVector; +import jdk.incubator.vector.IntVector; +import jdk.incubator.vector.LongVector; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Fork(1) +public class SpiltReplicate { + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public long broadcastInt() { + var species = IntVector.SPECIES_PREFERRED; + var sum = IntVector.zero(species); + return sum.add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .reinterpretAsLongs() + .lane(0); + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public long broadcastLong() { + var species = LongVector.SPECIES_PREFERRED; + var sum = LongVector.zero(species); + return sum.add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .reinterpretAsLongs() + .lane(0); + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public long broadcastFloat() { + var species = FloatVector.SPECIES_PREFERRED; + var sum = FloatVector.zero(species); + return sum.add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .reinterpretAsLongs() + .lane(0); + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public long broadcastDouble() { + var species = DoubleVector.SPECIES_PREFERRED; + var sum = DoubleVector.zero(species); + return sum.add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .add(1).add(2).add(3).add(4).add(5).add(6).add(7).add(8) + .add(9).add(10).add(11).add(12).add(13).add(14).add(15).add(16) + .add(17).add(18).add(19).add(20).add(21).add(22).add(23).add(24) + .add(25).add(26).add(27).add(28).add(29).add(30).add(31).add(32) + .reinterpretAsLongs() + .lane(0); + } + + @Benchmark + public void testInt() { + broadcastInt(); + } + + @Benchmark + public void testLong() { + broadcastLong(); + } + + @Benchmark + public void testFloat() { + broadcastFloat(); + } + + @Benchmark + public void testDouble() { + broadcastDouble(); + } +} \ No newline at end of file diff --git a/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java b/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java index 057a1dc6104..0075edc5fd6 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java +++ b/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java @@ -46,8 +46,8 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) -@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @Fork(value = 3) public class AddIdealNotXPlusC { diff --git a/test/micro/org/openjdk/bench/vm/compiler/ArrayAllocation.java b/test/micro/org/openjdk/bench/vm/compiler/ArrayAllocation.java index 03a6eb198c6..324e2d1703d 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ArrayAllocation.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayAllocation.java @@ -26,28 +26,30 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) - +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class ArrayAllocation { @Param("128") private int size; - @Fork(value = 1, warmups = 1) @Benchmark public int eliminateArrayConstLength() { byte z[] = new byte[128]; return z.length; } - @Fork(value = 1, warmups = 1) @Benchmark public int eliminateArrayVarLength() { byte z[] = new byte[size]; diff --git a/test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java b/test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java index 86b55181e30..bdbb34c9c5c 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -38,6 +41,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class ArrayBoundCheckRemoval { private int[] a; diff --git a/test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java b/test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java index 08153c9e6bd..6fedc343156 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java @@ -24,18 +24,24 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class ArrayClear { @Param("100000") diff --git a/test/micro/org/openjdk/bench/vm/compiler/ArrayFill.java b/test/micro/org/openjdk/bench/vm/compiler/ArrayFill.java index 872732fbe52..08f0f65b3b8 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ArrayFill.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayFill.java @@ -26,12 +26,15 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; import java.util.Arrays; @@ -39,6 +42,9 @@ import java.util.Arrays; @State(Scope.Benchmark) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class ArrayFill { @Param("65536") private int size; diff --git a/test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java b/test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java index 000499b6ccc..514456384c5 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java @@ -24,12 +24,15 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.Stack; import java.util.Vector; diff --git a/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java b/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java index 9155bfbd3de..a2a4654b40a 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java +++ b/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java @@ -27,12 +27,12 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.*; import java.util.concurrent.TimeUnit; -@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) @State(Scope.Thread) -@Fork(value=1) +@Fork(value=2) public class AutoVectorization2DArray { @Param({"16", "32", "64"}) private int LEN; diff --git a/test/micro/org/openjdk/bench/vm/compiler/BitSetAndReset.java b/test/micro/org/openjdk/bench/vm/compiler/BitSetAndReset.java index 9fcb42e9bf9..98ebd559e3c 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/BitSetAndReset.java +++ b/test/micro/org/openjdk/bench/vm/compiler/BitSetAndReset.java @@ -30,6 +30,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class BitSetAndReset { private static final int COUNT = 10_000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/BitTest.java b/test/micro/org/openjdk/bench/vm/compiler/BitTest.java index 35669cd0ffa..a5f55b49cd0 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/BitTest.java +++ b/test/micro/org/openjdk/bench/vm/compiler/BitTest.java @@ -24,14 +24,20 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class BitTest { private static final int COUNT = 1000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/ClearMemory.java b/test/micro/org/openjdk/bench/vm/compiler/ClearMemory.java index 5a3f7a3581d..f70b4aa734a 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ClearMemory.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ClearMemory.java @@ -24,22 +24,26 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.TimeUnit; -@Fork(jvmArgsPrepend = {"-XX:-EliminateAllocations", "-XX:-DoEscapeAnalysis"}) +@Fork(value = 3, jvmArgsPrepend = {"-XX:-EliminateAllocations", "-XX:-DoEscapeAnalysis"}) @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) public class ClearMemory { class Payload8 { public long f0; diff --git a/test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java b/test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java index 266a60f9c1d..bf7613bbfe1 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java +++ b/test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -39,6 +42,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class CopyLoop { private MyString s; diff --git a/test/micro/org/openjdk/bench/vm/compiler/DivRem.java b/test/micro/org/openjdk/bench/vm/compiler/DivRem.java index 9e9b8e38110..4f34b2ba4b7 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/DivRem.java +++ b/test/micro/org/openjdk/bench/vm/compiler/DivRem.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -39,6 +42,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class DivRem { private static final int ARRAYSIZE = 500; diff --git a/test/micro/org/openjdk/bench/vm/compiler/Explosion.java b/test/micro/org/openjdk/bench/vm/compiler/Explosion.java index 20d5577c775..99eece79f47 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/Explosion.java +++ b/test/micro/org/openjdk/bench/vm/compiler/Explosion.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.Enumeration; @@ -41,6 +44,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class Explosion { @Param("5") diff --git a/test/micro/org/openjdk/bench/vm/compiler/FloatingScalarVectorAbsDiff.java b/test/micro/org/openjdk/bench/vm/compiler/FloatingScalarVectorAbsDiff.java index ffae1ad8025..b1491ca2175 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/FloatingScalarVectorAbsDiff.java +++ b/test/micro/org/openjdk/bench/vm/compiler/FloatingScalarVectorAbsDiff.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class FloatingScalarVectorAbsDiff { @Param({"1024"}) public int count; diff --git a/test/micro/org/openjdk/bench/vm/compiler/FpMinMaxIntrinsics.java b/test/micro/org/openjdk/bench/vm/compiler/FpMinMaxIntrinsics.java index b1f8cc0fc03..e4c3330dc9e 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/FpMinMaxIntrinsics.java +++ b/test/micro/org/openjdk/bench/vm/compiler/FpMinMaxIntrinsics.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class FpMinMaxIntrinsics { private static final int COUNT = 1000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/IndexVector.java b/test/micro/org/openjdk/bench/vm/compiler/IndexVector.java index 759ebaf17c6..5b7a4b75a66 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/IndexVector.java +++ b/test/micro/org/openjdk/bench/vm/compiler/IndexVector.java @@ -24,10 +24,14 @@ package org.openjdk.bench.vm.compiler; import java.util.Random; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.*; @State(Scope.Benchmark) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class IndexVector { @Param({"65536"}) private int count; diff --git a/test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java b/test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java index 359e929d356..a5cd89b47aa 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java +++ b/test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java @@ -24,17 +24,23 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class InnerClassNullRef { class Pickles { diff --git a/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java b/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java index bbecd3d3b23..59920591f67 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java +++ b/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.TimeUnit; @@ -36,6 +39,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class InterfaceCalls { interface AnInterface { diff --git a/test/micro/org/openjdk/bench/vm/compiler/InterfacePrivateCalls.java b/test/micro/org/openjdk/bench/vm/compiler/InterfacePrivateCalls.java index 620b885db36..7ccc91901de 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/InterfacePrivateCalls.java +++ b/test/micro/org/openjdk/bench/vm/compiler/InterfacePrivateCalls.java @@ -32,10 +32,13 @@ import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @State(Scope.Benchmark) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) public class InterfacePrivateCalls { interface I { private int bar() { return 0; } @@ -61,7 +64,7 @@ public class InterfacePrivateCalls { @Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Fork(value=1, jvmArgsAppend={"-XX:TieredStopAtLevel=1"}) + @Fork(value=3, jvmArgsAppend={"-XX:TieredStopAtLevel=1"}) public void invokePrivateInterfaceMethodC1() { for (int i = 0; i < objs.length; ++i) { objs[i].foo(); @@ -71,7 +74,7 @@ public class InterfacePrivateCalls { @Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Fork(value=1) + @Fork(value=3) public void invokePrivateInterfaceMethodC2() { for (int i = 0; i < objs.length; ++i) { objs[i].foo(); diff --git a/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java b/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java index 26e75f0e052..30c6c850ee5 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java +++ b/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java @@ -26,18 +26,21 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) -@Fork(1) - +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class IterativeEA { public static int ii = 1; diff --git a/test/micro/org/openjdk/bench/vm/compiler/LeaInstruction.java b/test/micro/org/openjdk/bench/vm/compiler/LeaInstruction.java index 02b10d7ddf7..00aee26e0bc 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/LeaInstruction.java +++ b/test/micro/org/openjdk/bench/vm/compiler/LeaInstruction.java @@ -29,7 +29,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 1, jvmArgsAppend = {"-XX:LoopUnrollLimit=1"}) +@Fork(value = 2, jvmArgsAppend = {"-XX:LoopUnrollLimit=1"}) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @State(Scope.Thread) public class LeaInstruction { static final int ITERATION = 1000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/LoopUnroll.java b/test/micro/org/openjdk/bench/vm/compiler/LoopUnroll.java index 84630e70b89..cbb216bbaa6 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/LoopUnroll.java +++ b/test/micro/org/openjdk/bench/vm/compiler/LoopUnroll.java @@ -27,14 +27,14 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.*; import java.util.concurrent.TimeUnit; -@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Warmup(iterations = 3, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) @State(Scope.Thread) -@Fork(value=1) +@Fork(value=3) public class LoopUnroll { - @Param({"16", "32", "64", "128", "256", "512", "1024"}) + @Param({"16", "32", /* "64", "128", "256", "512", */ "1024"}) private int VECLEN; private byte[][] a; diff --git a/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java b/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java index 40c3ba1b2ba..019504126d4 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class MacroLogicOpt { @Param({"64","128","256","512","1024"}) private int VECLEN; diff --git a/test/micro/org/openjdk/bench/vm/compiler/MaxMinOptimizeTest.java b/test/micro/org/openjdk/bench/vm/compiler/MaxMinOptimizeTest.java index ec83488464a..02df4652a39 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MaxMinOptimizeTest.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MaxMinOptimizeTest.java @@ -32,6 +32,9 @@ import org.openjdk.jmh.infra.Blackhole; @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.MICROSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class MaxMinOptimizeTest { private static final int COUNT = 100000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/ModPowerOf2.java b/test/micro/org/openjdk/bench/vm/compiler/ModPowerOf2.java index 879e777e679..14b65257ce4 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/ModPowerOf2.java +++ b/test/micro/org/openjdk/bench/vm/compiler/ModPowerOf2.java @@ -25,6 +25,8 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; @@ -40,6 +42,8 @@ import java.util.concurrent.TimeUnit; */ @BenchmarkMode(Mode.AverageTime) @Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) public class ModPowerOf2 { diff --git a/test/micro/org/openjdk/bench/vm/compiler/Multiplication.java b/test/micro/org/openjdk/bench/vm/compiler/Multiplication.java index 69c01faf6d8..495b1e8bbfa 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/Multiplication.java +++ b/test/micro/org/openjdk/bench/vm/compiler/Multiplication.java @@ -24,12 +24,15 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -39,6 +42,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class Multiplication { @Param("500") diff --git a/test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java b/test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java index 2ac98a07cf5..16f11230ce6 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java +++ b/test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java @@ -24,8 +24,11 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -34,6 +37,9 @@ import java.util.concurrent.TimeUnit; */ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class PostAllocationStores { /** Tests allocation with explicit stores of null/zero to all fields. */ diff --git a/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java b/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java index e84ca35ab27..bb26a379fd4 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java +++ b/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java @@ -24,15 +24,21 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.OutputTimeUnit; -import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class SharedLoopHeader { private static final int size = 1000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/Signum.java b/test/micro/org/openjdk/bench/vm/compiler/Signum.java index 65292814521..0679c32881b 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/Signum.java +++ b/test/micro/org/openjdk/bench/vm/compiler/Signum.java @@ -40,9 +40,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) -@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) -@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) -@Fork(3) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class Signum { private final int ITERATIONS = 15000; diff --git a/test/micro/org/openjdk/bench/vm/compiler/SpillCode.java b/test/micro/org/openjdk/bench/vm/compiler/SpillCode.java index ed935a0215f..ac950868e51 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/SpillCode.java +++ b/test/micro/org/openjdk/bench/vm/compiler/SpillCode.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -38,6 +41,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class SpillCode { @Param("10") diff --git a/test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java b/test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java index 1b473ddf5fd..46eb6129f50 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java +++ b/test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java @@ -24,10 +24,13 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -38,6 +41,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class StoreAfterStore { public int s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8; diff --git a/test/micro/org/openjdk/bench/vm/compiler/Straighten.java b/test/micro/org/openjdk/bench/vm/compiler/Straighten.java index 9d48a70fae3..a145978a242 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/Straighten.java +++ b/test/micro/org/openjdk/bench/vm/compiler/Straighten.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -39,6 +42,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class Straighten { private int[] intArr; diff --git a/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java b/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java index 4763c59629c..75306d80379 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java +++ b/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java @@ -25,17 +25,23 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; import java.nio.charset.StandardCharsets; @State(Scope.Thread) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class StringConstructorBenchmark { private byte[] array; private String str; diff --git a/test/micro/org/openjdk/bench/vm/compiler/TypeVectorOperations.java b/test/micro/org/openjdk/bench/vm/compiler/TypeVectorOperations.java index 5733b6092b5..93ae6039709 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/TypeVectorOperations.java +++ b/test/micro/org/openjdk/bench/vm/compiler/TypeVectorOperations.java @@ -31,8 +31,11 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public abstract class TypeVectorOperations { - @Param({"512","1024", "2048"}) + @Param({"512", /* "1024", */ "2048"}) public int COUNT; private byte[] bytesA; @@ -363,14 +366,14 @@ public abstract class TypeVectorOperations { } } - @Fork(value = 1, jvmArgsPrepend = { + @Fork(value = 2, jvmArgsPrepend = { "-XX:+UseSuperWord" }) public static class TypeVectorOperationsSuperWord extends TypeVectorOperations { } - @Fork(value = 1, jvmArgsPrepend = { + @Fork(value = 2, jvmArgsPrepend = { "-XX:-UseSuperWord" }) public static class TypeVectorOperationsNonSuperWord extends TypeVectorOperations { diff --git a/test/micro/org/openjdk/bench/vm/compiler/UnsignedComparison.java b/test/micro/org/openjdk/bench/vm/compiler/UnsignedComparison.java index a82e1d87c63..43cf3ab975d 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/UnsignedComparison.java +++ b/test/micro/org/openjdk/bench/vm/compiler/UnsignedComparison.java @@ -26,16 +26,20 @@ import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @Fork(2) @State(Scope.Thread) public class UnsignedComparison { diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java b/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java index e16cf422a9d..49b644a64f1 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java @@ -31,6 +31,8 @@ import java.util.random.RandomGeneratorFactory; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) public abstract class VectorBitCount { @Param({"1024"}) public int SIZE; @@ -70,14 +72,14 @@ public abstract class VectorBitCount { } - @Fork(value = 1, jvmArgsPrepend = { + @Fork(value = 2, jvmArgsPrepend = { "-XX:+UseSuperWord" }) public static class WithSuperword extends VectorBitCount { } - @Fork(value = 1, jvmArgsPrepend = { + @Fork(value = 2, jvmArgsPrepend = { "-XX:-UseSuperWord" }) public static class NoSuperword extends VectorBitCount { diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorIntMinMax.java b/test/micro/org/openjdk/bench/vm/compiler/VectorIntMinMax.java index 13754ec3cb1..7419bb0ce9b 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/VectorIntMinMax.java +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorIntMinMax.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class VectorIntMinMax { @Param({"2048"}) private int LENGTH; diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorReduction.java b/test/micro/org/openjdk/bench/vm/compiler/VectorReduction.java index 49e40726892..cc853ae471b 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/VectorReduction.java +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorReduction.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public abstract class VectorReduction { @Param({"512"}) public int COUNT; @@ -119,14 +122,14 @@ public abstract class VectorReduction { } } - @Fork(value = 1, jvmArgsPrepend = { + @Fork(value = 2, jvmArgsPrepend = { "-XX:+UseSuperWord" }) public static class WithSuperword extends VectorReduction { } - @Fork(value = 1, jvmArgsPrepend = { + @Fork(value = 2, jvmArgsPrepend = { "-XX:-UseSuperWord" }) public static class NoSuperword extends VectorReduction { diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorReductionFloatingMinMax.java b/test/micro/org/openjdk/bench/vm/compiler/VectorReductionFloatingMinMax.java index 9c957a807db..d25d22f12b1 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/VectorReductionFloatingMinMax.java +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorReductionFloatingMinMax.java @@ -32,6 +32,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class VectorReductionFloatingMinMax { @Param({"512"}) public int COUNT_DOUBLE; diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorShiftAccumulate.java b/test/micro/org/openjdk/bench/vm/compiler/VectorShiftAccumulate.java index e655209e714..a3998b27ce1 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/VectorShiftAccumulate.java +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorShiftAccumulate.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class VectorShiftAccumulate { @Param({"1028"}) public int count; diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorShiftRight.java b/test/micro/org/openjdk/bench/vm/compiler/VectorShiftRight.java index 1edfb50bd5b..0171ee27756 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/VectorShiftRight.java +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorShiftRight.java @@ -31,6 +31,9 @@ import java.util.Random; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class VectorShiftRight { @Param({"1024"}) public int SIZE; diff --git a/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java b/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java index f464ce8f5c0..686706b46c4 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java +++ b/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java @@ -24,11 +24,14 @@ package org.openjdk.bench.vm.compiler; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -36,6 +39,9 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) public class WriteBarrier { // For array references