From 4f071ce074b934d5610e213d348cff8326f1499d Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Sat, 31 Aug 2024 01:13:07 +0000 Subject: [PATCH 01/29] 8311163: Parallel: Improve large object handling during evacuation Reviewed-by: tschatzl, ayang --- .../share/gc/parallel/psPromotionManager.cpp | 94 +++++++++++++------ .../share/gc/parallel/psPromotionManager.hpp | 12 ++- .../gc/parallel/psPromotionManager.inline.hpp | 12 +-- .../share/gc/shared/partialArrayState.hpp | 3 +- src/hotspot/share/gc/shared/taskqueue.hpp | 28 ------ 5 files changed, 82 insertions(+), 67 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index 19f688852385b..5f6629e6cc2c4 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "gc/parallel/psScavenge.inline.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" #include "gc/shared/gcTrace.hpp" +#include "gc/shared/partialArrayState.hpp" +#include "gc/shared/partialArrayTaskStepper.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/taskqueue.inline.hpp" #include "logging/log.hpp" @@ -42,12 +44,14 @@ #include "memory/resourceArea.hpp" #include "oops/access.inline.hpp" #include "oops/compressedOops.inline.hpp" +#include "utilities/checkedCast.hpp" PaddedEnd* PSPromotionManager::_manager_array = nullptr; PSPromotionManager::PSScannerTasksQueueSet* PSPromotionManager::_stack_array_depth = nullptr; PreservedMarksSet* PSPromotionManager::_preserved_marks_set = nullptr; PSOldGen* PSPromotionManager::_old_gen = nullptr; MutableSpace* PSPromotionManager::_young_space = nullptr; +PartialArrayStateAllocator* PSPromotionManager::_partial_array_state_allocator = nullptr; void PSPromotionManager::initialize() { ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); @@ -62,11 +66,16 @@ void PSPromotionManager::initialize() { assert(_manager_array == nullptr, "Attempt to initialize twice"); _manager_array = PaddedArray::create_unfreeable(promotion_manager_num); + assert(_partial_array_state_allocator == nullptr, "Attempt to initialize twice"); + _partial_array_state_allocator + = new PartialArrayStateAllocator(ParallelGCThreads); + _stack_array_depth = new PSScannerTasksQueueSet(ParallelGCThreads); // Create and register the PSPromotionManager(s) for the worker threads. for(uint i=0; iregister_queue(i, _manager_array[i].claimed_stack_depth()); + _manager_array[i]._partial_array_state_allocator_index = i; } // The VMThread gets its own PSPromotionManager, which is not available // for work stealing. @@ -124,6 +133,10 @@ bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { manager->flush_labs(); manager->flush_string_dedup_requests(); } + // All PartialArrayStates have been returned to the allocator, since the + // claimed_stack_depths are all empty. Leave them there for use by future + // collections. + if (!promotion_failure_occurred) { // If there was no promotion failure, the preserved mark stacks // should be empty. @@ -172,7 +185,10 @@ void PSPromotionManager::reset_stats() { } #endif // TASKQUEUE_STATS -PSPromotionManager::PSPromotionManager() { +// Most members are initialized either by initialize() or reset(). +PSPromotionManager::PSPromotionManager() + : _partial_array_stepper(ParallelGCThreads, ParGCArrayScanChunk) +{ // We set the old lab's start array. _old_lab.set_start_array(old_gen()->start_array()); @@ -182,9 +198,11 @@ PSPromotionManager::PSPromotionManager() { _target_stack_size = GCDrainStackTargetSize; } - _array_chunk_size = ParGCArrayScanChunk; + // Initialize to a bad value; fixed by initialize(). + _partial_array_state_allocator_index = UINT_MAX; + // let's choose 1.5x the chunk size - _min_array_size_for_chunking = 3 * _array_chunk_size / 2; + _min_array_size_for_chunking = (3 * ParGCArrayScanChunk / 2); _preserved_marks = nullptr; @@ -277,37 +295,57 @@ template void PSPromotionManager::process_array_chunk_work( } } -void PSPromotionManager::process_array_chunk(PartialArrayScanTask task) { - assert(PSChunkLargeArrays, "invariant"); - - oop old = task.to_source_array(); - assert(old->is_objArray(), "invariant"); - assert(old->is_forwarded(), "invariant"); - +void PSPromotionManager::process_array_chunk(PartialArrayState* state) { TASKQUEUE_STATS_ONLY(++_array_chunks_processed); - oop const obj = old->forwardee(); - - int start; - int const end = arrayOop(old)->length(); - if (end > (int) _min_array_size_for_chunking) { - // we'll chunk more - start = end - _array_chunk_size; - assert(start > 0, "invariant"); - arrayOop(old)->set_length(start); - push_depth(ScannerTask(PartialArrayScanTask(old))); - TASKQUEUE_STATS_ONLY(++_array_chunk_pushes); + // Claim a chunk. Push additional tasks before processing the claimed + // chunk to allow other workers to steal while we're processing. + PartialArrayTaskStepper::Step step = _partial_array_stepper.next(state); + if (step._ncreate > 0) { + state->add_references(step._ncreate); + for (uint i = 0; i < step._ncreate; ++i) { + push_depth(ScannerTask(state)); + } + TASKQUEUE_STATS_ONLY(_array_chunk_pushes += step._ncreate); + } + int start = checked_cast(step._index); + int end = checked_cast(step._index + _partial_array_stepper.chunk_size()); + assert(start < end, "invariant"); + if (UseCompressedOops) { + process_array_chunk_work(state->destination(), start, end); } else { - // this is the final chunk for this array - start = 0; - int const actual_length = arrayOop(obj)->length(); - arrayOop(old)->set_length(actual_length); + process_array_chunk_work(state->destination(), start, end); } + // Release reference to state, now that we're done with it. + _partial_array_state_allocator->release(_partial_array_state_allocator_index, state); +} +void PSPromotionManager::push_objArray(oop old_obj, oop new_obj) { + assert(old_obj->is_objArray(), "precondition"); + assert(old_obj->is_forwarded(), "precondition"); + assert(old_obj->forwardee() == new_obj, "precondition"); + assert(new_obj->is_objArray(), "precondition"); + + size_t array_length = objArrayOop(new_obj)->length(); + PartialArrayTaskStepper::Step step = _partial_array_stepper.start(array_length); + + if (step._ncreate > 0) { + TASKQUEUE_STATS_ONLY(++_arrays_chunked); + PartialArrayState* state = + _partial_array_state_allocator->allocate(_partial_array_state_allocator_index, + old_obj, new_obj, + step._index, + array_length, + step._ncreate); + for (uint i = 0; i < step._ncreate; ++i) { + push_depth(ScannerTask(state)); + } + TASKQUEUE_STATS_ONLY(_array_chunk_pushes += step._ncreate); + } if (UseCompressedOops) { - process_array_chunk_work(obj, start, end); + process_array_chunk_work(new_obj, 0, checked_cast(step._index)); } else { - process_array_chunk_work(obj, start, end); + process_array_chunk_work(new_obj, 0, checked_cast(step._index)); } } diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.hpp index b7d2e0f725331..8d4122346147c 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "gc/parallel/psPromotionLAB.hpp" #include "gc/shared/copyFailedInfo.hpp" #include "gc/shared/gcTrace.hpp" +#include "gc/shared/partialArrayTaskStepper.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/taskqueue.hpp" @@ -49,6 +50,8 @@ class MutableSpace; class PSOldGen; class ParCompactionManager; +class PartialArrayState; +class PartialArrayStateAllocator; class PSPromotionManager { friend class PSScavenge; @@ -85,7 +88,9 @@ class PSPromotionManager { uint _target_stack_size; - uint _array_chunk_size; + static PartialArrayStateAllocator* _partial_array_state_allocator; + PartialArrayTaskStepper _partial_array_stepper; + uint _partial_array_state_allocator_index; uint _min_array_size_for_chunking; PreservedMarks* _preserved_marks; @@ -101,7 +106,8 @@ class PSPromotionManager { template void process_array_chunk_work(oop obj, int start, int end); - void process_array_chunk(PartialArrayScanTask task); + void process_array_chunk(PartialArrayState* state); + void push_objArray(oop old_obj, oop new_obj); void push_depth(ScannerTask task); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp index 390dea4976d19..f38cbaecf439c 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -276,9 +276,7 @@ inline oop PSPromotionManager::copy_unmarked_to_survivor_space(oop o, if (new_obj_size > _min_array_size_for_chunking && new_obj->is_objArray() && PSChunkLargeArrays) { - // we'll chunk it - push_depth(ScannerTask(PartialArrayScanTask(o))); - TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_array_chunk_pushes); + push_objArray(o, new_obj); } else { // we'll just push its contents push_contents(new_obj); @@ -322,9 +320,9 @@ inline void PSPromotionManager::copy_and_push_safe_barrier(T* p) { } inline void PSPromotionManager::process_popped_location_depth(ScannerTask task) { - if (task.is_partial_array_task()) { + if (task.is_partial_array_state()) { assert(PSChunkLargeArrays, "invariant"); - process_array_chunk(task.to_partial_array_task()); + process_array_chunk(task.to_partial_array_state()); } else { if (task.is_narrow_oop_ptr()) { assert(UseCompressedOops, "Error"); @@ -341,7 +339,7 @@ inline bool PSPromotionManager::steal_depth(int queue_num, ScannerTask& t) { #if TASKQUEUE_STATS void PSPromotionManager::record_steal(ScannerTask task) { - if (task.is_partial_array_task()) { + if (task.is_partial_array_state()) { ++_array_chunk_steals; } } diff --git a/src/hotspot/share/gc/shared/partialArrayState.hpp b/src/hotspot/share/gc/shared/partialArrayState.hpp index f3bfc3ed8b859..fb226e08665a0 100644 --- a/src/hotspot/share/gc/shared/partialArrayState.hpp +++ b/src/hotspot/share/gc/shared/partialArrayState.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_GC_SHARED_PARTIALARRAYSTATE_HPP #define SHARE_GC_SHARED_PARTIALARRAYSTATE_HPP +#include "memory/allocation.hpp" #include "oops/oopsHierarchy.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" @@ -109,7 +110,7 @@ class PartialArrayState { // the worker_id used in the operation. This avoids locking and such on those // data structures, at the cost of possibly doing more total arena allocation // that would be needed with a single shared arena and free-list. -class PartialArrayStateAllocator { +class PartialArrayStateAllocator : public CHeapObj { class Impl; Impl* _impl; diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index 2ea75e1457c48..f4a3731583bc9 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -573,20 +573,6 @@ class ObjArrayTask int _index; }; -// Wrapper over an oop that is a partially scanned array. -// Can be converted to a ScannerTask for placement in associated task queues. -// Refers to the partially copied source array oop. -// Temporarily retained to support ParallelGC until it adopts PartialArrayState. -class PartialArrayScanTask { - oop _src; - -public: - explicit PartialArrayScanTask(oop src_array) : _src(src_array) {} - // Trivially copyable. - - oop to_source_array() const { return _src; } -}; - class PartialArrayState; // Discriminated union over oop*, narrowOop*, and PartialArrayState. @@ -627,10 +613,6 @@ class ScannerTask { explicit ScannerTask(narrowOop* p) : _p(encode(p, NarrowOopTag)) {} - // Temporarily retained to support ParallelGC until it adopts PartialArrayState. - explicit ScannerTask(PartialArrayScanTask t) : - _p(encode(t.to_source_array(), PartialArrayTag)) {} - explicit ScannerTask(PartialArrayState* state) : _p(encode(state, PartialArrayTag)) {} @@ -646,11 +628,6 @@ class ScannerTask { return (raw_value() & NarrowOopTag) != 0; } - // Temporarily retained to support ParallelGC until it adopts PartialArrayState. - bool is_partial_array_task() const { - return (raw_value() & PartialArrayTag) != 0; - } - bool is_partial_array_state() const { return (raw_value() & PartialArrayTag) != 0; } @@ -663,11 +640,6 @@ class ScannerTask { return static_cast(decode(NarrowOopTag)); } - // Temporarily retained to support ParallelGC until it adopts PartialArrayState. - PartialArrayScanTask to_partial_array_task() const { - return PartialArrayScanTask(cast_to_oop(decode(PartialArrayTag))); - } - PartialArrayState* to_partial_array_state() const { return static_cast(decode(PartialArrayTag)); } From 392bdd5734e0ad4e616d52bb7bcafcf85dccbf34 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Sat, 31 Aug 2024 01:44:17 +0000 Subject: [PATCH 02/29] 8339248: RISC-V: Remove li64 macro assembler routine and related code Reviewed-by: rehn, fjiang, luhenry --- .../cpu/riscv/macroAssembler_riscv.cpp | 75 ------------------- .../cpu/riscv/macroAssembler_riscv.hpp | 36 --------- 2 files changed, 111 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index c5516336ebc00..ab4d89f2d7528 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -146,18 +146,6 @@ bool MacroAssembler::is_li32_at(address instr) { check_li32_data_dependency(instr); } -bool MacroAssembler::is_li64_at(address instr) { - return is_lui_at(instr) && // lui - is_addi_at(instr + instruction_size) && // addi - is_slli_shift_at(instr + instruction_size * 2, 12) && // Slli Rd, Rs, 12 - is_addi_at(instr + instruction_size * 3) && // addi - is_slli_shift_at(instr + instruction_size * 4, 12) && // Slli Rd, Rs, 12 - is_addi_at(instr + instruction_size * 5) && // addi - is_slli_shift_at(instr + instruction_size * 6, 8) && // Slli Rd, Rs, 8 - is_addi_at(instr + instruction_size * 7) && // addi - check_li64_data_dependency(instr); -} - bool MacroAssembler::is_lwu_to_zr(address instr) { assert_cond(instr != nullptr); return (extract_opcode(instr) == 0b0000011 && @@ -909,37 +897,9 @@ void MacroAssembler::li32(Register Rd, int32_t imm) { upper = (int32_t)upper; // lui Rd, imm[31:12] + imm[11] lui(Rd, upper); - // use addiw to distinguish li32 to li64 addiw(Rd, Rd, lower); } -void MacroAssembler::li64(Register Rd, int64_t imm) { - // Load upper 32 bits. upper = imm[63:32], but if imm[31] == 1 or - // (imm[31:20] == 0x7ff && imm[19] == 1), upper = imm[63:32] + 1. - int64_t lower = imm & 0xffffffff; - lower -= ((lower << 44) >> 44); - int64_t tmp_imm = ((uint64_t)(imm & 0xffffffff00000000)) + (uint64_t)lower; - int32_t upper = (tmp_imm - (int32_t)lower) >> 32; - - // Load upper 32 bits - int64_t up = upper, lo = upper; - lo = (lo << 52) >> 52; - up -= lo; - up = (int32_t)up; - lui(Rd, up); - addi(Rd, Rd, lo); - - // Load the rest 32 bits. - slli(Rd, Rd, 12); - addi(Rd, Rd, (int32_t)lower >> 20); - slli(Rd, Rd, 12); - lower = ((int32_t)imm << 12) >> 20; - addi(Rd, Rd, lower); - slli(Rd, Rd, 8); - lower = imm & 0xff; - addi(Rd, Rd, lower); -} - void MacroAssembler::li(Register Rd, int64_t imm) { // int64_t is in range 0x8000 0000 0000 0000 ~ 0x7fff ffff ffff ffff // li -> c.li @@ -1741,27 +1701,6 @@ static int patch_addr_in_movptr2(address instruction_address, address target) { return MacroAssembler::movptr2_instruction_size; } -static int patch_imm_in_li64(address branch, address target) { - const int LI64_INSTRUCTIONS_NUM = 8; // lui + addi + slli + addi + slli + addi + slli + addi - int64_t lower = (intptr_t)target & 0xffffffff; - lower = lower - ((lower << 44) >> 44); - int64_t tmp_imm = ((uint64_t)((intptr_t)target & 0xffffffff00000000)) + (uint64_t)lower; - int32_t upper = (tmp_imm - (int32_t)lower) >> 32; - int64_t tmp_upper = upper, tmp_lower = upper; - tmp_lower = (tmp_lower << 52) >> 52; - tmp_upper -= tmp_lower; - tmp_upper >>= 12; - // Load upper 32 bits. Upper = target[63:32], but if target[31] = 1 or (target[31:20] == 0x7ff && target[19] == 1), - // upper = target[63:32] + 1. - Assembler::patch(branch + 0, 31, 12, tmp_upper & 0xfffff); // Lui. - Assembler::patch(branch + 4, 31, 20, tmp_lower & 0xfff); // Addi. - // Load the rest 32 bits. - Assembler::patch(branch + 12, 31, 20, ((int32_t)lower >> 20) & 0xfff); // Addi. - Assembler::patch(branch + 20, 31, 20, (((intptr_t)target << 44) >> 52) & 0xfff); // Addi. - Assembler::patch(branch + 28, 31, 20, (intptr_t)target & 0xff); // Addi. - return LI64_INSTRUCTIONS_NUM * MacroAssembler::instruction_size; -} - static int patch_imm_in_li16u(address branch, uint16_t target) { Assembler::patch(branch, 31, 12, target); // patch lui only return MacroAssembler::instruction_size; @@ -1832,16 +1771,6 @@ static address get_target_of_movptr2(address insn_addr) { return ret; } -static address get_target_of_li64(address insn_addr) { - assert_cond(insn_addr != nullptr); - intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 44; // Lui. - target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)) << 32; // Addi. - target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 12), 31, 20)) << 20; // Addi. - target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 20), 31, 20)) << 8; // Addi. - target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 28), 31, 20)); // Addi. - return (address)target_address; -} - address MacroAssembler::get_target_of_li32(address insn_addr) { assert_cond(insn_addr != nullptr); intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 12; // Lui. @@ -1864,8 +1793,6 @@ int MacroAssembler::pd_patch_instruction_size(address instruction_address, addre return patch_addr_in_movptr1(instruction_address, target); } else if (MacroAssembler::is_movptr2_at(instruction_address)) { // movptr2 return patch_addr_in_movptr2(instruction_address, target); - } else if (MacroAssembler::is_li64_at(instruction_address)) { // li64 - return patch_imm_in_li64(instruction_address, target); } else if (MacroAssembler::is_li32_at(instruction_address)) { // li32 int64_t imm = (intptr_t)target; return patch_imm_in_li32(instruction_address, (int32_t)imm); @@ -1896,8 +1823,6 @@ address MacroAssembler::target_addr_for_insn(address insn_addr) { return get_target_of_movptr1(insn_addr); } else if (MacroAssembler::is_movptr2_at(insn_addr)) { // movptr2 return get_target_of_movptr2(insn_addr); - } else if (MacroAssembler::is_li64_at(insn_addr)) { // li64 - return get_target_of_li64(insn_addr); } else if (MacroAssembler::is_li32_at(insn_addr)) { // li32 return get_target_of_li32(insn_addr); } else { diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index b0404929f46d8..c3161beea117d 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -813,7 +813,6 @@ class MacroAssembler: public Assembler { void li16u(Register Rd, uint16_t imm); void li32(Register Rd, int32_t imm); - void li64(Register Rd, int64_t imm); void li (Register Rd, int64_t imm); // optimized load immediate // mv @@ -1706,40 +1705,6 @@ class MacroAssembler: public Assembler { extract_rs1(last_instr) == extract_rd(add); } - // the instruction sequence of li64 is as below: - // lui - // addi - // slli - // addi - // slli - // addi - // slli - // addi - static bool check_li64_data_dependency(address instr) { - address lui = instr; - address addi1 = lui + instruction_size; - address slli1 = addi1 + instruction_size; - address addi2 = slli1 + instruction_size; - address slli2 = addi2 + instruction_size; - address addi3 = slli2 + instruction_size; - address slli3 = addi3 + instruction_size; - address addi4 = slli3 + instruction_size; - return extract_rs1(addi1) == extract_rd(lui) && - extract_rs1(addi1) == extract_rd(addi1) && - extract_rs1(slli1) == extract_rd(addi1) && - extract_rs1(slli1) == extract_rd(slli1) && - extract_rs1(addi2) == extract_rd(slli1) && - extract_rs1(addi2) == extract_rd(addi2) && - extract_rs1(slli2) == extract_rd(addi2) && - extract_rs1(slli2) == extract_rd(slli2) && - extract_rs1(addi3) == extract_rd(slli2) && - extract_rs1(addi3) == extract_rd(addi3) && - extract_rs1(slli3) == extract_rd(addi3) && - extract_rs1(slli3) == extract_rd(slli3) && - extract_rs1(addi4) == extract_rd(slli3) && - extract_rs1(addi4) == extract_rd(addi4); - } - // the instruction sequence of li16u is as below: // lui // srli @@ -1784,7 +1749,6 @@ class MacroAssembler: public Assembler { } static bool is_li32_at(address instr); - static bool is_li64_at(address instr); static bool is_pc_relative_at(address branch); static bool is_membar(address addr) { From 92aafb43424321d8f2552aa34a9a3df291abf992 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Sun, 1 Sep 2024 16:13:53 +0000 Subject: [PATCH 03/29] 8338934: vmTestbase/nsk/jvmti/*Field*Watch/TestDescription.java tests timeout intermittently Reviewed-by: sspitsyn, amenkov --- src/hotspot/share/prims/jvmtiEnv.cpp | 4 ++++ src/hotspot/share/prims/jvmtiEventController.cpp | 2 -- src/hotspot/share/runtime/mutexLocker.cpp | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 63cc33222ec37..a36d12059a96a 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -2534,6 +2534,7 @@ JvmtiEnv::ClearBreakpoint(Method* method, jlocation location) { jvmtiError JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) { + JvmtiVTMSTransitionDisabler disabler; // make sure we haven't set this watch before if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE; fdesc_ptr->set_is_field_access_watched(true); @@ -2546,6 +2547,7 @@ JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) { jvmtiError JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) { + JvmtiVTMSTransitionDisabler disabler; // make sure we have a watch to clear if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND; fdesc_ptr->set_is_field_access_watched(false); @@ -2558,6 +2560,7 @@ JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) { jvmtiError JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) { + JvmtiVTMSTransitionDisabler disabler; // make sure we haven't set this watch before if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE; fdesc_ptr->set_is_field_modification_watched(true); @@ -2570,6 +2573,7 @@ JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) { jvmtiError JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) { + JvmtiVTMSTransitionDisabler disabler; // make sure we have a watch to clear if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND; fdesc_ptr->set_is_field_modification_watched(false); diff --git a/src/hotspot/share/prims/jvmtiEventController.cpp b/src/hotspot/share/prims/jvmtiEventController.cpp index c9867ff164350..df14047e70030 100644 --- a/src/hotspot/share/prims/jvmtiEventController.cpp +++ b/src/hotspot/share/prims/jvmtiEventController.cpp @@ -982,8 +982,6 @@ JvmtiEventControllerPrivate::change_field_watch(jvmtiEvent event_type, bool adde added? "add" : "remove", *count_addr)); - JvmtiVTMSTransitionDisabler disabler; - if (added) { (*count_addr)++; if (*count_addr == 1) { diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 8c1dff38051d9..f033f42624987 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -267,7 +267,7 @@ void mutex_init() { MUTEX_DEFN(CompileStatistics_lock , PaddedMutex , safepoint); MUTEX_DEFN(DirectivesStack_lock , PaddedMutex , nosafepoint); - MUTEX_DEFN(JvmtiThreadState_lock , PaddedMutex , safepoint); // Used by JvmtiThreadState/JvmtiEventController + MUTEX_DEFN(JvmtiVTMSTransition_lock , PaddedMonitor, safepoint); // used for Virtual Thread Mount State transition management MUTEX_DEFN(EscapeBarrier_lock , PaddedMonitor, nosafepoint); // Used to synchronize object reallocation/relocking triggered by JVMTI MUTEX_DEFN(Management_lock , PaddedMutex , safepoint); // used for JVM management @@ -354,7 +354,7 @@ void mutex_init() { // JVMCIRuntime_lock must be acquired before JVMCI_lock to avoid deadlock MUTEX_DEFL(JVMCI_lock , PaddedMonitor, JVMCIRuntime_lock); #endif - MUTEX_DEFL(JvmtiVTMSTransition_lock , PaddedMonitor, JvmtiThreadState_lock); // used for Virtual Thread Mount State transition management + MUTEX_DEFL(JvmtiThreadState_lock , PaddedMutex , JvmtiVTMSTransition_lock); // Used by JvmtiThreadState/JvmtiEventController // Allocate RecursiveMutex MultiArray_lock = new RecursiveMutex(); From 9d7d85a6aa20ed95166f5f2f951597bca1fde841 Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Mon, 2 Sep 2024 01:23:50 +0000 Subject: [PATCH 04/29] 8339298: Remove unused function declaration poll_for_safepoint Reviewed-by: fyang, chagedorn --- src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp | 2 -- src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp index ef1b5fe2703e6..77edbd7bc0a0e 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.hpp @@ -60,8 +60,6 @@ friend class ArrayCopyStub; void casw(Register addr, Register newval, Register cmpval); void casl(Register addr, Register newval, Register cmpval); - void poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info = nullptr); - static const int max_tableswitches = 20; struct tableswitch switches[max_tableswitches]; int tableswitch_count; diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp index 4388d0cf4d71d..4ce7eb2bf7392 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.hpp @@ -62,8 +62,6 @@ friend class ArrayCopyStub; void caswu(Register addr, Register newval, Register cmpval); void casl(Register addr, Register newval, Register cmpval); - void poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info = nullptr); - void deoptimize_trap(CodeEmitInfo *info); enum { From a136a85b6f5bbc92727883693c1ce31c37a82fd5 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 2 Sep 2024 09:14:36 +0000 Subject: [PATCH 05/29] 8338768: Introduce runtime lookup to check for static builds Co-authored-by: Magnus Ihse Bursie Co-authored-by: Jiangli Zhou Reviewed-by: prr, jiangli, alanb --- make/modules/jdk.jdwp.agent/Lib.gmk | 4 +- src/hotspot/os/bsd/os_bsd.cpp | 22 ++--- src/hotspot/share/compiler/disassembler.cpp | 18 ++-- src/hotspot/share/include/jvm.h | 3 + src/hotspot/share/prims/jvm.cpp | 4 + src/hotspot/share/runtime/java.hpp | 5 +- src/hotspot/share/runtime/linkType.cpp | 38 ++++++++ .../macosx/native/libjli/java_md_macosx.m | 88 +++++++++---------- src/java.base/share/native/libjli/jli_util.h | 3 + src/java.base/share/native/libjli/link_type.c | 38 ++++++++ .../unix/native/libawt/awt/awt_LoadLibrary.c | 45 +++++----- .../share/native/libjdwp/transport.c | 12 +-- 12 files changed, 184 insertions(+), 96 deletions(-) create mode 100644 src/hotspot/share/runtime/linkType.cpp create mode 100644 src/java.base/share/native/libjli/link_type.c diff --git a/make/modules/jdk.jdwp.agent/Lib.gmk b/make/modules/jdk.jdwp.agent/Lib.gmk index 354bfda4ea014..53b48cc7c453b 100644 --- a/make/modules/jdk.jdwp.agent/Lib.gmk +++ b/make/modules/jdk.jdwp.agent/Lib.gmk @@ -69,8 +69,8 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJDWP, \ EXTRA_HEADER_DIRS := \ include \ libjdwp/export \ - java.base:libjava \ - java.base:libjvm, \ + java.base:libjava, \ + JDK_LIBS := java.base:libjvm, \ LIBS_linux := $(LIBDL), \ LIBS_macosx := -liconv, \ LIBS_aix := -liconv, \ diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index c9c6c4d3edf97..9ad7c35e6bdef 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -473,9 +473,9 @@ void os::init_system_properties_values() { if (pslash != nullptr) { *pslash = '\0'; // Get rid of /{client|server|hotspot}. } -#ifdef STATIC_BUILD - strcat(buf, "/lib"); -#endif + if (is_vm_statically_linked()) { + strcat(buf, "/lib"); + } Arguments::set_dll_dir(buf); @@ -1093,19 +1093,20 @@ void *os::Bsd::dlopen_helper(const char *filename, int mode, char *ebuf, int ebu #ifdef __APPLE__ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { -#ifdef STATIC_BUILD - return os::get_default_process_handle(); -#else + if (is_vm_statically_linked()) { + return os::get_default_process_handle(); + } + log_info(os)("attempting shared library load of %s", filename); return os::Bsd::dlopen_helper(filename, RTLD_LAZY, ebuf, ebuflen); -#endif // STATIC_BUILD } #else void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { -#ifdef STATIC_BUILD - return os::get_default_process_handle(); -#else + if (is_vm_statically_linked()) { + return os::get_default_process_handle(); + } + log_info(os)("attempting shared library load of %s", filename); void* result; @@ -1269,7 +1270,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { } return nullptr; -#endif // STATIC_BUILD } #endif // !__APPLE__ diff --git a/src/hotspot/share/compiler/disassembler.cpp b/src/hotspot/share/compiler/disassembler.cpp index 091f1a2410e31..6556ce4ae1df2 100644 --- a/src/hotspot/share/compiler/disassembler.cpp +++ b/src/hotspot/share/compiler/disassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ #include "memory/universe.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" @@ -785,13 +786,13 @@ bool Disassembler::load_library(outputStream* st) { os::jvm_path(buf, sizeof(buf)); int jvm_offset = -1; int lib_offset = -1; -#ifdef STATIC_BUILD - char* p = strrchr(buf, '/'); - *p = '\0'; - strcat(p, "/lib/"); - lib_offset = jvm_offset = (int)strlen(buf); -#else - { + + if (is_vm_statically_linked()) { + char* p = strrchr(buf, '/'); + *p = '\0'; + strcat(p, "/lib/"); + lib_offset = jvm_offset = (int)strlen(buf); + } else { // Match "libjvm" instead of "jvm" on *nix platforms. Creates better matches. // Match "[lib]jvm[^/]*" in jvm_path. const char* base = buf; @@ -805,7 +806,6 @@ bool Disassembler::load_library(outputStream* st) { if (p != nullptr) jvm_offset = p - base + 3; // this points to 'j' in libjvm. #endif } -#endif // Find the disassembler shared library. // Search for several paths derived from libjvm, in this order: diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 6082af55487e2..edad228b4e3ae 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -180,6 +180,9 @@ JVM_IsContinuationsSupported(void); JNIEXPORT jboolean JNICALL JVM_IsForeignLinkerSupported(void); +JNIEXPORT jboolean JNICALL +JVM_IsStaticallyLinked(void); + JNIEXPORT void JNICALL JVM_InitializeFromArchive(JNIEnv* env, jclass cls); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index a26a82debe750..6425f5f583f36 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -3448,6 +3448,10 @@ JVM_LEAF(jboolean, JVM_IsForeignLinkerSupported(void)) return ForeignGlobals::is_foreign_linker_supported() ? JNI_TRUE : JNI_FALSE; JVM_END +JVM_ENTRY_NO_ENV(jboolean, JVM_IsStaticallyLinked(void)) + return is_vm_statically_linked() ? JNI_TRUE : JNI_FALSE; +JVM_END + // String support /////////////////////////////////////////////////////////////////////////// JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str)) diff --git a/src/hotspot/share/runtime/java.hpp b/src/hotspot/share/runtime/java.hpp index 9ab270e143d5a..21cbd76431fbb 100644 --- a/src/hotspot/share/runtime/java.hpp +++ b/src/hotspot/share/runtime/java.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,9 @@ extern void vm_shutdown_during_initialization(const char* error, const char* mes extern void vm_exit_during_cds_dumping(const char* error, const char* message = nullptr); +// This is defined in linkType.cpp due to linking restraints +extern bool is_vm_statically_linked(); + /** * With the integration of the changes to handle the version string * as defined by JEP-223, most of the code related to handle the version diff --git a/src/hotspot/share/runtime/linkType.cpp b/src/hotspot/share/runtime/linkType.cpp new file mode 100644 index 0000000000000..cc13efd68c2d8 --- /dev/null +++ b/src/hotspot/share/runtime/linkType.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/java.hpp" + +// This is in a separate file since it will need to be compiled to two different +// object files, depending on if we are going to build a static or a dynamic +// library. + +bool is_vm_statically_linked(void) { +#ifdef STATIC_BUILD + return true; +#else + return false; +#endif +} diff --git a/src/java.base/macosx/native/libjli/java_md_macosx.m b/src/java.base/macosx/native/libjli/java_md_macosx.m index 279a7abef1ee4..4ac2f2c10a215 100644 --- a/src/java.base/macosx/native/libjli/java_md_macosx.m +++ b/src/java.base/macosx/native/libjli/java_md_macosx.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -428,9 +428,9 @@ static void MacOSXStartup(int argc, char *argv[]) { JLI_TraceLauncher("Does `%s' exist ... ", jvmpath); -#ifdef STATIC_BUILD - return JNI_TRUE; -#else + if (JLI_IsStaticallyLinked()) { + return JNI_TRUE; + } if (stat(jvmpath, &s) == 0) { JLI_TraceLauncher("yes.\n"); return JNI_TRUE; @@ -438,7 +438,6 @@ static void MacOSXStartup(int argc, char *argv[]) { JLI_TraceLauncher("no.\n"); return JNI_FALSE; } -#endif } /* @@ -451,18 +450,18 @@ static void MacOSXStartup(int argc, char *argv[]) { if (GetApplicationHome(path, pathsize)) { /* Is JRE co-located with the application? */ -#ifdef STATIC_BUILD - char jvm_cfg[MAXPATHLEN]; - JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path); - if (access(jvm_cfg, F_OK) == 0) { - return JNI_TRUE; - } -#else - JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path); - if (access(libjava, F_OK) == 0) { - return JNI_TRUE; + if (JLI_IsStaticallyLinked()) { + char jvm_cfg[MAXPATHLEN]; + JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path); + if (access(jvm_cfg, F_OK) == 0) { + return JNI_TRUE; + } + } else { + JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path); + if (access(libjava, F_OK) == 0) { + return JNI_TRUE; + } } -#endif /* ensure storage for path + /jre + NULL */ if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) { JLI_TraceLauncher("Insufficient space to store JRE path\n"); @@ -481,23 +480,24 @@ static void MacOSXStartup(int argc, char *argv[]) { Dl_info selfInfo; dladdr(&GetJREPath, &selfInfo); -#ifdef STATIC_BUILD - char jvm_cfg[MAXPATHLEN]; - char *p = NULL; - strncpy(jvm_cfg, selfInfo.dli_fname, MAXPATHLEN); - p = strrchr(jvm_cfg, '/'); *p = '\0'; - p = strrchr(jvm_cfg, '/'); - if (strcmp(p, "/.") == 0) { - *p = '\0'; - p = strrchr(jvm_cfg, '/'); *p = '\0'; - } - else *p = '\0'; - strncpy(path, jvm_cfg, pathsize); - strncat(jvm_cfg, "/lib/jvm.cfg", MAXPATHLEN); - if (access(jvm_cfg, F_OK) == 0) { - return JNI_TRUE; + if (JLI_IsStaticallyLinked()) { + char jvm_cfg[MAXPATHLEN]; + char *p = NULL; + strncpy(jvm_cfg, selfInfo.dli_fname, MAXPATHLEN); + p = strrchr(jvm_cfg, '/'); *p = '\0'; + p = strrchr(jvm_cfg, '/'); + if (strcmp(p, "/.") == 0) { + *p = '\0'; + p = strrchr(jvm_cfg, '/'); *p = '\0'; + } else { + *p = '\0'; + } + strncpy(path, jvm_cfg, pathsize); + strncat(jvm_cfg, "/lib/jvm.cfg", MAXPATHLEN); + if (access(jvm_cfg, F_OK) == 0) { + return JNI_TRUE; + } } -#endif char *realPathToSelf = realpath(selfInfo.dli_fname, path); if (realPathToSelf != path) { @@ -549,11 +549,12 @@ static void MacOSXStartup(int argc, char *argv[]) { JLI_TraceLauncher("JVM path is %s\n", jvmpath); -#ifndef STATIC_BUILD - libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL); -#else - libjvm = dlopen(NULL, RTLD_FIRST); -#endif + if (!JLI_IsStaticallyLinked()) { + libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL); + } else { + libjvm = dlopen(NULL, RTLD_FIRST); + } + if (libjvm == NULL) { JLI_ReportErrorMessage(DLL_ERROR1, __LINE__); JLI_ReportErrorMessage(DLL_ERROR2, jvmpath, dlerror()); @@ -603,14 +604,13 @@ static void MacOSXStartup(int argc, char *argv[]) { char* exec_path = NULL; { Dl_info dlinfo; - -#ifdef STATIC_BUILD void *fptr; - fptr = (void *)&SetExecname; -#else - int (*fptr)(); - fptr = (int (*)())dlsym(RTLD_DEFAULT, "main"); -#endif + + if (JLI_IsStaticallyLinked()) { + fptr = (void *)&SetExecname; + } else { + fptr = dlsym(RTLD_DEFAULT, "main"); + } if (fptr == NULL) { JLI_ReportErrorMessage(DLL_ERROR3, dlerror()); return JNI_FALSE; diff --git a/src/java.base/share/native/libjli/jli_util.h b/src/java.base/share/native/libjli/jli_util.h index cacb0d65cb0f3..4bd72abc2db74 100644 --- a/src/java.base/share/native/libjli/jli_util.h +++ b/src/java.base/share/native/libjli/jli_util.h @@ -113,6 +113,9 @@ JLI_SetTraceLauncher(); jboolean JLI_IsTraceLauncher(); +// This is defined in link_type.c due to linking restraints +jboolean JLI_IsStaticallyLinked(); + /* * JLI_List - a dynamic list of char* */ diff --git a/src/java.base/share/native/libjli/link_type.c b/src/java.base/share/native/libjli/link_type.c new file mode 100644 index 0000000000000..aa060ddb00e29 --- /dev/null +++ b/src/java.base/share/native/libjli/link_type.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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. + */ + +#include "jni.h" + +// This is in a separate file since it will need to be compiled to two different +// object files, depending on if we are going to build a static or a dynamic +// library. + +jboolean JLI_IsStaticallyLinked(void) { +#ifdef STATIC_BUILD + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +} diff --git a/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c b/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c index b2dedca351c5f..389e25caaec0c 100644 --- a/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c +++ b/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,44 +116,41 @@ AWT_OnLoad(JavaVM *vm, void *reserved) } jvm = vm; -#ifndef STATIC_BUILD - /* Get address of this library and the directory containing it. */ - dladdr((void *)AWT_OnLoad, &dlinfo); - realpath((char *)dlinfo.dli_fname, buf); - len = strlen(buf); - p = strrchr(buf, '/'); -#endif + /* * The code below is responsible for * loading appropriate awt library, i.e. libawt_xawt or libawt_headless */ #ifdef MACOSX - tk = LWAWT_PATH; + tk = LWAWT_PATH; #else - tk = XAWT_PATH; -#endif + tk = XAWT_PATH; -#ifndef MACOSX if (AWTIsHeadless()) { tk = HEADLESS_PATH; } #endif -#ifndef STATIC_BUILD - /* Calculate library name to load */ - strncpy(p, tk, MAXPATHLEN-len-1); -#endif + if (!JVM_IsStaticallyLinked()) { + /* Get address of this library and the directory containing it. */ + dladdr((void *)AWT_OnLoad, &dlinfo); + realpath((char *)dlinfo.dli_fname, buf); + len = strlen(buf); + p = strrchr(buf, '/'); -#ifndef STATIC_BUILD - jstring jbuf = JNU_NewStringPlatform(env, buf); - CHECK_EXCEPTION_FATAL(env, "Could not allocate library name"); - JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load", - "(Ljava/lang/String;)V", - jbuf); + /* Calculate library name to load */ + strncpy(p, tk, MAXPATHLEN-len-1); + + jstring jbuf = JNU_NewStringPlatform(env, buf); + CHECK_EXCEPTION_FATAL(env, "Could not allocate library name"); + JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load", + "(Ljava/lang/String;)V", + jbuf); + + awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); + } - awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); -#endif return JNI_VERSION_1_2; } diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/transport.c b/src/jdk.jdwp.agent/share/native/libjdwp/transport.c index 273bb7ad9c148..f67e9da47ea94 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/transport.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/transport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ * questions. */ +#include "jvm.h" #include "util.h" #include "utf_util.h" #include "transport.h" @@ -121,7 +122,11 @@ static void * loadTransportLibrary(const char *libdir, const char *name) { char buf[MAXPATHLEN*2+100]; -#ifndef STATIC_BUILD + + if (JVM_IsStaticallyLinked()) { + return (dbgsysLoadLibrary(NULL, buf, sizeof(buf))); + } + void *handle; char libname[MAXPATHLEN+2]; const char *plibdir; @@ -145,9 +150,6 @@ loadTransportLibrary(const char *libdir, const char *name) /* dlopen (unix) / LoadLibrary (windows) the transport library */ handle = dbgsysLoadLibrary(libname, buf, sizeof(buf)); return handle; -#else - return (dbgsysLoadLibrary(NULL, buf, sizeof(buf))); -#endif } /* From 03ba37e60ce08def6afd172efc1cdbbcc856c633 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Mon, 2 Sep 2024 09:32:10 +0000 Subject: [PATCH 06/29] 8339169: Remove NaiveHuffman coder Reviewed-by: djelinski, dfuchs --- .../internal/net/http/hpack/NaiveHuffman.java | 691 ------------------ 1 file changed, 691 deletions(-) delete mode 100644 src/java.net.http/share/classes/jdk/internal/net/http/hpack/NaiveHuffman.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/hpack/NaiveHuffman.java b/src/java.net.http/share/classes/jdk/internal/net/http/hpack/NaiveHuffman.java deleted file mode 100644 index 8a076ca67cb6b..0000000000000 --- a/src/java.net.http/share/classes/jdk/internal/net/http/hpack/NaiveHuffman.java +++ /dev/null @@ -1,691 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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.net.http.hpack; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import static java.lang.String.format; - -/** - * Huffman coding table. - * - *

Instances of this class are safe for use by multiple threads. - * - * @since 9 - */ -public final class NaiveHuffman { - - // TODO: check if reset is done in both reader and writer - - static final class Reader implements Huffman.Reader { - - private Node curr; // position in the trie - private int len; // length of the path from the root to 'curr' - private int p; // byte probe - - { - reset(); - } - - @Override - public void read(ByteBuffer source, - Appendable destination, - boolean isLast) throws IOException { - read(source, destination, true, isLast); - } - - // Takes 'isLast' rather than returns whether the reading is done or - // not, for more informative exceptions. - void read(ByteBuffer source, - Appendable destination, - boolean reportEOS, /* reportEOS is exposed for tests */ - boolean isLast) throws IOException { - Node c = curr; - int l = len; - /* - Since ByteBuffer is itself stateful, its position is - remembered here NOT as a part of Reader's state, - but to set it back in the case of a failure - */ - int pos = source.position(); - - while (source.hasRemaining()) { - int d = source.get(); - for (; p != 0; p >>= 1) { - c = c.getChild(p & d); - l++; - if (c.isLeaf()) { - if (reportEOS && c.isEOSPath) { - throw new IOException("Encountered EOS"); - } - char ch; - try { - ch = c.getChar(); - } catch (IllegalStateException e) { - source.position(pos); // do we need this? - throw new IOException(e); - } - try { - destination.append(ch); - } catch (IOException e) { - source.position(pos); // do we need this? - throw e; - } - c = INSTANCE.root; - l = 0; - } - curr = c; - len = l; - } - resetProbe(); - pos++; - } - if (!isLast) { - return; // it's too early to jump to any conclusions, let's wait - } - if (c.isLeaf()) { - return; // it's perfectly ok, no extra padding bits - } - if (c.isEOSPath && len <= 7) { - return; // it's ok, some extra padding bits - } - if (c.isEOSPath) { - throw new IOException( - "Padding is too long (len=" + len + ") " + - "or unexpected end of data"); - } - throw new IOException( - "Not a EOS prefix padding or unexpected end of data"); - } - - @Override - public void reset() { - curr = INSTANCE.root; - len = 0; - resetProbe(); - } - - private void resetProbe() { - p = 0x80; - } - } - - static final class Writer implements Huffman.Writer { - - private int pos; // position in 'source' - private int avail = 8; // number of least significant bits available in 'curr' - private int curr; // next byte to put to the destination - private int rem; // number of least significant bits in 'code' yet to be processed - private int code; // current code being written - - private CharSequence source; - private int end; - - @Override - public Writer from(CharSequence input, int start, int end) { - if (start < 0 || end < 0 || end > input.length() || start > end) { - throw new IndexOutOfBoundsException( - String.format("input.length()=%s, start=%s, end=%s", - input.length(), start, end)); - } - pos = start; - this.end = end; - this.source = input; - return this; - } - - @Override - public boolean write(ByteBuffer destination) { - for (; pos < end; pos++) { - if (rem == 0) { - Code desc = INSTANCE.codeOf(source.charAt(pos)); - rem = desc.length; - code = desc.code; - } - while (rem > 0) { - if (rem < avail) { - curr |= (code << (avail - rem)); - avail -= rem; - rem = 0; - } else { - int c = (curr | (code >>> (rem - avail))); - if (destination.hasRemaining()) { - destination.put((byte) c); - } else { - return false; - } - curr = c; - code <<= (32 - rem + avail); // throw written bits off the cliff (is this Sparta?) - code >>>= (32 - rem + avail); // return to the position - rem -= avail; - curr = 0; - avail = 8; - } - } - } - - if (avail < 8) { // have to pad - if (destination.hasRemaining()) { - destination.put((byte) (curr | (INSTANCE.EOS.code >>> (INSTANCE.EOS.length - avail)))); - avail = 8; - } else { - return false; - } - } - - return true; - } - - @Override - public Writer reset() { - source = null; - end = -1; - pos = -1; - avail = 8; - curr = 0; - code = 0; - return this; - } - - @Override - public int lengthOf(CharSequence value, int start, int end) { - return INSTANCE.lengthOf(value, start, end); - } - } - - /** - * Shared instance. - */ - public static final NaiveHuffman INSTANCE = new NaiveHuffman(); - - private final Code EOS = new Code(0x3fffffff, 30); - private final Code[] codes = new Code[257]; - private final Node root = new Node() { - @Override - public String toString() { return "root"; } - }; - - // TODO: consider builder and immutable trie - private NaiveHuffman() { - // @formatter:off - addChar(0, 0x1ff8, 13); - addChar(1, 0x7fffd8, 23); - addChar(2, 0xfffffe2, 28); - addChar(3, 0xfffffe3, 28); - addChar(4, 0xfffffe4, 28); - addChar(5, 0xfffffe5, 28); - addChar(6, 0xfffffe6, 28); - addChar(7, 0xfffffe7, 28); - addChar(8, 0xfffffe8, 28); - addChar(9, 0xffffea, 24); - addChar(10, 0x3ffffffc, 30); - addChar(11, 0xfffffe9, 28); - addChar(12, 0xfffffea, 28); - addChar(13, 0x3ffffffd, 30); - addChar(14, 0xfffffeb, 28); - addChar(15, 0xfffffec, 28); - addChar(16, 0xfffffed, 28); - addChar(17, 0xfffffee, 28); - addChar(18, 0xfffffef, 28); - addChar(19, 0xffffff0, 28); - addChar(20, 0xffffff1, 28); - addChar(21, 0xffffff2, 28); - addChar(22, 0x3ffffffe, 30); - addChar(23, 0xffffff3, 28); - addChar(24, 0xffffff4, 28); - addChar(25, 0xffffff5, 28); - addChar(26, 0xffffff6, 28); - addChar(27, 0xffffff7, 28); - addChar(28, 0xffffff8, 28); - addChar(29, 0xffffff9, 28); - addChar(30, 0xffffffa, 28); - addChar(31, 0xffffffb, 28); - addChar(32, 0x14, 6); - addChar(33, 0x3f8, 10); - addChar(34, 0x3f9, 10); - addChar(35, 0xffa, 12); - addChar(36, 0x1ff9, 13); - addChar(37, 0x15, 6); - addChar(38, 0xf8, 8); - addChar(39, 0x7fa, 11); - addChar(40, 0x3fa, 10); - addChar(41, 0x3fb, 10); - addChar(42, 0xf9, 8); - addChar(43, 0x7fb, 11); - addChar(44, 0xfa, 8); - addChar(45, 0x16, 6); - addChar(46, 0x17, 6); - addChar(47, 0x18, 6); - addChar(48, 0x0, 5); - addChar(49, 0x1, 5); - addChar(50, 0x2, 5); - addChar(51, 0x19, 6); - addChar(52, 0x1a, 6); - addChar(53, 0x1b, 6); - addChar(54, 0x1c, 6); - addChar(55, 0x1d, 6); - addChar(56, 0x1e, 6); - addChar(57, 0x1f, 6); - addChar(58, 0x5c, 7); - addChar(59, 0xfb, 8); - addChar(60, 0x7ffc, 15); - addChar(61, 0x20, 6); - addChar(62, 0xffb, 12); - addChar(63, 0x3fc, 10); - addChar(64, 0x1ffa, 13); - addChar(65, 0x21, 6); - addChar(66, 0x5d, 7); - addChar(67, 0x5e, 7); - addChar(68, 0x5f, 7); - addChar(69, 0x60, 7); - addChar(70, 0x61, 7); - addChar(71, 0x62, 7); - addChar(72, 0x63, 7); - addChar(73, 0x64, 7); - addChar(74, 0x65, 7); - addChar(75, 0x66, 7); - addChar(76, 0x67, 7); - addChar(77, 0x68, 7); - addChar(78, 0x69, 7); - addChar(79, 0x6a, 7); - addChar(80, 0x6b, 7); - addChar(81, 0x6c, 7); - addChar(82, 0x6d, 7); - addChar(83, 0x6e, 7); - addChar(84, 0x6f, 7); - addChar(85, 0x70, 7); - addChar(86, 0x71, 7); - addChar(87, 0x72, 7); - addChar(88, 0xfc, 8); - addChar(89, 0x73, 7); - addChar(90, 0xfd, 8); - addChar(91, 0x1ffb, 13); - addChar(92, 0x7fff0, 19); - addChar(93, 0x1ffc, 13); - addChar(94, 0x3ffc, 14); - addChar(95, 0x22, 6); - addChar(96, 0x7ffd, 15); - addChar(97, 0x3, 5); - addChar(98, 0x23, 6); - addChar(99, 0x4, 5); - addChar(100, 0x24, 6); - addChar(101, 0x5, 5); - addChar(102, 0x25, 6); - addChar(103, 0x26, 6); - addChar(104, 0x27, 6); - addChar(105, 0x6, 5); - addChar(106, 0x74, 7); - addChar(107, 0x75, 7); - addChar(108, 0x28, 6); - addChar(109, 0x29, 6); - addChar(110, 0x2a, 6); - addChar(111, 0x7, 5); - addChar(112, 0x2b, 6); - addChar(113, 0x76, 7); - addChar(114, 0x2c, 6); - addChar(115, 0x8, 5); - addChar(116, 0x9, 5); - addChar(117, 0x2d, 6); - addChar(118, 0x77, 7); - addChar(119, 0x78, 7); - addChar(120, 0x79, 7); - addChar(121, 0x7a, 7); - addChar(122, 0x7b, 7); - addChar(123, 0x7ffe, 15); - addChar(124, 0x7fc, 11); - addChar(125, 0x3ffd, 14); - addChar(126, 0x1ffd, 13); - addChar(127, 0xffffffc, 28); - addChar(128, 0xfffe6, 20); - addChar(129, 0x3fffd2, 22); - addChar(130, 0xfffe7, 20); - addChar(131, 0xfffe8, 20); - addChar(132, 0x3fffd3, 22); - addChar(133, 0x3fffd4, 22); - addChar(134, 0x3fffd5, 22); - addChar(135, 0x7fffd9, 23); - addChar(136, 0x3fffd6, 22); - addChar(137, 0x7fffda, 23); - addChar(138, 0x7fffdb, 23); - addChar(139, 0x7fffdc, 23); - addChar(140, 0x7fffdd, 23); - addChar(141, 0x7fffde, 23); - addChar(142, 0xffffeb, 24); - addChar(143, 0x7fffdf, 23); - addChar(144, 0xffffec, 24); - addChar(145, 0xffffed, 24); - addChar(146, 0x3fffd7, 22); - addChar(147, 0x7fffe0, 23); - addChar(148, 0xffffee, 24); - addChar(149, 0x7fffe1, 23); - addChar(150, 0x7fffe2, 23); - addChar(151, 0x7fffe3, 23); - addChar(152, 0x7fffe4, 23); - addChar(153, 0x1fffdc, 21); - addChar(154, 0x3fffd8, 22); - addChar(155, 0x7fffe5, 23); - addChar(156, 0x3fffd9, 22); - addChar(157, 0x7fffe6, 23); - addChar(158, 0x7fffe7, 23); - addChar(159, 0xffffef, 24); - addChar(160, 0x3fffda, 22); - addChar(161, 0x1fffdd, 21); - addChar(162, 0xfffe9, 20); - addChar(163, 0x3fffdb, 22); - addChar(164, 0x3fffdc, 22); - addChar(165, 0x7fffe8, 23); - addChar(166, 0x7fffe9, 23); - addChar(167, 0x1fffde, 21); - addChar(168, 0x7fffea, 23); - addChar(169, 0x3fffdd, 22); - addChar(170, 0x3fffde, 22); - addChar(171, 0xfffff0, 24); - addChar(172, 0x1fffdf, 21); - addChar(173, 0x3fffdf, 22); - addChar(174, 0x7fffeb, 23); - addChar(175, 0x7fffec, 23); - addChar(176, 0x1fffe0, 21); - addChar(177, 0x1fffe1, 21); - addChar(178, 0x3fffe0, 22); - addChar(179, 0x1fffe2, 21); - addChar(180, 0x7fffed, 23); - addChar(181, 0x3fffe1, 22); - addChar(182, 0x7fffee, 23); - addChar(183, 0x7fffef, 23); - addChar(184, 0xfffea, 20); - addChar(185, 0x3fffe2, 22); - addChar(186, 0x3fffe3, 22); - addChar(187, 0x3fffe4, 22); - addChar(188, 0x7ffff0, 23); - addChar(189, 0x3fffe5, 22); - addChar(190, 0x3fffe6, 22); - addChar(191, 0x7ffff1, 23); - addChar(192, 0x3ffffe0, 26); - addChar(193, 0x3ffffe1, 26); - addChar(194, 0xfffeb, 20); - addChar(195, 0x7fff1, 19); - addChar(196, 0x3fffe7, 22); - addChar(197, 0x7ffff2, 23); - addChar(198, 0x3fffe8, 22); - addChar(199, 0x1ffffec, 25); - addChar(200, 0x3ffffe2, 26); - addChar(201, 0x3ffffe3, 26); - addChar(202, 0x3ffffe4, 26); - addChar(203, 0x7ffffde, 27); - addChar(204, 0x7ffffdf, 27); - addChar(205, 0x3ffffe5, 26); - addChar(206, 0xfffff1, 24); - addChar(207, 0x1ffffed, 25); - addChar(208, 0x7fff2, 19); - addChar(209, 0x1fffe3, 21); - addChar(210, 0x3ffffe6, 26); - addChar(211, 0x7ffffe0, 27); - addChar(212, 0x7ffffe1, 27); - addChar(213, 0x3ffffe7, 26); - addChar(214, 0x7ffffe2, 27); - addChar(215, 0xfffff2, 24); - addChar(216, 0x1fffe4, 21); - addChar(217, 0x1fffe5, 21); - addChar(218, 0x3ffffe8, 26); - addChar(219, 0x3ffffe9, 26); - addChar(220, 0xffffffd, 28); - addChar(221, 0x7ffffe3, 27); - addChar(222, 0x7ffffe4, 27); - addChar(223, 0x7ffffe5, 27); - addChar(224, 0xfffec, 20); - addChar(225, 0xfffff3, 24); - addChar(226, 0xfffed, 20); - addChar(227, 0x1fffe6, 21); - addChar(228, 0x3fffe9, 22); - addChar(229, 0x1fffe7, 21); - addChar(230, 0x1fffe8, 21); - addChar(231, 0x7ffff3, 23); - addChar(232, 0x3fffea, 22); - addChar(233, 0x3fffeb, 22); - addChar(234, 0x1ffffee, 25); - addChar(235, 0x1ffffef, 25); - addChar(236, 0xfffff4, 24); - addChar(237, 0xfffff5, 24); - addChar(238, 0x3ffffea, 26); - addChar(239, 0x7ffff4, 23); - addChar(240, 0x3ffffeb, 26); - addChar(241, 0x7ffffe6, 27); - addChar(242, 0x3ffffec, 26); - addChar(243, 0x3ffffed, 26); - addChar(244, 0x7ffffe7, 27); - addChar(245, 0x7ffffe8, 27); - addChar(246, 0x7ffffe9, 27); - addChar(247, 0x7ffffea, 27); - addChar(248, 0x7ffffeb, 27); - addChar(249, 0xffffffe, 28); - addChar(250, 0x7ffffec, 27); - addChar(251, 0x7ffffed, 27); - addChar(252, 0x7ffffee, 27); - addChar(253, 0x7ffffef, 27); - addChar(254, 0x7fffff0, 27); - addChar(255, 0x3ffffee, 26); - addEOS (256, EOS.code, EOS.length); - // @formatter:on - } - - - /** - * Calculates the number of bytes required to represent the given {@code - * CharSequence} with the Huffman coding. - * - * @param value - * characters - * - * @return number of bytes - * - * @throws NullPointerException - * if the value is null - */ - public int lengthOf(CharSequence value) { - return lengthOf(value, 0, value.length()); - } - - /** - * Calculates the number of bytes required to represent a subsequence of the - * given {@code CharSequence} with the Huffman coding. - * - * @param value - * characters - * @param start - * the start index, inclusive - * @param end - * the end index, exclusive - * - * @return number of bytes - * - * @throws NullPointerException - * if the value is null - * @throws IndexOutOfBoundsException - * if any invocation of {@code value.charAt(i)}, where - * {@code start <= i < end} would throw an IndexOutOfBoundsException - */ - public int lengthOf(CharSequence value, int start, int end) { - int len = 0; - for (int i = start; i < end; i++) { - char c = value.charAt(i); - len += INSTANCE.codeOf(c).length; - } - // Integer division with ceiling, assumption: - assert (len / 8 + (len % 8 != 0 ? 1 : 0)) == (len + 7) / 8 : len; - return (len + 7) / 8; - } - - private void addChar(int c, int code, int bitLength) { - addLeaf(c, code, bitLength, false); - codes[c] = new Code(code, bitLength); - } - - private void addEOS(int c, int code, int bitLength) { - addLeaf(c, code, bitLength, true); - codes[c] = new Code(code, bitLength); - } - - private void addLeaf(int c, int code, int bitLength, boolean isEOS) { - if (bitLength < 1) { - throw new IllegalArgumentException("bitLength < 1"); - } - Node curr = root; - for (int p = 1 << bitLength - 1; p != 0 && !curr.isLeaf(); p = p >> 1) { - curr.isEOSPath |= isEOS; // If it's already true, it can't become false - curr = curr.addChildIfAbsent(p & code); - } - curr.isEOSPath |= isEOS; // The last one needs to have this property as well - if (curr.isLeaf()) { - throw new IllegalStateException("Specified code is already taken"); - } - curr.setChar((char) c); - } - - private Code codeOf(char c) { - if (c > 255) { - throw new IllegalArgumentException("char=" + ((int) c)); - } - return codes[c]; - } - - // - // For debugging/testing purposes - // - Node getRoot() { - return root; - } - - // - // Guarantees: - // - // if (isLeaf() == true) => getChar() is a legal call - // if (isLeaf() == false) => getChild(i) is a legal call (though it can - // return null) - // - static class Node { - - Node left; - Node right; - boolean isEOSPath; - - boolean charIsSet; - char c; - - Node getChild(int selector) { - if (isLeaf()) { - throw new IllegalStateException("This is a leaf node"); - } - Node result = selector == 0 ? left : right; - if (result == null) { - throw new IllegalStateException(format( - "Node doesn't have a child (selector=%s)", selector)); - } - return result; - } - - boolean isLeaf() { - return charIsSet; - } - - char getChar() { - if (!isLeaf()) { - throw new IllegalStateException("This node is not a leaf node"); - } - return c; - } - - void setChar(char c) { - if (charIsSet) { - throw new IllegalStateException( - "This node has been taken already"); - } - if (left != null || right != null) { - throw new IllegalStateException("The node cannot be made " - + "a leaf as it's already has a child"); - } - this.c = c; - charIsSet = true; - } - - Node addChildIfAbsent(int i) { - if (charIsSet) { - throw new IllegalStateException("The node cannot have a child " - + "as it's already a leaf node"); - } - Node child; - if (i == 0) { - if ((child = left) == null) { - child = left = new Node(); - } - } else { - if ((child = right) == null) { - child = right = new Node(); - } - } - return child; - } - - @Override - public String toString() { - if (isLeaf()) { - if (isEOSPath) { - return "EOS"; - } else { - return format("char: (%3s) '%s'", (int) c, c); - } - } - return "/\\"; - } - } - - // TODO: value-based class? - // FIXME: can we re-use Node instead of this class? - private static final class Code { - - final int code; - final int length; - - private Code(int code, int length) { - this.code = code; - this.length = length; - } - - public int getCode() { - return code; - } - - public int getLength() { - return length; - } - - @Override - public String toString() { - long p = 1 << length; - return Long.toBinaryString(code + p).substring(1) - + ", length=" + length; - } - } -} From b1163bcc88a5b88b9a56d5584310f1d679690ab2 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Mon, 2 Sep 2024 14:52:04 +0000 Subject: [PATCH 07/29] 8256211: assert fired in java/net/httpclient/DependentPromiseActionsTest (infrequent) Reviewed-by: jpai --- .../DependentPromiseActionsTest.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java index 4e17408ee6f50..32c594808a9c4 100644 --- a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java +++ b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,6 +73,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Flow; import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiPredicate; @@ -112,6 +113,7 @@ public class DependentPromiseActionsTest implements HttpServerAdapters { static volatile boolean tasksFailed; static final AtomicLong serverCount = new AtomicLong(); static final AtomicLong clientCount = new AtomicLong(); + static final AtomicInteger requestCount = new AtomicInteger(); static final long start = System.nanoTime(); public static String now() { long now = System.nanoTime() - start; @@ -244,14 +246,17 @@ HttpClient newHttpClient(boolean share) { } @Test(dataProvider = "noStalls") - public void testNoStalls(String uri, boolean sameClient) + public void testNoStalls(String rootUri, boolean sameClient) throws Exception { + if (!FAILURES.isEmpty()) return; HttpClient client = null; - out.printf("%ntestNoStalls(%s, %b)%n", uri, sameClient); + out.printf("%ntestNoStalls(%s, %b)%n", rootUri, sameClient); for (int i=0; i< ITERATION_COUNT; i++) { if (!sameClient || client == null) client = newHttpClient(sameClient); + String uri = rootUri + "/" + requestCount.incrementAndGet(); + out.printf("\tsending request %s%n", uri); HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) .build(); BodyHandler> handler = @@ -331,6 +336,10 @@ private void testDependent(String name, String uri, boolean sameClient, SubscriberType subscriberType) throws Exception { + if (!FAILURES.isEmpty()) { + out.printf("%s: skipping test - previous failure detected%n", name); + return; + } out.printf("%n%s%s%n", now(), name); try { testDependent(uri, sameClient, handlers, finisher, @@ -341,7 +350,7 @@ private void testDependent(String name, String uri, boolean sameClient, } } - private void testDependent(String uri, boolean sameClient, + private void testDependent(String rootUri, boolean sameClient, Supplier> handlers, Finisher finisher, Extractor extractor, @@ -354,6 +363,8 @@ private void testDependent(String uri, boolean sameClient, if (!sameClient || client == null) client = newHttpClient(sameClient); + String uri = rootUri + "/" + requestCount.incrementAndGet(); + out.printf("\tsending request %s%n", uri); HttpRequest req = HttpRequest. newBuilder(URI.create(uri)) .build(); @@ -363,7 +374,13 @@ private void testDependent(String uri, boolean sameClient, System.out.println("try stalling in " + where); CompletableFuture> responseCF = client.sendAsync(req, handler, promiseHandler); - assert subscriberType == SubscriberType.LAZZY || !responseCF.isDone(); + // The body of the main response can be received before the body + // of the push promise handlers are received. + // The body of the main response doesn't stall, so the cf of + // the main response may be done here even for EAGER subscribers. + // We cannot make any assumption on the state of the main response + // cf here, so the only thing we can do is to call the finisher + // which will wait for them all. finisher.finish(where, responseCF, promiseHandler, extractor); } } From 0e6bb514c8ec7c4a7100fe06eaa9e954a74fda30 Mon Sep 17 00:00:00 2001 From: Joshua Zhu Date: Mon, 2 Sep 2024 15:37:58 +0000 Subject: [PATCH 08/29] 8339063: [aarch64] Skip verify_sve_vector_length after native calls if SVE supports 128 bits VL only Reviewed-by: adinn, fgao --- src/hotspot/cpu/aarch64/aarch64.ad | 4 +- src/hotspot/cpu/aarch64/aarch64_vector.ad | 2 +- src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 | 2 +- .../cpu/aarch64/macroAssembler_aarch64.cpp | 4 +- src/hotspot/cpu/aarch64/register_aarch64.hpp | 10 +++- .../cpu/aarch64/vm_version_aarch64.cpp | 47 +++++++++++-------- .../cpu/aarch64/vm_version_aarch64.hpp | 4 +- 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 8eb2821cc5744..fced9cfc35e57 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -2334,7 +2334,7 @@ bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { // Vector width in bytes. int Matcher::vector_width_in_bytes(BasicType bt) { // The MaxVectorSize should have been set by detecting SVE max vector register size. - int size = MIN2((UseSVE > 0) ? 256 : 16, (int)MaxVectorSize); + int size = MIN2((UseSVE > 0) ? (int)FloatRegister::sve_vl_max : (int)FloatRegister::neon_vl, (int)MaxVectorSize); // Minimum 2 values in vector if (size < 2*type2aelembytes(bt)) size = 0; // But never < 4 @@ -2373,7 +2373,7 @@ int Matcher::scalable_vector_reg_size(const BasicType bt) { // Vector ideal reg. uint Matcher::vector_ideal_reg(int len) { - if (UseSVE > 0 && 16 < len && len <= 256) { + if (UseSVE > 0 && FloatRegister::neon_vl < len && len <= FloatRegister::sve_vl_max) { return Op_VecA; } switch(len) { diff --git a/src/hotspot/cpu/aarch64/aarch64_vector.ad b/src/hotspot/cpu/aarch64/aarch64_vector.ad index 637d3de73af6f..cdbc4103df89a 100644 --- a/src/hotspot/cpu/aarch64/aarch64_vector.ad +++ b/src/hotspot/cpu/aarch64/aarch64_vector.ad @@ -155,7 +155,7 @@ source %{ } int length_in_bytes = vlen * type2aelembytes(bt); - if (UseSVE == 0 && length_in_bytes > 16) { + if (UseSVE == 0 && length_in_bytes > FloatRegister::neon_vl) { return false; } diff --git a/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 index b3403ec82a1fe..020a75b51fa8f 100644 --- a/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 @@ -145,7 +145,7 @@ source %{ } int length_in_bytes = vlen * type2aelembytes(bt); - if (UseSVE == 0 && length_in_bytes > 16) { + if (UseSVE == 0 && length_in_bytes > FloatRegister::neon_vl) { return false; } diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index f8b703fb4daf6..d09ef26cef995 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -6413,8 +6413,10 @@ void MacroAssembler::cache_wbsync(bool is_pre) { } void MacroAssembler::verify_sve_vector_length(Register tmp) { + if (!UseSVE || VM_Version::get_max_supported_sve_vector_length() == FloatRegister::sve_vl_min) { + return; + } // Make sure that native code does not change SVE vector length. - if (!UseSVE) return; Label verify_ok; movw(tmp, zr); sve_inc(tmp, B); diff --git a/src/hotspot/cpu/aarch64/register_aarch64.hpp b/src/hotspot/cpu/aarch64/register_aarch64.hpp index 8e340fefbb46a..ab635e1be9040 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -166,7 +166,13 @@ class FloatRegister { max_slots_per_register = 4, save_slots_per_register = 2, slots_per_neon_register = 4, - extra_save_slots_per_neon_register = slots_per_neon_register - save_slots_per_register + extra_save_slots_per_neon_register = slots_per_neon_register - save_slots_per_register, + neon_vl = 16, + // VLmax: The maximum sve vector length is determined by the hardware + // sve_vl_min <= VLmax <= sve_vl_max. + sve_vl_min = 16, + // Maximum supported vector length across all CPUs + sve_vl_max = 256 }; class FloatRegisterImpl: public AbstractRegisterImpl { diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index c0f10adc85df9..d71162ac568ea 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "pauth_aarch64.hpp" +#include "register_aarch64.hpp" #include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" #include "runtime/java.hpp" @@ -44,6 +45,7 @@ int VM_Version::_zva_length; int VM_Version::_dcache_line_size; int VM_Version::_icache_line_size; int VM_Version::_initial_sve_vector_length; +int VM_Version::_max_supported_sve_vector_length; bool VM_Version::_rop_protection; uintptr_t VM_Version::_pac_mask; @@ -507,30 +509,37 @@ void VM_Version::initialize() { if (UseSVE > 0) { if (FLAG_IS_DEFAULT(MaxVectorSize)) { MaxVectorSize = _initial_sve_vector_length; - } else if (MaxVectorSize < 16) { - warning("SVE does not support vector length less than 16 bytes. Disabling SVE."); + } else if (MaxVectorSize < FloatRegister::sve_vl_min) { + warning("SVE does not support vector length less than %d bytes. Disabling SVE.", + FloatRegister::sve_vl_min); UseSVE = 0; - } else if ((MaxVectorSize % 16) == 0 && is_power_of_2(MaxVectorSize)) { - int new_vl = set_and_get_current_sve_vector_length(MaxVectorSize); - _initial_sve_vector_length = new_vl; - // Update MaxVectorSize to the largest supported value. - if (new_vl < 0) { - vm_exit_during_initialization( - err_msg("Current system does not support SVE vector length for MaxVectorSize: %d", - (int)MaxVectorSize)); - } else if (new_vl != MaxVectorSize) { - warning("Current system only supports max SVE vector length %d. Set MaxVectorSize to %d", - new_vl, new_vl); - } - MaxVectorSize = new_vl; - } else { + } else if (!((MaxVectorSize % FloatRegister::sve_vl_min) == 0 && is_power_of_2(MaxVectorSize))) { vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize)); } + + if (UseSVE > 0) { + // Acquire the largest supported vector length of this machine + _max_supported_sve_vector_length = set_and_get_current_sve_vector_length(FloatRegister::sve_vl_max); + + if (MaxVectorSize != _max_supported_sve_vector_length) { + int new_vl = set_and_get_current_sve_vector_length(MaxVectorSize); + if (new_vl < 0) { + vm_exit_during_initialization( + err_msg("Current system does not support SVE vector length for MaxVectorSize: %d", + (int)MaxVectorSize)); + } else if (new_vl != MaxVectorSize) { + warning("Current system only supports max SVE vector length %d. Set MaxVectorSize to %d", + new_vl, new_vl); + } + MaxVectorSize = new_vl; + } + _initial_sve_vector_length = MaxVectorSize; + } } if (UseSVE == 0) { // NEON int min_vector_size = 8; - int max_vector_size = 16; + int max_vector_size = FloatRegister::neon_vl; if (!FLAG_IS_DEFAULT(MaxVectorSize)) { if (!is_power_of_2(MaxVectorSize)) { vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize)); @@ -542,11 +551,11 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(MaxVectorSize, max_vector_size); } } else { - FLAG_SET_DEFAULT(MaxVectorSize, 16); + FLAG_SET_DEFAULT(MaxVectorSize, FloatRegister::neon_vl); } } - int inline_size = (UseSVE > 0 && MaxVectorSize >= 16) ? MaxVectorSize : 0; + int inline_size = (UseSVE > 0 && MaxVectorSize >= FloatRegister::sve_vl_min) ? MaxVectorSize : 0; if (FLAG_IS_DEFAULT(ArrayOperationPartialInlineSize)) { FLAG_SET_DEFAULT(ArrayOperationPartialInlineSize, inline_size); } else if (ArrayOperationPartialInlineSize != 0 && ArrayOperationPartialInlineSize != inline_size) { diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index f6cac72804f2c..04cf9c9c2a07c 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp @@ -46,6 +46,7 @@ class VM_Version : public Abstract_VM_Version { static int _dcache_line_size; static int _icache_line_size; static int _initial_sve_vector_length; + static int _max_supported_sve_vector_length; static bool _rop_protection; static uintptr_t _pac_mask; @@ -164,7 +165,8 @@ enum Ampere_CPU_Model { static int icache_line_size() { return _icache_line_size; } static int dcache_line_size() { return _dcache_line_size; } - static int get_initial_sve_vector_length() { return _initial_sve_vector_length; }; + static int get_initial_sve_vector_length() { return _initial_sve_vector_length; }; + static int get_max_supported_sve_vector_length() { return _max_supported_sve_vector_length; }; // Aarch64 supports fast class initialization checks static bool supports_fast_class_init_checks() { return true; } From 62dad3a9ea222b0fbf15668d6e7b1c4ed61b2532 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 2 Sep 2024 17:57:02 +0000 Subject: [PATCH 09/29] 8339351: Remove duplicate line in FileMapHeader::print Reviewed-by: dholmes --- src/hotspot/share/cds/filemap.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index dc6c7ea097c65..35c43157b1ab3 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -268,7 +268,6 @@ void FileMapHeader::print(outputStream* st) { st->print_cr("- core_region_alignment: " SIZE_FORMAT, _core_region_alignment); st->print_cr("- obj_alignment: %d", _obj_alignment); st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base)); - st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base)); st->print_cr("- narrow_oop_shift %d", _narrow_oop_shift); st->print_cr("- compact_strings: %d", _compact_strings); st->print_cr("- max_heap_size: " UINTX_FORMAT, _max_heap_size); From 3a88fd437dfb218df5d3338c8ee7d70416839cf8 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Tue, 3 Sep 2024 06:58:29 +0000 Subject: [PATCH 10/29] 8334724: C2: remove PhaseIdealLoop::cast_incr_before_loop() Reviewed-by: chagedorn, kvn --- src/hotspot/share/opto/loopTransform.cpp | 36 ++++-------------------- src/hotspot/share/opto/loopnode.hpp | 6 ++-- src/hotspot/share/opto/loopopts.cpp | 23 +++++++++++++++ 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index 99742a598e858..6e53705464366 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -1309,19 +1309,6 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr return n; } -Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) { - Node* castii = new CastIINode(ctrl, incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency); - register_new_node(castii, ctrl); - for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) { - Node* n = incr->fast_out(i); - if (n->is_Phi() && n->in(0) == loop) { - int nrep = n->replace_edge(incr, castii, &_igvn); - return castii; - } - } - return nullptr; -} - #ifdef ASSERT void PhaseIdealLoop::ensure_zero_trip_guard_proj(Node* node, bool is_main_loop) { assert(node->is_IfProj(), "must be the zero trip guard If node"); @@ -1680,14 +1667,11 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n // variable value and the induction variable Phi to preserve correct // dependencies. - // CastII for the main loop: - Node* castii = cast_incr_before_loop(pre_incr, min_taken, main_head); - assert(castii != nullptr, "no castII inserted"); assert(post_head->in(1)->is_IfProj(), "must be zero-trip guard If node projection of the post loop"); - copy_assertion_predicates_to_main_loop(pre_head, castii, stride, outer_loop, outer_main_head, dd_main_head, + copy_assertion_predicates_to_main_loop(pre_head, pre_incr, stride, outer_loop, outer_main_head, dd_main_head, idx_before_pre_post, idx_after_post_before_pre, min_taken, post_head->in(1), old_new); - copy_assertion_predicates_to_post_loop(outer_main_head, post_head, post_incr, stride); + copy_assertion_predicates_to_post_loop(outer_main_head, post_head, stride); // Step B4: Shorten the pre-loop to run only 1 iteration (for now). // RCE and alignment may change this later. @@ -1812,7 +1796,7 @@ void PhaseIdealLoop::insert_vector_post_loop(IdealLoopTree *loop, Node_List &old // In this case we throw away the result as we are not using it to connect anything else. CountedLoopNode *post_head = nullptr; insert_post_loop(loop, old_new, main_head, main_end, incr, limit, post_head); - copy_assertion_predicates_to_post_loop(main_head->skip_strip_mined(), post_head, incr, main_head->stride()); + copy_assertion_predicates_to_post_loop(main_head->skip_strip_mined(), post_head, main_head->stride()); // It's difficult to be precise about the trip-counts // for post loops. They are usually very short, @@ -1915,10 +1899,6 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new, } } - // CastII for the new post loop: - incr = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head); - assert(incr != nullptr, "no castII inserted"); - return new_main_exit; } @@ -1934,12 +1914,6 @@ bool IdealLoopTree::is_invariant(Node* n) const { // to the new stride. void PhaseIdealLoop::update_main_loop_assertion_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, const int stride_con) { - if (init->is_CastII()) { - // skip over the cast added by PhaseIdealLoop::cast_incr_before_loop() when pre/post/main loops are created because - // it can get in the way of type propagation - assert(init->as_CastII()->carry_dependency() && loop_head->skip_assertion_predicates_with_halt() == init->in(0), "casted iv phi from pre loop expected"); - init = init->in(1); - } Node* entry = ctrl; Node* prev_proj = ctrl; LoopNode* outer_loop_head = loop_head->skip_strip_mined(); @@ -1988,7 +1962,9 @@ void PhaseIdealLoop::update_main_loop_assertion_predicates(Node* ctrl, CountedLo // Go over the Assertion Predicates of the main loop and make a copy for the post loop with its initial iv value and // stride as inputs. void PhaseIdealLoop::copy_assertion_predicates_to_post_loop(LoopNode* main_loop_head, CountedLoopNode* post_loop_head, - Node* init, Node* stride) { + Node* stride) { + Node* opaq = post_loop_head->is_canonical_loop_entry(); + Node* init = opaq->in(1); Node* post_loop_entry = post_loop_head->in(LoopNode::EntryControl); Node* main_loop_entry = main_loop_head->in(LoopNode::EntryControl); IdealLoopTree* post_loop = get_loop(post_loop_head); diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 1217caa41eba4..369f446adbbd7 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -938,8 +938,6 @@ class PhaseIdealLoop : public PhaseTransform { return ctrl; } - Node* cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); - #ifdef ASSERT void ensure_zero_trip_guard_proj(Node* node, bool is_main_loop); #endif @@ -960,7 +958,7 @@ class PhaseIdealLoop : public PhaseTransform { static bool assertion_predicate_has_loop_opaque_node(IfNode* iff); static void get_assertion_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque = false); void update_main_loop_assertion_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con); - void copy_assertion_predicates_to_post_loop(LoopNode* main_loop_head, CountedLoopNode* post_loop_head, Node* init, + void copy_assertion_predicates_to_post_loop(LoopNode* main_loop_head, CountedLoopNode* post_loop_head, Node* stride); void initialize_assertion_predicates_for_peeled_loop(const PredicateBlock* predicate_block, LoopNode* outer_loop_head, int dd_outer_loop_head, Node* init, Node* stride, @@ -1534,6 +1532,8 @@ class PhaseIdealLoop : public PhaseTransform { // Attempt to use a conditional move instead of a phi/branch Node *conditional_move( Node *n ); + bool split_thru_phi_could_prevent_vectorization(Node* n, Node* n_blk); + // Check for aggressive application of 'split-if' optimization, // using basic block level info. void split_if_with_blocks ( VectorSet &visited, Node_Stack &nstack); diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index b838b15032f70..7f42d2d4beb42 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1089,6 +1089,25 @@ void PhaseIdealLoop::try_move_store_after_loop(Node* n) { } } +// Split some nodes that take a counted loop phi as input at a counted +// loop can cause vectorization of some expressions to fail +bool PhaseIdealLoop::split_thru_phi_could_prevent_vectorization(Node* n, Node* n_blk) { + if (!n_blk->is_CountedLoop()) { + return false; + } + + int opcode = n->Opcode(); + + if (opcode != Op_AndI && + opcode != Op_MulI && + opcode != Op_RotateRight && + opcode != Op_RShiftI) { + return false; + } + + return n->in(1) == n_blk->as_BaseCountedLoop()->phi(); +} + //------------------------------split_if_with_blocks_pre----------------------- // Do the real work in a non-recursive function. Data nodes want to be // cloned in the pre-order so they can feed each other nicely. @@ -1175,6 +1194,10 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) { return n; } + if (split_thru_phi_could_prevent_vectorization(n, n_blk)) { + return n; + } + // Check for having no control input; not pinned. Allow // dominating control. if (n->in(0)) { From dc4fd896289db1d2f6f7bbf5795fec533448a48c Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Tue, 3 Sep 2024 06:58:44 +0000 Subject: [PATCH 11/29] 8339359: RISC-V: Use auipc explicitly in far_jump and far_call macro assembler routines Reviewed-by: rehn, luhenry --- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index ab4d89f2d7528..a4eaab9b0285e 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3530,14 +3530,18 @@ void MacroAssembler::atomic_cas( void MacroAssembler::far_jump(const Address &entry, Register tmp) { assert(CodeCache::find_blob(entry.target()) != nullptr, - "destination of far call not found in code cache"); + "destination of far jump not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type || entry.rspec().type() == relocInfo::runtime_call_type || entry.rspec().type() == relocInfo::none, "wrong entry relocInfo type"); // Fixed length: see MacroAssembler::far_branch_size() + // We can use auipc + jr here because we know that the total size of + // the code cache cannot exceed 2Gb. relocate(entry.rspec(), [&] { - int32_t offset; - la(tmp, entry.target(), offset); + int64_t distance = entry.target() - pc(); + int32_t offset = ((int32_t)distance << 20) >> 20; + assert(is_valid_32bit_offset(distance), "Far jump using wrong instructions."); + auipc(tmp, (int32_t)distance + 0x800); jr(tmp, offset); }); } @@ -3552,8 +3556,11 @@ void MacroAssembler::far_call(const Address &entry, Register tmp) { // We can use auipc + jalr here because we know that the total size of // the code cache cannot exceed 2Gb. relocate(entry.rspec(), [&] { - assert(is_valid_32bit_offset(entry.target() - pc()), "Far call using wrong instructions."); - call(entry.target(), tmp); + int64_t distance = entry.target() - pc(); + int32_t offset = ((int32_t)distance << 20) >> 20; + assert(is_valid_32bit_offset(distance), "Far call using wrong instructions."); + auipc(tmp, (int32_t)distance + 0x800); + jalr(tmp, offset); }); } From 288fa60ebee445bb2835f096d144b9c6dea98df6 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Tue, 3 Sep 2024 07:56:04 +0000 Subject: [PATCH 12/29] 8338891: HotSpotDiagnosticsMXBean missing @since tag Reviewed-by: alanb --- .../classes/com/sun/management/HotSpotDiagnosticMXBean.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index b1d86a743a5c3..cb8b3bdf0a620 100644 --- a/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -47,6 +47,8 @@ * {@code null} unless it's stated otherwise. * * @see java.lang.management.ManagementFactory#getPlatformMXBeans(Class) + * + * @since 1.6 */ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { /** From ed422ed1a3d6cdb733bc878c4173b43eb2dfb3da Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Tue, 3 Sep 2024 07:56:14 +0000 Subject: [PATCH 13/29] 8338817: Wrong indent in API docs for java.lang.management.ManagementFactory Reviewed-by: alanb, dfuchs --- .../share/classes/java/lang/management/ManagementFactory.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/src/java.management/share/classes/java/lang/management/ManagementFactory.java index b1ac1d0391e54..a95102cd1258b 100644 --- a/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,6 @@ *

* An application can access a platform MXBean in the following ways: *

1. Direct access to an MXBean interface

- *
*
    *
  • Get an MXBean instance by calling the * {@link #getPlatformMXBean(Class) getPlatformMXBean} or @@ -130,7 +129,6 @@ * for details. *
  • *
- *
* *

* The {@link #getPlatformManagementInterfaces getPlatformManagementInterfaces} From 6f3e3fd0d4f5e80e3fdbd26be6483c672479802a Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 3 Sep 2024 09:27:59 +0000 Subject: [PATCH 14/29] 8339411: [PPC64] cmpxchgw/h/b doesn't handle external Label Reviewed-by: lucy, mbaesken --- src/hotspot/cpu/ppc/macroAssembler_ppc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index 0af384a36fabe..faca90990c893 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -1737,7 +1737,7 @@ void MacroAssembler::cmpxchg_generic(ConditionRegister flag, Register dest_curre cmpxchg_loop_body(flag, dest_current_value, compare_value, exchange_value, addr_base, tmp1, tmp2, retry, failed, cmpxchgx_hint, size); - if (!weak || use_result_reg) { + if (!weak || use_result_reg || failed_ext) { if (UseStaticBranchPredictionInCompareAndSwapPPC64) { bne_predict_not_taken(CCR0, weak ? failed : retry); // StXcx_ sets CCR0. } else { From 633fad8e53109bef52190494a8b171035229d2ac Mon Sep 17 00:00:00 2001 From: Damon Fenacci Date: Tue, 3 Sep 2024 09:45:43 +0000 Subject: [PATCH 15/29] 8326615: C1/C2 don't handle allocation failure properly during initialization (RuntimeStub::new_runtime_stub fatal crash) Reviewed-by: thartmann, kvn --- src/hotspot/share/code/codeCache.cpp | 2 +- src/hotspot/share/compiler/compilationPolicy.cpp | 2 +- .../share/compiler/compilerDefinitions.cpp | 5 ++--- .../share/compiler/compilerDefinitions.hpp | 2 ++ .../share/compiler/compilerDefinitions.inline.hpp | 15 +++++++++++++++ test/hotspot/jtreg/ProblemList.txt | 2 -- .../codecache/CheckSegmentedCodeCache.java | 15 ++++++++++++--- 7 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index a491dd62f070e..11e070862fe2f 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -205,7 +205,7 @@ void CodeCache::initialize_heaps() { const bool cache_size_set = FLAG_IS_CMDLINE(ReservedCodeCacheSize); const size_t ps = page_size(false, 8); const size_t min_size = MAX2(os::vm_allocation_granularity(), ps); - const size_t min_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3); // Make sure we have enough space for VM internal code + const size_t min_cache_size = CompilerConfig::min_code_cache_size(); // Make sure we have enough space for VM internal code size_t cache_size = align_up(ReservedCodeCacheSize, min_size); // Prerequisites diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index 0e6d8f6a6c91b..8fc70619abe7e 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -455,7 +455,7 @@ void CompilationPolicy::initialize() { c2_size = C2Compiler::initial_code_buffer_size(); #endif size_t buffer_size = c1_only ? c1_size : (c1_size/3 + 2*c2_size/3); - int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size; + int max_count = (ReservedCodeCacheSize - (int)CompilerConfig::min_code_cache_size()) / (int)buffer_size; if (count > max_count) { // Lower the compiler count such that all buffers fit into the code cache count = MAX2(max_count, c1_only ? 1 : 2); diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp index 0a04afad9aaee..ee0c73254f180 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.cpp +++ b/src/hotspot/share/compiler/compilerDefinitions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -475,8 +475,7 @@ void CompilerConfig::set_jvmci_specific_flags() { bool CompilerConfig::check_args_consistency(bool status) { // Check lower bounds of the code cache - // Template Interpreter code is approximately 3X larger in debug builds. - uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3); + size_t min_code_cache_size = CompilerConfig::min_code_cache_size(); if (ReservedCodeCacheSize < InitialCodeCacheSize) { jio_fprintf(defaultStream::error_stream(), "Invalid ReservedCodeCacheSize: %dK. Must be at least InitialCodeCacheSize=%dK.\n", diff --git a/src/hotspot/share/compiler/compilerDefinitions.hpp b/src/hotspot/share/compiler/compilerDefinitions.hpp index 03b7d446b1ab3..a72e82e32bd56 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.hpp @@ -148,6 +148,8 @@ class CompilerConfig : public AllStatic { inline static bool is_c2_or_jvmci_compiler_only(); inline static bool is_c2_or_jvmci_compiler_enabled(); + inline static size_t min_code_cache_size(); + private: static bool is_compilation_mode_selected(); static void set_compilation_policy_flags(); diff --git a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp index d490387672dad..5557892669ddd 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp @@ -25,6 +25,12 @@ #ifndef SHARE_COMPILER_COMPILERDEFINITIONS_INLINE_HPP #define SHARE_COMPILER_COMPILERDEFINITIONS_INLINE_HPP +#ifdef COMPILER1 +#include "c1/c1_Compiler.hpp" +#endif +#ifdef COMPILER2 +#include "opto/c2compiler.hpp" +#endif #include "compiler/compilerDefinitions.hpp" #include "compiler/compiler_globals.hpp" @@ -132,4 +138,13 @@ inline bool CompilerConfig::is_c2_or_jvmci_compiler_enabled() { return is_c2_enabled() || is_jvmci_compiler_enabled(); } +inline size_t CompilerConfig::min_code_cache_size() { + size_t min_code_cache_size = CodeCacheMinimumUseSpace; + // Template Interpreter code is approximately 3X larger in debug builds. + DEBUG_ONLY(min_code_cache_size *= 3); + COMPILER1_PRESENT(min_code_cache_size += Compiler::code_buffer_size()); + COMPILER2_PRESENT(min_code_cache_size += C2Compiler::initial_code_buffer_size()); + return min_code_cache_size; +} + #endif // SHARE_COMPILER_COMPILERDEFINITIONS_INLINE_HPP diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 664ba0175a2ec..e5ac630c3384b 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -73,8 +73,6 @@ compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInf compiler/floatingpoint/TestSubnormalFloat.java 8317810 generic-i586 compiler/floatingpoint/TestSubnormalDouble.java 8317810 generic-i586 -compiler/startup/StartupOutput.java 8326615 generic-x64 - compiler/codecache/CodeCacheFullCountTest.java 8332954 generic-all compiler/interpreter/Test6833129.java 8335266 generic-i586 diff --git a/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java b/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java index 0c4fb5a66ae93..d0b45333fb8b3 100644 --- a/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java +++ b/test/hotspot/jtreg/compiler/codecache/CheckSegmentedCodeCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -187,8 +187,17 @@ public static void main(String[] args) throws Exception { // Fails if not enough space for VM internal code long minUseSpace = WHITE_BOX.getUintxVMFlag("CodeCacheMinimumUseSpace"); - // minimum size: CodeCacheMinimumUseSpace DEBUG_ONLY(* 3) - long minSize = (Platform.isDebugBuild() ? 3 : 1) * minUseSpace; + long nMethodSizeLimit = WHITE_BOX.getIntxVMFlag("NMethodSizeLimit"); + long codeEntryAlignment = WHITE_BOX.getIntxVMFlag("CodeEntryAlignment"); + long c1MinCodeCacheSize = 11 * nMethodSizeLimit / 10; + long c2MinCodeCacheSize = 2048 /* PhaseOutput::MAX_inst_size */ + + 128 /* PhaseOutput::MAX_stubs_size */ + + 4 * 1024 /* initial_const_capacity */ + + 2 * Math.max(64, codeEntryAlignment) /* 2 * CodeSection::end_slop() */ + + 2 * 128 /* sizeof(relocInfo) * PhaseOutput::MAX_locs_size */; + // minimum size: CompilerConfig::min_code_cache_size = + // CodeCacheMinimumUseSpace DEBUG_ONLY(* 3) + Compiler::code_buffer_size() + C2Compiler::initial_code_buffer_size()) + long minSize = minUseSpace * (Platform.isDebugBuild() ? 3 : 1) + c1MinCodeCacheSize + c2MinCodeCacheSize; pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+SegmentedCodeCache", "-XX:NonNMethodCodeHeapSize=" + minSize, "-XX:ReservedCodeCacheSize=" + minSize, From 7a418fc07464fe359a0b45b6d797c65c573770cb Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Tue, 3 Sep 2024 10:25:27 +0000 Subject: [PATCH 16/29] 8338967: Improve performance for MemorySegment::fill Reviewed-by: mcimadamore, psandoz --- .../foreign/AbstractMemorySegmentImpl.java | 49 ++++++- test/jdk/java/foreign/TestFill.java | 136 ++++++++++++++++++ .../bench/java/lang/foreign/TestFill.java | 95 ++++++++++++ 3 files changed, 277 insertions(+), 3 deletions(-) create mode 100644 test/jdk/java/foreign/TestFill.java create mode 100644 test/micro/org/openjdk/bench/java/lang/foreign/TestFill.java diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index 75be22ac454fa..5d43c28a66711 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -51,6 +51,7 @@ import jdk.internal.misc.ScopedMemoryAccess; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.util.Architecture; import jdk.internal.util.ArraysSupport; import jdk.internal.util.Preconditions; import jdk.internal.vm.annotation.ForceInline; @@ -188,10 +189,52 @@ public Stream elements(MemoryLayout elementLayout) { return StreamSupport.stream(spliterator(elementLayout), false); } + // FILL_NATIVE_THRESHOLD must be a power of two and should be greater than 2^3 + // Update the value for Aarch64 once 8338975 is fixed. + private static final long FILL_NATIVE_THRESHOLD = 1L << (Architecture.isAARCH64() ? 10 : 5); + @Override - public final MemorySegment fill(byte value){ - checkAccess(0, length, false); - SCOPED_MEMORY_ACCESS.setMemory(sessionImpl(), unsafeGetBase(), unsafeGetOffset(), length, value); + @ForceInline + public final MemorySegment fill(byte value) { + checkReadOnly(false); + if (length == 0) { + // Implicit state check + checkValidState(); + } else if (length < FILL_NATIVE_THRESHOLD) { + // 0 <= length < FILL_NATIVE_LIMIT : 0...0X...XXXX + + // Handle smaller segments directly without transitioning to native code + final long u = Byte.toUnsignedLong(value); + final long longValue = u << 56 | u << 48 | u << 40 | u << 32 | u << 24 | u << 16 | u << 8 | u; + + int offset = 0; + // 0...0X...X000 + final int limit = (int) (length & (FILL_NATIVE_THRESHOLD - 8)); + for (; offset < limit; offset += 8) { + SCOPED_MEMORY_ACCESS.putLong(sessionImpl(), unsafeGetBase(), unsafeGetOffset() + offset, longValue); + } + int remaining = (int) length - limit; + // 0...0X00 + if (remaining >= 4) { + SCOPED_MEMORY_ACCESS.putInt(sessionImpl(), unsafeGetBase(), unsafeGetOffset() + offset, (int) longValue); + offset += 4; + remaining -= 4; + } + // 0...00X0 + if (remaining >= 2) { + SCOPED_MEMORY_ACCESS.putShort(sessionImpl(), unsafeGetBase(), unsafeGetOffset() + offset, (short) longValue); + offset += 2; + remaining -= 2; + } + // 0...000X + if (remaining == 1) { + SCOPED_MEMORY_ACCESS.putByte(sessionImpl(), unsafeGetBase(), unsafeGetOffset() + offset, value); + } + // We have now fully handled 0...0X...XXXX + } else { + // Handle larger segments via native calls + SCOPED_MEMORY_ACCESS.setMemory(sessionImpl(), unsafeGetBase(), unsafeGetOffset(), length, value); + } return this; } diff --git a/test/jdk/java/foreign/TestFill.java b/test/jdk/java/foreign/TestFill.java new file mode 100644 index 0000000000000..e5f69587f2f6c --- /dev/null +++ b/test/jdk/java/foreign/TestFill.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Test MemorySegment::fill + * @run junit TestFill + */ + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.foreign.Arena; +import java.lang.foreign.ValueLayout; +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +final class TestFill { + + // Make sure negative values are treated as expected + private static final byte VALUE = -71; + + @ParameterizedTest + @MethodSource("sizes") + void testFill(int len) { + int offset = 16; + int expandedLen = offset + MAX_SIZE + offset; + + // Make sure fill only affects the intended region XXXXXX + // + // ................XXXXXX................ + // | offset | len | offset | + + try (var arena = Arena.ofConfined()) { + var segment = arena.allocate(expandedLen); + var slice = segment.asSlice(offset, len); + slice.fill(VALUE); + + var expected = new byte[expandedLen]; + Arrays.fill(expected, offset, offset + len, VALUE); + + // This checks the actual fill region as well as potential under and overflows + assertArrayEquals(expected, segment.toArray(ValueLayout.JAVA_BYTE)); + } + } + + @ParameterizedTest + @MethodSource("values") + void testValues(int value) { + int size = 0b1111; + try (var arena = Arena.ofConfined()) { + var segment = arena.allocate(size); + segment.fill((byte) value); + assertTrue(segment.elements(ValueLayout.JAVA_BYTE) + .map(s -> s.get(ValueLayout.JAVA_BYTE, 0)) + .allMatch(v -> v == value), "Failed to fill with value " + value); + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testReadOnly(int len) { + try (var arena = Arena.ofConfined()) { + var segment = arena.allocate(10).asReadOnly(); + assertThrows(IllegalArgumentException.class, () -> segment.fill(VALUE)); + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testConfinement(int len) { + try (var arena = Arena.ofConfined()) { + var segment = arena.allocate(10); + AtomicReference ex = new AtomicReference<>(); + CompletableFuture future = CompletableFuture.runAsync(() -> { + try { + segment.fill(VALUE); + } catch (RuntimeException e) { + ex.set(e); + } + }); + future.join(); + assertInstanceOf(WrongThreadException.class, ex.get()); + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testScope(int len) { + var arena = Arena.ofConfined(); + var segment = arena.allocate(len); + arena.close(); + assertThrows(IllegalStateException.class, () -> segment.fill(VALUE)); + } + + private static final int MAX_SIZE = 1 << 10; + + private static Stream sizes() { + return IntStream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 23, 32, 63, 128, 256, 511, MAX_SIZE) + .boxed() + .map(Arguments::of); + } + + private static Stream values() { + return IntStream.rangeClosed(Byte.MIN_VALUE, Byte.MAX_VALUE) + .boxed() + .map(Arguments::of); + } + +} diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/TestFill.java b/test/micro/org/openjdk/bench/java/lang/foreign/TestFill.java new file mode 100644 index 0000000000000..78719f03bc377 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/foreign/TestFill.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package org.openjdk.bench.java.lang.foreign; + +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.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Fork(value = 3) +public class TestFill { + + @Param({"0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "30", "31", + "32", "128", "256", "384", "511", "512"}) + public int ELEM_SIZE; + + byte[] array; + MemorySegment heapSegment; + MemorySegment nativeSegment; + MemorySegment unalignedSegment; + ByteBuffer buffer; + + @Setup + public void setup() { + array = new byte[ELEM_SIZE]; + heapSegment = MemorySegment.ofArray(array); + nativeSegment = Arena.ofAuto().allocate(ELEM_SIZE, 8); + unalignedSegment = Arena.ofAuto().allocate(ELEM_SIZE + 1, 8).asSlice(1); + buffer = ByteBuffer.wrap(array); + } + + @Benchmark + public void arrays_fill() { + Arrays.fill(array, (byte) 0); + } + + @Benchmark + public void heap_segment_fill() { + heapSegment.fill((byte) 0); + } + + @Benchmark + public void native_segment_fill() { + nativeSegment.fill((byte) 0); + } + + @Benchmark + public void unaligned_segment_fill() { + unalignedSegment.fill((byte) 0); + } + +} From 8ea6adc623ca2183046d794eba806065deea916e Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 3 Sep 2024 12:02:49 +0000 Subject: [PATCH 17/29] 8339364: AIX build fails: various unused variable and function warnings Reviewed-by: mdoerr, clanger, jwaters --- make/modules/java.desktop/lib/AwtLibraries.gmk | 12 +++++++++--- .../unix/native/libjava/ProcessHandleImpl_unix.c | 3 --- src/java.base/unix/native/libjava/TimeZone_md.c | 8 ++------ .../aix/native/libawt_xawt/awt/awt_InputMethod.c | 3 --- src/java.desktop/unix/native/common/awt/CUPSfuncs.c | 1 - src/java.desktop/unix/native/common/awt/X11Color.c | 13 +++++-------- src/java.desktop/unix/native/common/awt/fontpath.c | 10 ++-------- .../native/common/java2d/x11/X11FontScaler_md.c | 6 ++---- .../unix/native/common/java2d/x11/X11Renderer.c | 1 - .../unix/native/common/java2d/x11/X11SurfaceData.c | 4 +--- .../native/common/java2d/x11/X11TextRenderer_md.c | 4 +--- .../unix/native/libawt_xawt/awt/awt_GraphicsEnv.c | 5 +---- .../unix/native/libawt_xawt/awt/multiVis.c | 4 ---- .../unix/native/libsplashscreen/splashscreen_sys.c | 7 ++----- 14 files changed, 25 insertions(+), 56 deletions(-) diff --git a/make/modules/java.desktop/lib/AwtLibraries.gmk b/make/modules/java.desktop/lib/AwtLibraries.gmk index f2c97612ba167..aaf5100d83b37 100644 --- a/make/modules/java.desktop/lib/AwtLibraries.gmk +++ b/make/modules/java.desktop/lib/AwtLibraries.gmk @@ -181,8 +181,11 @@ ifeq ($(call isTargetOs, windows macosx), false) $(X_CFLAGS), \ EXTRA_HEADER_DIRS := $(LIBAWT_HEADLESS_EXTRA_HEADER_DIRS), \ DISABLED_WARNINGS_gcc := unused-variable, \ + DISABLED_WARNINGS_clang := unused-variable, \ DISABLED_WARNINGS_gcc_X11Renderer.c := unused-function, \ DISABLED_WARNINGS_gcc_X11SurfaceData.c := unused-function, \ + DISABLED_WARNINGS_clang_X11Renderer.c := unused-function, \ + DISABLED_WARNINGS_clang_X11SurfaceData.c := unused-function, \ JDK_LIBS := libawt java.base:libjava, \ LIBS_linux := $(LIBDL) $(LIBM), \ STATIC_LIB_EXCLUDE_OBJS := $(LIBAWT_HEADLESS_STATIC_EXCLUDE_OBJS), \ @@ -238,6 +241,7 @@ ifeq ($(call isTargetOs, windows macosx)+$(ENABLE_HEADLESS_ONLY), false+false) CFLAGS := -DXAWT -DXAWT_HACK $(LIBAWT_XAWT_CFLAGS) \ $(FONTCONFIG_CFLAGS) $(CUPS_CFLAGS) $(X_CFLAGS), \ DISABLED_WARNINGS_gcc := int-to-pointer-cast unused-variable, \ + DISABLED_WARNINGS_clang := unused-variable, \ DISABLED_WARNINGS_gcc_awt_Taskbar.c := parentheses, \ DISABLED_WARNINGS_gcc_GLXSurfaceData.c := unused-function, \ DISABLED_WARNINGS_gcc_gtk3_interface.c := parentheses type-limits \ @@ -256,20 +260,22 @@ ifeq ($(call isTargetOs, windows macosx)+$(ENABLE_HEADLESS_ONLY), false+false) DISABLED_WARNINGS_gcc_XToolkit.c := unused-result, \ DISABLED_WARNINGS_gcc_XWindow.c := unused-function, \ DISABLED_WARNINGS_clang_awt_Taskbar.c := parentheses, \ - DISABLED_WARNINGS_clang_gtk3_interface.c := parentheses, \ + DISABLED_WARNINGS_clang_gtk3_interface.c := unused-function parentheses, \ + DISABLED_WARNINGS_clang_GLXSurfaceData.c := unused-function, \ DISABLED_WARNINGS_clang_OGLBufImgOps.c := format-nonliteral, \ DISABLED_WARNINGS_clang_OGLPaints.c := format-nonliteral, \ DISABLED_WARNINGS_clang_screencast_pipewire.c := format-nonliteral, \ DISABLED_WARNINGS_clang_sun_awt_X11_GtkFileDialogPeer.c := parentheses, \ + DISABLED_WARNINGS_clang_XWindow.c := unused-function, \ DISABLED_WARNINGS_clang_aix := deprecated-non-prototype, \ DISABLED_WARNINGS_clang_aix_awt_Taskbar.c := parentheses, \ DISABLED_WARNINGS_clang_aix_OGLPaints.c := format-nonliteral, \ DISABLED_WARNINGS_clang_aix_OGLBufImgOps.c := format-nonliteral, \ - DISABLED_WARNINGS_clang_aix_gtk3_interface.c := parentheses \ + DISABLED_WARNINGS_clang_aix_gtk3_interface.c := unused-function parentheses \ logical-op-parentheses, \ DISABLED_WARNINGS_clang_aix_sun_awt_X11_GtkFileDialogPeer.c := \ parentheses, \ - DISABLED_WARNINGS_clang_aix_awt_InputMethod.c := sign-compare, \ + DISABLED_WARNINGS_clang_aix_awt_InputMethod.c := unused-function sign-compare, \ JDK_LIBS := libawt java.base:libjava, \ LIBS_unix := $(LIBDL) $(LIBM) $(X_LIBS) -lX11 -lXext -lXi -lXrender \ -lXtst, \ diff --git a/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c b/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c index 57d911e35de0a..acc7f0c73c903 100644 --- a/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c +++ b/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c @@ -661,11 +661,8 @@ pid_t unix_getParentPidAndTimings(JNIEnv *env, pid_t pid, void unix_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { psinfo_t psinfo; - char fn[32]; - char exePath[PATH_MAX]; char prargs[PRARGSZ + 1]; jstring cmdexe = NULL; - int ret; /* * Now try to open /proc/%d/psinfo diff --git a/src/java.base/unix/native/libjava/TimeZone_md.c b/src/java.base/unix/native/libjava/TimeZone_md.c index 988c4bd2646f9..bc55f099bd95a 100644 --- a/src/java.base/unix/native/libjava/TimeZone_md.c +++ b/src/java.base/unix/native/libjava/TimeZone_md.c @@ -41,8 +41,6 @@ #include "TimeZone_md.h" #include "path_util.h" -static char *isFileIdentical(char* buf, size_t size, char *pathname); - #define fileopen fopen #define filegets fgets #define fileclose fclose @@ -59,11 +57,8 @@ static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime"; static const char popularZones[][4] = {"UTC", "GMT"}; -#if defined(_AIX) -static const char *ETC_ENVIRONMENT_FILE = "/etc/environment"; -#endif - #if defined(__linux__) || defined(MACOSX) +static char *isFileIdentical(char* buf, size_t size, char *pathname); /* * remove repeated path separators ('/') in the given 'path'. @@ -356,6 +351,7 @@ getPlatformTimeZoneID() } #elif defined(_AIX) +static const char *ETC_ENVIRONMENT_FILE = "/etc/environment"; static char * getPlatformTimeZoneID() diff --git a/src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c b/src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c index 4907200db72e8..908b7cca653cc 100644 --- a/src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c +++ b/src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c @@ -493,9 +493,6 @@ static StatusWindow *createStatusWindow(Window parent) { XWindowAttributes xwa; XWindowAttributes xxwa; /* Variable for XCreateFontSet()*/ - char **mclr; - int mccr = 0; - char *dsr; unsigned long bg, fg, light, dim; int x, y, off_x, off_y, xx, yy; unsigned int w, h, bw, depth; diff --git a/src/java.desktop/unix/native/common/awt/CUPSfuncs.c b/src/java.desktop/unix/native/common/awt/CUPSfuncs.c index 216da01e0cd62..173d44d96c845 100644 --- a/src/java.desktop/unix/native/common/awt/CUPSfuncs.c +++ b/src/java.desktop/unix/native/common/awt/CUPSfuncs.c @@ -202,7 +202,6 @@ Java_sun_print_CUPSPrinter_getCupsDefaultPrinter(JNIEnv *env, cups_dest_t *dests; char *defaultPrinter = NULL; int num_dests = j2d_cupsGetDests(&dests); - int i = 0; cups_dest_t *dest = j2d_cupsGetDest(NULL, NULL, num_dests, dests); if (dest != NULL) { defaultPrinter = dest->name; diff --git a/src/java.desktop/unix/native/common/awt/X11Color.c b/src/java.desktop/unix/native/common/awt/X11Color.c index 6d3f4e7b246e9..2d3fd48091489 100644 --- a/src/java.desktop/unix/native/common/awt/X11Color.c +++ b/src/java.desktop/unix/native/common/awt/X11Color.c @@ -338,7 +338,7 @@ awt_allocate_colors(AwtGraphicsConfigDataPtr awt_data) unsigned char reds[256], greens[256], blues[256]; int indices[256]; Colormap cm; - int i, j, k, cmapsize, nfree, depth, bpp; + int i, k, cmapsize, nfree, depth, bpp; int allocatedColorsNum, unavailableColorsNum; XPixmapFormatValues *pPFV; int numpfv; @@ -878,7 +878,6 @@ awt_allocate_colors(AwtGraphicsConfigDataPtr awt_data) jobject getColorSpace(JNIEnv* env, jint csID) { jclass clazz; - jobject cspaceL; jmethodID mid; clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace"); @@ -1033,7 +1032,6 @@ jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) jobject validBits = NULL; ColorEntry *c; int i, allocAllGray, b, allvalid, paletteSize; - jlong pData; if (aData->awt_visInfo.depth == 12) { paletteSize = MAX_PALETTE12_SIZE; @@ -1233,11 +1231,10 @@ jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) void awt_allocate_systemrgbcolors (jint *rgbColors, int num_colors, AwtGraphicsConfigDataPtr awtData) { - int i, pixel; - for (i = 0; i < num_colors; i++) - pixel = alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]), - green (rgbColors [i]), blue (rgbColors [i]), -1, - awtData); + for (int i = 0; i < num_colors; i++) + alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]), + green (rgbColors [i]), blue (rgbColors [i]), -1, + awtData); } int diff --git a/src/java.desktop/unix/native/common/awt/fontpath.c b/src/java.desktop/unix/native/common/awt/fontpath.c index b270a3fc94d7f..2da0ec0328bee 100644 --- a/src/java.desktop/unix/native/common/awt/fontpath.c +++ b/src/java.desktop/unix/native/common/awt/fontpath.c @@ -100,7 +100,6 @@ typedef struct { jboolean isDisplayLocal(JNIEnv *env) { static jboolean isLocal = False; static jboolean isLocalSet = False; - jboolean ret; if (! isLocalSet) { jclass geCls = (*env)->FindClass(env, "java/awt/GraphicsEnvironment"); @@ -134,7 +133,7 @@ jboolean isDisplayLocal(JNIEnv *env) { static char **getX11FontPath () { char **x11Path, **fontdirs; - int i, pos, slen, nPaths, numDirs; + int i, pos, slen, nPaths; x11Path = XGetFontPath (awt_display, &nPaths); @@ -533,7 +532,6 @@ static char **getFontConfigLocations() { char **fontdirs; int numdirs = 0; - FcInitLoadConfigFuncType FcInitLoadConfig; FcPatternBuildFuncType FcPatternBuild; FcObjectSetFuncType FcObjectSetBuild; FcFontListFuncType FcFontList; @@ -543,14 +541,10 @@ static char **getFontConfigLocations() { FcObjectSetDestroyFuncType FcObjectSetDestroy; FcFontSetDestroyFuncType FcFontSetDestroy; - FcConfig *fontconfig; FcPattern *pattern; FcObjectSet *objset; FcFontSet *fontSet; - FcStrList *strList; - FcChar8 *str; - int i, f, found, len=0; - char **fontPath; + int i, f, found; void* libfontconfig = openFontConfig(); diff --git a/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c b/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c index 2ab6f287b690f..521b7cfef3ab4 100644 --- a/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c +++ b/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c @@ -43,8 +43,6 @@ static GC pixmapGC = 0; static Pixmap pixmap = 0; -static Atom psAtom = 0; -static Atom fullNameAtom = 0; static int pixmapWidth = 0; static int pixmapHeight = 0; @@ -127,9 +125,9 @@ JNIEXPORT int JNICALL AWTCountFonts(char* xlfd) { } JNIEXPORT void JNICALL AWTLoadFont(char* name, AWTFont *pReturn) { - JNIEnv *env; *pReturn = NULL; #ifndef HEADLESS + JNIEnv *env; FONT_AWT_LOCK(); *pReturn = (AWTFont)XLoadQueryFont(awt_display, name); AWT_UNLOCK(); @@ -268,7 +266,7 @@ JNIEXPORT jlong JNICALL AWTFontGenerateImage(AWTFont pFont, AWTChar2b* xChar) { XCharStruct xcs; XImage *ximage; int h, i, j, nbytes; - unsigned char *srcRow, *dstRow, *dstByte; + unsigned char *srcRow, *dstRow; int wholeByteCount, remainingBitsCount; unsigned int imageSize; JNIEnv *env; diff --git a/src/java.desktop/unix/native/common/java2d/x11/X11Renderer.c b/src/java.desktop/unix/native/common/java2d/x11/X11Renderer.c index 871c129ca913d..216fe8090ff2e 100644 --- a/src/java.desktop/unix/native/common/java2d/x11/X11Renderer.c +++ b/src/java.desktop/unix/native/common/java2d/x11/X11Renderer.c @@ -571,7 +571,6 @@ Java_sun_java2d_x11_X11Renderer_XDoPath #ifndef HEADLESS X11SDOps *xsdo = (X11SDOps *) pXSData; jarray typesArray; - jobject pointArray; jarray coordsArray; jint numTypes; jint fillRule; diff --git a/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c b/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c index 36d6feb6029a7..e62ccff4653a2 100644 --- a/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c +++ b/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c @@ -882,11 +882,9 @@ static void X11SD_GetRasInfo(JNIEnv *env, } else #endif /* MITSHM */ if (xpriv->lockType == X11SD_LOCK_BY_XIMAGE) { - int x, y, w, h; + int x, y; x = pRasInfo->bounds.x1; y = pRasInfo->bounds.y1; - w = pRasInfo->bounds.x2 - x; - h = pRasInfo->bounds.y2 - y; xpriv->img = X11SD_GetImage(env, xsdo, &pRasInfo->bounds, lockFlags); if (xpriv->img) { diff --git a/src/java.desktop/unix/native/common/java2d/x11/X11TextRenderer_md.c b/src/java.desktop/unix/native/common/java2d/x11/X11TextRenderer_md.c index c7aff6f34c84f..d50ef00f94532 100644 --- a/src/java.desktop/unix/native/common/java2d/x11/X11TextRenderer_md.c +++ b/src/java.desktop/unix/native/common/java2d/x11/X11TextRenderer_md.c @@ -213,7 +213,7 @@ AWTDrawGlyphList(JNIEnv *env, jobject xtr, XImage *theImage; Pixmap thePixmap; XGCValues xgcv; - int scan, screen; + int screen; AwtGraphicsConfigDataPtr cData; X11SDOps *xsdo = (X11SDOps *)jlong_to_ptr(dstData); jint cx1, cy1, cx2, cy2; @@ -236,8 +236,6 @@ AWTDrawGlyphList(JNIEnv *env, jobject xtr, thePixmap = cData->monoPixmap; theGC = cData->monoPixmapGC; - scan = theImage->bytes_per_line; - xgcv.fill_style = FillStippled; xgcv.stipple = thePixmap; xgcv.ts_x_origin = bounds->x1; diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c index aa2e88940dcae..33d2aeb66bbc1 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c @@ -304,7 +304,6 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { AwtGraphicsConfigDataPtr *graphicsConfigs; AwtGraphicsConfigDataPtr defaultConfig; int ind; - char errmsg[128]; int xinawareScreen; void* xrenderLibHandle = NULL; XRenderFindVisualFormatFunc* xrenderFindVisualFormat = NULL; @@ -722,7 +721,6 @@ awt_init_Display(JNIEnv *env, jobject this) jclass klass; Display *dpy; char errmsg[128]; - int i; if (awt_display) { return awt_display; @@ -872,7 +870,6 @@ extern int mitShmPermissionMask; void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps) { XShmSegmentInfo shminfo; int XShmMajor, XShmMinor; - int a, b, c; AWT_LOCK(); if (canUseShmExt != UNSET_MITSHM) { @@ -1154,7 +1151,7 @@ JNIEnv *env, jobject this, jint visualNum, jint screen) AwtGraphicsConfigData *adata = NULL; AwtScreenData asd = x11Screens[screen]; - int i, n; + int i; int depth; XImage * tempImage; diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/multiVis.c b/src/java.desktop/unix/native/libawt_xawt/awt/multiVis.c index e2e3cd1180948..93c1f4d0c1a3f 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/multiVis.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/multiVis.c @@ -793,8 +793,6 @@ static list_ptr make_region_list(Display *disp, Window win, XRectangle *bbox, XRectangle clip; int image_only; - int count=0 ; - *hasNonDefault = False; XUnionRectWithRegion( bbox, bbox_region, bbox_region); XGetWindowAttributes( disp, win, &win_attrs); @@ -823,8 +821,6 @@ static list_ptr make_region_list(Display *disp, Window win, XRectangle *bbox, malloc( sizeof( image_region_type)))) { return (list_ptr) NULL; } - count++; - new_reg->visible_region = XCreateRegion(); new_reg->win = base_src->win; new_reg->vis = base_src->vis; diff --git a/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c b/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c index e990cd9014a04..5a008d10a482c 100644 --- a/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c +++ b/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c @@ -209,7 +209,7 @@ FreeColors(Display * display, Screen * screen, int numColors, } static void SplashCenter(Splash * splash) { - Atom type, atom, actual_type; + Atom atom, actual_type; int status, actual_format; unsigned long nitems, bytes_after; CARD16 *prop = NULL; @@ -251,8 +251,6 @@ static void SplashUpdateSizeHints(Splash * splash) { void SplashCreateWindow(Splash * splash) { - XSizeHints sizeHints; - XSetWindowAttributes attr; attr.backing_store = NotUseful; @@ -740,11 +738,10 @@ void SplashCreateThread(Splash * splash) { pthread_t thr; pthread_attr_t attr; - int rc; int rslt = pthread_attr_init(&attr); if (rslt != 0) return; - rc = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash); + pthread_create(&thr, &attr, SplashScreenThread, (void *) splash); pthread_attr_destroy(&attr); } From b94c3debf5083dbf5bc21ed7794c1656743ab48e Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Tue, 3 Sep 2024 12:05:02 +0000 Subject: [PATCH 18/29] 8339401: Optimize ClassFile load and store instructions Reviewed-by: liach, redestad --- .../classfile/impl/BytecodeHelpers.java | 187 +++++++++++------- .../classfile/impl/DirectCodeBuilder.java | 63 ++++++ 2 files changed, 178 insertions(+), 72 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java index 51285d8236b30..058be41198b73 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,83 +57,125 @@ public static IllegalArgumentException cannotConvertException(TypeKind from, Typ public static Opcode loadOpcode(TypeKind tk, int slot) { return switch (tk) { - case INT, SHORT, BYTE, CHAR, BOOLEAN -> switch (slot) { - case 0 -> Opcode.ILOAD_0; - case 1 -> Opcode.ILOAD_1; - case 2 -> Opcode.ILOAD_2; - case 3 -> Opcode.ILOAD_3; - default -> (slot < 256) ? Opcode.ILOAD : Opcode.ILOAD_W; - }; - case LONG -> switch (slot) { - case 0 -> Opcode.LLOAD_0; - case 1 -> Opcode.LLOAD_1; - case 2 -> Opcode.LLOAD_2; - case 3 -> Opcode.LLOAD_3; - default -> (slot < 256) ? Opcode.LLOAD : Opcode.LLOAD_W; - }; - case DOUBLE -> switch (slot) { - case 0 -> Opcode.DLOAD_0; - case 1 -> Opcode.DLOAD_1; - case 2 -> Opcode.DLOAD_2; - case 3 -> Opcode.DLOAD_3; - default -> (slot < 256) ? Opcode.DLOAD : Opcode.DLOAD_W; - }; - case FLOAT -> switch (slot) { - case 0 -> Opcode.FLOAD_0; - case 1 -> Opcode.FLOAD_1; - case 2 -> Opcode.FLOAD_2; - case 3 -> Opcode.FLOAD_3; - default -> (slot < 256) ? Opcode.FLOAD : Opcode.FLOAD_W; - }; - case REFERENCE -> switch (slot) { - case 0 -> Opcode.ALOAD_0; - case 1 -> Opcode.ALOAD_1; - case 2 -> Opcode.ALOAD_2; - case 3 -> Opcode.ALOAD_3; - default -> (slot < 256) ? Opcode.ALOAD : Opcode.ALOAD_W; - }; - case VOID -> throw new IllegalArgumentException("void"); + case INT, SHORT, BYTE, CHAR, BOOLEAN + -> iload(slot); + case LONG -> lload(slot); + case DOUBLE -> dload(slot); + case FLOAT -> fload(slot); + case REFERENCE -> aload(slot); + case VOID -> throw new IllegalArgumentException("void"); + }; + } + + public static Opcode aload(int slot) { + return switch (slot) { + case 0 -> Opcode.ALOAD_0; + case 1 -> Opcode.ALOAD_1; + case 2 -> Opcode.ALOAD_2; + case 3 -> Opcode.ALOAD_3; + default -> (slot < 256) ? Opcode.ALOAD : Opcode.ALOAD_W; + }; + } + + public static Opcode fload(int slot) { + return switch (slot) { + case 0 -> Opcode.FLOAD_0; + case 1 -> Opcode.FLOAD_1; + case 2 -> Opcode.FLOAD_2; + case 3 -> Opcode.FLOAD_3; + default -> (slot < 256) ? Opcode.FLOAD : Opcode.FLOAD_W; + }; + } + + public static Opcode dload(int slot) { + return switch (slot) { + case 0 -> Opcode.DLOAD_0; + case 1 -> Opcode.DLOAD_1; + case 2 -> Opcode.DLOAD_2; + case 3 -> Opcode.DLOAD_3; + default -> (slot < 256) ? Opcode.DLOAD : Opcode.DLOAD_W; + }; + } + + public static Opcode lload(int slot) { + return switch (slot) { + case 0 -> Opcode.LLOAD_0; + case 1 -> Opcode.LLOAD_1; + case 2 -> Opcode.LLOAD_2; + case 3 -> Opcode.LLOAD_3; + default -> (slot < 256) ? Opcode.LLOAD : Opcode.LLOAD_W; + }; + } + + public static Opcode iload(int slot) { + return switch (slot) { + case 0 -> Opcode.ILOAD_0; + case 1 -> Opcode.ILOAD_1; + case 2 -> Opcode.ILOAD_2; + case 3 -> Opcode.ILOAD_3; + default -> (slot < 256) ? Opcode.ILOAD : Opcode.ILOAD_W; }; } public static Opcode storeOpcode(TypeKind tk, int slot) { return switch (tk) { - case INT, SHORT, BYTE, CHAR, BOOLEAN -> switch (slot) { - case 0 -> Opcode.ISTORE_0; - case 1 -> Opcode.ISTORE_1; - case 2 -> Opcode.ISTORE_2; - case 3 -> Opcode.ISTORE_3; - default -> (slot < 256) ? Opcode.ISTORE : Opcode.ISTORE_W; - }; - case LONG -> switch (slot) { - case 0 -> Opcode.LSTORE_0; - case 1 -> Opcode.LSTORE_1; - case 2 -> Opcode.LSTORE_2; - case 3 -> Opcode.LSTORE_3; - default -> (slot < 256) ? Opcode.LSTORE : Opcode.LSTORE_W; - }; - case DOUBLE -> switch (slot) { - case 0 -> Opcode.DSTORE_0; - case 1 -> Opcode.DSTORE_1; - case 2 -> Opcode.DSTORE_2; - case 3 -> Opcode.DSTORE_3; - default -> (slot < 256) ? Opcode.DSTORE : Opcode.DSTORE_W; - }; - case FLOAT -> switch (slot) { - case 0 -> Opcode.FSTORE_0; - case 1 -> Opcode.FSTORE_1; - case 2 -> Opcode.FSTORE_2; - case 3 -> Opcode.FSTORE_3; - default -> (slot < 256) ? Opcode.FSTORE : Opcode.FSTORE_W; - }; - case REFERENCE -> switch (slot) { - case 0 -> Opcode.ASTORE_0; - case 1 -> Opcode.ASTORE_1; - case 2 -> Opcode.ASTORE_2; - case 3 -> Opcode.ASTORE_3; - default -> (slot < 256) ? Opcode.ASTORE : Opcode.ASTORE_W; - }; - case VOID -> throw new IllegalArgumentException("void"); + case INT, SHORT, BYTE, CHAR, BOOLEAN + -> istore(slot); + case LONG -> lstore(slot); + case DOUBLE -> dstore(slot); + case FLOAT -> fstore(slot); + case REFERENCE -> astore(slot); + case VOID -> throw new IllegalArgumentException("void"); + }; + } + + public static Opcode astore(int slot) { + return switch (slot) { + case 0 -> Opcode.ASTORE_0; + case 1 -> Opcode.ASTORE_1; + case 2 -> Opcode.ASTORE_2; + case 3 -> Opcode.ASTORE_3; + default -> (slot < 256) ? Opcode.ASTORE : Opcode.ASTORE_W; + }; + } + + public static Opcode fstore(int slot) { + return switch (slot) { + case 0 -> Opcode.FSTORE_0; + case 1 -> Opcode.FSTORE_1; + case 2 -> Opcode.FSTORE_2; + case 3 -> Opcode.FSTORE_3; + default -> (slot < 256) ? Opcode.FSTORE : Opcode.FSTORE_W; + }; + } + + public static Opcode dstore(int slot) { + return switch (slot) { + case 0 -> Opcode.DSTORE_0; + case 1 -> Opcode.DSTORE_1; + case 2 -> Opcode.DSTORE_2; + case 3 -> Opcode.DSTORE_3; + default -> (slot < 256) ? Opcode.DSTORE : Opcode.DSTORE_W; + }; + } + + public static Opcode lstore(int slot) { + return switch (slot) { + case 0 -> Opcode.LSTORE_0; + case 1 -> Opcode.LSTORE_1; + case 2 -> Opcode.LSTORE_2; + case 3 -> Opcode.LSTORE_3; + default -> (slot < 256) ? Opcode.LSTORE : Opcode.LSTORE_W; + }; + } + + public static Opcode istore(int slot) { + return switch (slot) { + case 0 -> Opcode.ISTORE_0; + case 1 -> Opcode.ISTORE_1; + case 2 -> Opcode.ISTORE_2; + case 3 -> Opcode.ISTORE_3; + default -> (slot < 256) ? Opcode.ISTORE : Opcode.ISTORE_W; }; } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java index 9bc4abf069266..e2dcc982e6b5b 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +64,8 @@ import static java.lang.classfile.Opcode.*; +import static jdk.internal.classfile.impl.BytecodeHelpers.*; + public final class DirectCodeBuilder extends AbstractDirectBuilder implements TerminalCodeBuilder { @@ -855,6 +858,12 @@ public CodeBuilder aconst_null() { return this; } + @Override + public CodeBuilder aload(int slot) { + writeLocalVar(BytecodeHelpers.aload(slot), slot); + return this; + } + @Override public CodeBuilder anewarray(ClassEntry entry) { writeNewReferenceArray(entry); @@ -867,6 +876,12 @@ public CodeBuilder arraylength() { return this; } + @Override + public CodeBuilder astore(int slot) { + writeLocalVar(BytecodeHelpers.astore(slot), slot); + return this; + } + @Override public CodeBuilder athrow() { writeBytecode(ATHROW); @@ -940,6 +955,12 @@ public CodeBuilder ddiv() { return this; } + @Override + public CodeBuilder dload(int slot) { + writeLocalVar(BytecodeHelpers.dload(slot), slot); + return this; + } + @Override public CodeBuilder dmul() { writeBytecode(DMUL); @@ -958,6 +979,12 @@ public CodeBuilder drem() { return this; } + @Override + public CodeBuilder dstore(int slot) { + writeLocalVar(BytecodeHelpers.dstore(slot), slot); + return this; + } + @Override public CodeBuilder dsub() { writeBytecode(DSUB); @@ -1060,6 +1087,12 @@ public CodeBuilder fdiv() { return this; } + @Override + public CodeBuilder fload(int slot) { + writeLocalVar(BytecodeHelpers.fload(slot), slot); + return this; + } + @Override public CodeBuilder fmul() { writeBytecode(FMUL); @@ -1078,6 +1111,12 @@ public CodeBuilder frem() { return this; } + @Override + public CodeBuilder fstore(int slot) { + writeLocalVar(BytecodeHelpers.fstore(slot), slot); + return this; + } + @Override public CodeBuilder fsub() { writeBytecode(FSUB); @@ -1186,6 +1225,12 @@ public CodeBuilder iinc(int slot, int val) { return this; } + @Override + public CodeBuilder iload(int slot) { + writeLocalVar(BytecodeHelpers.iload(slot), slot); + return this; + } + @Override public CodeBuilder imul() { writeBytecode(IMUL); @@ -1270,6 +1315,12 @@ public CodeBuilder ishr() { return this; } + @Override + public CodeBuilder istore(int slot) { + writeLocalVar(BytecodeHelpers.istore(slot), slot); + return this; + } + @Override public CodeBuilder isub() { writeBytecode(ISUB); @@ -1354,6 +1405,12 @@ public CodeBuilder ldiv() { return this; } + @Override + public CodeBuilder lload(int slot) { + writeLocalVar(BytecodeHelpers.lload(slot), slot); + return this; + } + @Override public CodeBuilder lmul() { writeBytecode(LMUL); @@ -1390,6 +1447,12 @@ public CodeBuilder lshr() { return this; } + @Override + public CodeBuilder lstore(int slot) { + writeLocalVar(BytecodeHelpers.lstore(slot), slot); + return this; + } + @Override public CodeBuilder lsub() { writeBytecode(LSUB); From e0c46d589b12aa644e12e4a4c9e84e035f7cf98d Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 3 Sep 2024 12:55:23 +0000 Subject: [PATCH 19/29] 8325397: sun/java2d/Disposer/TestDisposerRace.java fails in linux-aarch64 Reviewed-by: alanb --- .../locks/AbstractQueuedLongSynchronizer.java | 44 +++++++++++-- .../locks/AbstractQueuedSynchronizer.java | 44 +++++++++++-- .../sun/java2d/Disposer/TestDisposerRace.java | 61 +++++++++++++++---- 3 files changed, 126 insertions(+), 23 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 2de1d17e7c18c..95ac1b2e46fc2 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -277,6 +277,40 @@ private static void signalNextIfShared(Node h) { } } + /** + * Repeatedly invokes acquire, if its execution throws an Error or a Runtime Exception, + * using an Unsafe.park-based backoff + * @param node which to reacquire + * @param arg the acquire argument + */ + private final void reacquire(Node node, long arg) { + try { + acquire(node, arg, false, false, false, 0L); + } catch (Error | RuntimeException firstEx) { + // While we currently do not emit an JFR events in this situation, mainly + // because the conditions under which this happens are such that it + // cannot be presumed to be possible to actually allocate an event, and + // using a preconstructed one would have limited value in serviceability. + // Having said that, the following place would be the more appropriate + // place to put such logic: + // emit JFR event + + for (long nanos = 1L;;) { + U.park(false, nanos); // must use Unsafe park to sleep + if (nanos < 1L << 30) // max about 1 second + nanos <<= 1; + + try { + acquire(node, arg, false, false, false, 0L); + } catch (Error | RuntimeException ignored) { + continue; + } + + throw firstEx; + } + } + } + /** * Main acquire method, invoked by all exported acquire methods. * @@ -1299,7 +1333,7 @@ else if ((node.status & COND) != 0) { } LockSupport.setCurrentBlocker(null); node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (interrupted) Thread.currentThread().interrupt(); } @@ -1346,7 +1380,7 @@ public final void await() throws InterruptedException { } LockSupport.setCurrentBlocker(null); node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (interrupted) { if (cancelled) { unlinkCancelledWaiters(node); @@ -1389,7 +1423,7 @@ public final long awaitNanos(long nanosTimeout) LockSupport.parkNanos(this, nanos); } node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) @@ -1433,7 +1467,7 @@ public final boolean awaitUntil(Date deadline) LockSupport.parkUntil(this, abstime); } node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) @@ -1478,7 +1512,7 @@ public final boolean await(long time, TimeUnit unit) LockSupport.parkNanos(this, nanos); } node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 2ea0d3ed3b091..6794bab3110b8 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -656,6 +656,40 @@ private static void signalNextIfShared(Node h) { } } + /** + * Repeatedly invokes acquire, if its execution throws an Error or a Runtime Exception, + * using an Unsafe.park-based backoff + * @param node which to reacquire + * @param arg the acquire argument + */ + private final void reacquire(Node node, int arg) { + try { + acquire(node, arg, false, false, false, 0L); + } catch (Error | RuntimeException firstEx) { + // While we currently do not emit an JFR events in this situation, mainly + // because the conditions under which this happens are such that it + // cannot be presumed to be possible to actually allocate an event, and + // using a preconstructed one would have limited value in serviceability. + // Having said that, the following place would be the more appropriate + // place to put such logic: + // emit JFR event + + for (long nanos = 1L;;) { + U.park(false, nanos); // must use Unsafe park to sleep + if (nanos < 1L << 30) // max about 1 second + nanos <<= 1; + + try { + acquire(node, arg, false, false, false, 0L); + } catch (Error | RuntimeException ignored) { + continue; + } + + throw firstEx; + } + } + } + /** * Main acquire method, invoked by all exported acquire methods. * @@ -1678,7 +1712,7 @@ else if ((node.status & COND) != 0) { } LockSupport.setCurrentBlocker(null); node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (interrupted) Thread.currentThread().interrupt(); } @@ -1725,7 +1759,7 @@ public final void await() throws InterruptedException { } LockSupport.setCurrentBlocker(null); node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (interrupted) { if (cancelled) { unlinkCancelledWaiters(node); @@ -1768,7 +1802,7 @@ public final long awaitNanos(long nanosTimeout) LockSupport.parkNanos(this, nanos); } node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) @@ -1812,7 +1846,7 @@ public final boolean awaitUntil(Date deadline) LockSupport.parkUntil(this, abstime); } node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) @@ -1857,7 +1891,7 @@ public final boolean await(long time, TimeUnit unit) LockSupport.parkNanos(this, nanos); } node.clearStatus(); - acquire(node, savedState, false, false, false, 0L); + reacquire(node, savedState); if (cancelled) { unlinkCancelledWaiters(node); if (interrupted) diff --git a/test/jdk/sun/java2d/Disposer/TestDisposerRace.java b/test/jdk/sun/java2d/Disposer/TestDisposerRace.java index e22e59799515c..b78966f1200b2 100644 --- a/test/jdk/sun/java2d/Disposer/TestDisposerRace.java +++ b/test/jdk/sun/java2d/Disposer/TestDisposerRace.java @@ -23,6 +23,7 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; import javax.swing.SwingUtilities; import sun.java2d.Disposer; @@ -39,16 +40,23 @@ public final class TestDisposerRace { private static final AtomicInteger recordsCount = new AtomicInteger(); private static volatile boolean disposerDone = false; + private static final String KO_OVERFLOW = "Some records have not been disposed!"; + private static final String KO_UNDERFLOW = "Disposed more records than were added!"; + public static void main(String[] args) throws Exception { - TestDisposerRace test = new TestDisposerRace(); - test.run(); + new TestDisposerRace().run(); checkRecordsCountIsSane(); if (recordsCount.get() > 0) { + System.err.println(KO_OVERFLOW); // In case the next line fails to allocate due to OOME throw new RuntimeException("Some records (" + recordsCount + ") have not been disposed"); } } + interface ThrowingRunnable { + void run() throws E; + } + TestDisposerRace() { addRecordsToDisposer(30_000); } @@ -56,14 +64,14 @@ public static void main(String[] args) throws Exception { void run() throws Exception { generateOOME(); for (int i = 0; i < 1000; ++i) { - SwingUtilities.invokeAndWait(Disposer::pollRemove); - if (i % 10 == 0) { - // Adding records will race with the diposer trying to remove them + retryOnOOME(() -> SwingUtilities.invokeAndWait(Disposer::pollRemove)); + + // Adding records will race with the diposer trying to remove them + if (i % 10 == 0) addRecordsToDisposer(1000); - } } - Disposer.addObjectRecord(new Object(), new FinalDisposerRecord()); + retryOnOOME(() -> Disposer.addObjectRecord(new Object(), new FinalDisposerRecord())); while (!disposerDone) { generateOOME(); @@ -72,18 +80,45 @@ void run() throws Exception { private static void checkRecordsCountIsSane() { if (recordsCount.get() < 0) { - throw new RuntimeException("Disposed more records than were added"); + throw new RuntimeException(KO_UNDERFLOW); + } + } + + private static T retryOnOOME(Supplier allocator) { + for(;;) { + try { + return allocator.get(); + } catch (OutOfMemoryError ignored1) { + try { + Thread.sleep(1); // Give GC a little chance to run + } catch (InterruptedException ignored2) {} + } + } + } + + private static void retryOnOOME(ThrowingRunnable tr) throws E { + for(;;) { + try { + tr.run(); + break; + } catch (OutOfMemoryError ignored1) { + try { + Thread.sleep(1); // Give GC a little chance to run + } catch (InterruptedException ignored2) {} + } } } private void addRecordsToDisposer(int count) { checkRecordsCountIsSane(); - recordsCount.addAndGet(count); + MyDisposerRecord disposerRecord = retryOnOOME(MyDisposerRecord::new); - MyDisposerRecord disposerRecord = new MyDisposerRecord(); - for (int i = 0; i < count; i++) { - Disposer.addObjectRecord(new Object(), disposerRecord); + while(count > 0) { + recordsCount.incrementAndGet(); // pre-add to make sure it doesn't go negative + var o = retryOnOOME(Object::new); + retryOnOOME(() -> Disposer.addObjectRecord(o, disposerRecord)); + --count; } } @@ -106,8 +141,8 @@ private static void giveGCAChance() { } private static void generateOOME() throws Exception { - final List leak = new LinkedList<>(); try { + final List leak = new LinkedList<>(); while (true) { leak.add(new byte[1024 * 1024]); } From 4ca2c208ea2b308093b4a25b04a274f9b1ec6a1d Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Tue, 3 Sep 2024 13:32:50 +0000 Subject: [PATCH 20/29] 8338740: java/net/httpclient/HttpsTunnelAuthTest.java fails with java.io.IOException: HTTP/1.1 header parser received no bytes Reviewed-by: djelinski, jpai --- test/jdk/java/net/httpclient/ProxyServer.java | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/test/jdk/java/net/httpclient/ProxyServer.java b/test/jdk/java/net/httpclient/ProxyServer.java index e07badd2bb7aa..7de14a79225a5 100644 --- a/test/jdk/java/net/httpclient/ProxyServer.java +++ b/test/jdk/java/net/httpclient/ProxyServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -195,6 +195,9 @@ class Connection { volatile InputStream clientIn, serverIn; volatile OutputStream clientOut, serverOut; + boolean proxyInClosed; // only accessed from synchronized block + boolean proxyOutClosed; // only accessed from synchronized block + final static int CR = 13; final static int LF = 10; @@ -594,9 +597,7 @@ synchronized void proxyCommon(boolean log) throws IOException { if (log) System.out.printf("Proxy Forwarding [request body]: total %d%n", body); } - closing = true; - serverSocket.close(); - clientSocket.close(); + closeClientIn(); } catch (IOException e) { if (!closing && debug) { System.out.println("Proxy: " + e); @@ -615,9 +616,7 @@ synchronized void proxyCommon(boolean log) throws IOException { if (log) System.out.printf("Proxy Forwarding [response]: %s%n", new String(bb, 0, n, UTF_8)); if (log) System.out.printf("Proxy Forwarding [response]: total %d%n", resp); } - closing = true; - serverSocket.close(); - clientSocket.close(); + closeClientOut(); } catch (IOException e) { if (!closing && debug) { System.out.println("Proxy: " + e); @@ -641,6 +640,28 @@ void doTunnel(String dest) throws IOException { proxyCommon(false); } + synchronized void closeClientIn() throws IOException { + closing = true; + proxyInClosed = true; + clientSocket.shutdownInput(); + serverSocket.shutdownOutput(); + if (proxyOutClosed) { + serverSocket.close(); + clientSocket.close(); + } + } + + synchronized void closeClientOut() throws IOException { + closing = true; + proxyOutClosed = true; + serverSocket.shutdownInput(); + clientSocket.shutdownOutput(); + if (proxyInClosed) { + serverSocket.close(); + clientSocket.close(); + } + } + @Override public String toString() { return "Proxy connection " + id + ", client sock:" + clientSocket; From ad40a122d632d65052b71125c0dfd58c54e3a521 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Tue, 3 Sep 2024 13:44:48 +0000 Subject: [PATCH 21/29] 8339214: Remove misleading CodeBuilder.loadConstant(Opcode, ConstantDesc) Reviewed-by: asotona --- .../java/lang/classfile/CodeBuilder.java | 29 +---- .../instruction/ConstantInstruction.java | 18 ++- .../classfile/impl/BytecodeHelpers.java | 54 +------- .../classfile/impl/ClassRemapperImpl.java | 3 +- .../classfile/impl/DirectCodeBuilder.java | 15 --- .../jfr/internal/EventInstrumentation.java | 4 +- test/jdk/jdk/classfile/AdaptCodeTest.java | 2 +- test/jdk/jdk/classfile/LDCTest.java | 6 +- .../jdk/classfile/OpcodesValidationTest.java | 116 +++--------------- .../InstructionModelToCodeBuilder.java | 4 +- 10 files changed, 50 insertions(+), 201 deletions(-) diff --git a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java index fd63788336fd3..75413011731e4 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java @@ -604,23 +604,6 @@ default CodeBuilder conversion(TypeKind fromType, TypeKind toType) { return this; } - /** - * Generate an instruction pushing a constant onto the operand stack - * @see Opcode.Kind#CONSTANT - * @param opcode the constant instruction opcode - * @param value the constant value - * @return this builder - * @since 23 - */ - default CodeBuilder loadConstant(Opcode opcode, ConstantDesc value) { - BytecodeHelpers.validateValue(opcode, value); - return with(switch (opcode) { - case SIPUSH, BIPUSH -> ConstantInstruction.ofArgument(opcode, ((Number)value).intValue()); - case LDC, LDC_W, LDC2_W -> ConstantInstruction.ofLoad(opcode, BytecodeHelpers.constantEntry(constantPool(), value)); - default -> ConstantInstruction.ofIntrinsic(opcode); - }); - } - /** * Generate an instruction pushing a constant onto the operand stack * @param value the constant value @@ -931,12 +914,12 @@ default CodeBuilder bastore() { } /** - * Generate an instruction pushing a byte onto the operand stack - * @param b the byte + * Generate an instruction pushing an int in the range of byte onto the operand stack. + * @param b the int in the range of byte * @return this builder */ default CodeBuilder bipush(int b) { - return loadConstant(Opcode.BIPUSH, b); + return with(ConstantInstruction.ofArgument(Opcode.BIPUSH, b)); } /** @@ -2396,12 +2379,12 @@ default CodeBuilder sastore() { } /** - * Generate an instruction pushing a short onto the operand stack - * @param s the short + * Generate an instruction pushing an int in the range of short onto the operand stack. + * @param s the int in the range of short * @return this builder */ default CodeBuilder sipush(int s) { - return loadConstant(Opcode.SIPUSH, s); + return with(ConstantInstruction.ofArgument(Opcode.SIPUSH, s)); } /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java index a7ba9e2a6a10f..022c45fdeef4d 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import java.lang.classfile.TypeKind; import java.lang.classfile.constantpool.LoadableConstantEntry; import jdk.internal.classfile.impl.AbstractInstruction; +import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; import jdk.internal.javac.PreviewFeature; @@ -144,16 +145,21 @@ static IntrinsicConstantInstruction ofIntrinsic(Opcode op) { /** * {@return an argument constant instruction} * - * @param op the opcode for the specific type of intrinsic constant instruction, - * which must be of kind {@link Opcode.Kind#CONSTANT} + * @param op the opcode for the specific type of argument constant instruction, + * which must be {@link Opcode#BIPUSH} or {@link Opcode#SIPUSH} * @param value the constant value * @throws IllegalArgumentException if the opcode is not {@link Opcode#BIPUSH} - * or {@link Opcode#SIPUSH} + * or {@link Opcode#SIPUSH}, or if the constant value is out of range + * for the opcode */ static ArgumentConstantInstruction ofArgument(Opcode op, int value) { - Util.checkKind(op, Opcode.Kind.CONSTANT); - if (op != Opcode.BIPUSH && op != Opcode.SIPUSH) + if (op == Opcode.BIPUSH) { + BytecodeHelpers.validateBipush(value); + } else if (op == Opcode.SIPUSH) { + BytecodeHelpers.validateSipush(value); + } else { throw new IllegalArgumentException(String.format("Wrong opcode specified; found %s, expected BIPUSH or SIPUSH", op)); + } return new AbstractInstruction.UnboundArgumentConstantInstruction(op, value); } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java index 058be41198b73..e52d198e1f423 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java @@ -277,40 +277,20 @@ public static Opcode convertOpcode(TypeKind from, TypeKind to) { }; } - static void validateSipush(long value) { - if (value < Short.MIN_VALUE || Short.MAX_VALUE < value) + public static void validateSipush(int value) { + if (value != (short) value) throw new IllegalArgumentException( "SIPUSH: value must be within: Short.MIN_VALUE <= value <= Short.MAX_VALUE, found: " .concat(Long.toString(value))); } - static void validateBipush(long value) { - if (value < Byte.MIN_VALUE || Byte.MAX_VALUE < value) + public static void validateBipush(int value) { + if (value != (byte) value) throw new IllegalArgumentException( "BIPUSH: value must be within: Byte.MIN_VALUE <= value <= Byte.MAX_VALUE, found: " .concat(Long.toString(value))); } - static void validateSipush(ConstantDesc d) { - if (d instanceof Integer iVal) { - validateSipush(iVal.longValue()); - } else if (d instanceof Long lVal) { - validateSipush(lVal.longValue()); - } else { - throw new IllegalArgumentException("SIPUSH: not an integral number: ".concat(d.toString())); - } - } - - static void validateBipush(ConstantDesc d) { - if (d instanceof Integer iVal) { - validateBipush(iVal.longValue()); - } else if (d instanceof Long lVal) { - validateBipush(lVal.longValue()); - } else { - throw new IllegalArgumentException("BIPUSH: not an integral number: ".concat(d.toString())); - } - } - public static MethodHandleEntry handleDescToHandleInfo(ConstantPoolBuilder constantPool, DirectMethodHandleDesc bootstrapMethod) { ClassEntry bsOwner = constantPool.classEntry(bootstrapMethod.owner()); NameAndTypeEntry bsNameAndType = constantPool.nameAndTypeEntry(constantPool.utf8Entry(bootstrapMethod.methodName()), @@ -341,32 +321,6 @@ static ConstantDynamicEntry handleConstantDescToHandleInfo(ConstantPoolBuilder c desc.constantType())); } - public static void validateValue(Opcode opcode, ConstantDesc v) { - switch (opcode) { - case ACONST_NULL -> { - if (v != null && v != ConstantDescs.NULL) - throw new IllegalArgumentException("value must be null or ConstantDescs.NULL with opcode ACONST_NULL"); - } - case SIPUSH -> - validateSipush(v); - case BIPUSH -> - validateBipush(v); - case LDC, LDC_W, LDC2_W -> { - if (v == null) - throw new IllegalArgumentException("`null` must use ACONST_NULL"); - } - default -> { - var exp = opcode.constantValue(); - if (exp == null) - throw new IllegalArgumentException("Can not use Opcode: " + opcode + " with constant()"); - if (v == null || !(v.equals(exp) || (exp instanceof Long l && v.equals(l.intValue())))) { - var t = (exp instanceof Long) ? "L" : (exp instanceof Float) ? "f" : (exp instanceof Double) ? "d" : ""; - throw new IllegalArgumentException("value must be " + exp + t + " with opcode " + opcode.name()); - } - } - } - } - public static Opcode ldcOpcode(LoadableConstantEntry entry) { return entry.typeKind().slotSize() == 2 ? Opcode.LDC2_W : entry.index() > 0xff ? Opcode.LDC_W diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java index 9b5e7639fa2a4..1d1d028531ecb 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassRemapperImpl.java @@ -258,8 +258,7 @@ public CodeTransform asCodeTransform() { cob.localVariableType(c.slot(), c.name().stringValue(), mapSignature(c.signatureSymbol()), c.startScope(), c.endScope()); case LoadConstantInstruction ldc -> - cob.loadConstant(ldc.opcode(), - mapConstantValue(ldc.constantValue())); + cob.ldc(mapConstantValue(ldc.constantValue())); case RuntimeVisibleTypeAnnotationsAttribute aa -> cob.with(RuntimeVisibleTypeAnnotationsAttribute.of( mapTypeAnnotations(aa.annotations()))); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java index e2dcc982e6b5b..1b950f28d004b 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java @@ -831,21 +831,6 @@ public CodeBuilder branch(Opcode op, Label target) { return this; } - @Override - public CodeBuilder loadConstant(Opcode opcode, ConstantDesc value) { - BytecodeHelpers.validateValue(opcode, value); - // avoid non-local enum switch for bootstrap - if (opcode == BIPUSH || opcode == SIPUSH) { - writeArgumentConstant(opcode, ((Number) value).intValue()); - } else if (opcode == LDC || opcode == LDC_W || opcode == LDC2_W) { - writeLoadConstant(opcode, BytecodeHelpers.constantEntry(constantPool(), value)); - } else { - // intrinsics - writeBytecode(opcode); - } - return this; - } - @Override public CodeBuilder nop() { writeBytecode(NOP); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java index 5521336f93859..71dc97d114e2c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java @@ -562,7 +562,7 @@ void updateStaticCommit(BlockCodeBuilder blockCodeBuilder, Label excluded) { // write begin event getEventConfiguration(blockCodeBuilder); // stack: [EW], [EW], [EventConfiguration] - blockCodeBuilder.loadConstant(Opcode.LDC2_W, eventTypeId); + blockCodeBuilder.loadConstant(eventTypeId); // stack: [EW], [EW], [EventConfiguration] [long] invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.BEGIN_EVENT.method()); // stack: [EW], [integer] @@ -676,7 +676,7 @@ void updateInstanceCommit(BlockCodeBuilder blockCodeBuilder, Label end, Label ex // stack: [EW] [EW] getEventConfiguration(blockCodeBuilder); // stack: [EW] [EW] [EC] - blockCodeBuilder.loadConstant(Opcode.LDC2_W, eventTypeId); + blockCodeBuilder.loadConstant(eventTypeId); invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.BEGIN_EVENT.method()); // stack: [EW] [int] blockCodeBuilder.ifeq(excluded); diff --git a/test/jdk/jdk/classfile/AdaptCodeTest.java b/test/jdk/jdk/classfile/AdaptCodeTest.java index ca9145d688521..80c526c63c736 100644 --- a/test/jdk/jdk/classfile/AdaptCodeTest.java +++ b/test/jdk/jdk/classfile/AdaptCodeTest.java @@ -95,7 +95,7 @@ void testSevenOfThirteenIterator() throws Exception { if ((val instanceof Integer) && ((Integer) val) == 13) { val = 7; } - codeB.loadConstant(i.opcode(), val); + codeB.loadConstant(val); } default -> codeB.with(codeE); } diff --git a/test/jdk/jdk/classfile/LDCTest.java b/test/jdk/jdk/classfile/LDCTest.java index 7379218840e30..207d53e88204c 100644 --- a/test/jdk/jdk/classfile/LDCTest.java +++ b/test/jdk/jdk/classfile/LDCTest.java @@ -64,9 +64,9 @@ void testLDCisConvertedToLDCW() throws Exception { for (int i = 0; i <= 256/2 + 2; i++) { // two entries per String StringEntry s = cpb.stringEntry("string" + i); } - c0.loadConstant(LDC, "string0") - .loadConstant(LDC, "string131") - .loadConstant(LDC, "string50") + c0.ldc("string0") + .ldc("string131") + .ldc("string50") .loadConstant(-0.0f) .loadConstant(-0.0d) //non-LDC test cases diff --git a/test/jdk/jdk/classfile/OpcodesValidationTest.java b/test/jdk/jdk/classfile/OpcodesValidationTest.java index f44bdfd272559..2470fcf132c54 100644 --- a/test/jdk/jdk/classfile/OpcodesValidationTest.java +++ b/test/jdk/jdk/classfile/OpcodesValidationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,107 +23,29 @@ /* * @test - * @summary Testing ClassFile constant instruction opcodes. + * @summary Testing ClassFile constant instruction argument validation. * @run junit OpcodesValidationTest */ -import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDesc; -import static java.lang.constant.ConstantDescs.CD_void; -import java.lang.constant.MethodTypeDesc; +import java.lang.classfile.instruction.ConstantInstruction; +import org.junit.jupiter.api.Test; -import java.lang.reflect.AccessFlag; -import java.lang.classfile.ClassFile; -import java.lang.classfile.Opcode; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.junit.jupiter.api.Assertions.*; import static java.lang.classfile.Opcode.*; -import java.util.stream.Stream; -public class OpcodesValidationTest { - - record Case(Opcode opcode, Object constant) {} - - static Stream positiveCases() { - return Stream.of( - new Case(ACONST_NULL, null), - new Case(SIPUSH, (int)Short.MIN_VALUE), - new Case(SIPUSH, (int)Short.MAX_VALUE), - new Case(BIPUSH, (int)Byte.MIN_VALUE), - new Case(BIPUSH, (int)Byte.MAX_VALUE), - new Case(ICONST_M1, -1), - new Case(ICONST_0, 0), - new Case(ICONST_1, 1), - new Case(ICONST_2, 2), - new Case(ICONST_3, 3), - new Case(ICONST_4, 4), - new Case(ICONST_5, 5), - new Case(LCONST_0, 0l), - new Case(LCONST_0, 0), - new Case(LCONST_1, 1l), - new Case(LCONST_1, 1), - new Case(FCONST_0, 0.0f), - new Case(FCONST_1, 1.0f), - new Case(FCONST_2, 2.0f), - new Case(DCONST_0, 0.0d), - new Case(DCONST_1, 1.0d) - ); - } - - static Stream negativeCases() { - return Stream.of( - new Case(ACONST_NULL, 0), - new Case(SIPUSH, (int)Short.MIN_VALUE - 1), - new Case(SIPUSH, (int)Short.MAX_VALUE + 1), - new Case(BIPUSH, (int)Byte.MIN_VALUE - 1), - new Case(BIPUSH, (int)Byte.MAX_VALUE + 1), - new Case(ICONST_M1, -1l), - new Case(ICONST_0, 0l), - new Case(ICONST_1, 1l), - new Case(ICONST_2, 2l), - new Case(ICONST_3, 3l), - new Case(ICONST_4, 4l), - new Case(ICONST_5, 5l), - new Case(LCONST_0, null), - new Case(LCONST_0, 1l), - new Case(LCONST_1, 1.0d), - new Case(LCONST_1, 0), - new Case(FCONST_0, 0.0d), - new Case(FCONST_1, 1.01f), - new Case(FCONST_2, 2), - new Case(DCONST_0, 0.0f), - new Case(DCONST_1, 1.0f), - new Case(DCONST_1, 1) - ); - } - - @TestFactory - Stream testPositiveCases() { - return positiveCases().map(c -> dynamicTest(c.toString(), () -> testPositiveCase(c.opcode, c.constant))); - } - - private void testPositiveCase(Opcode opcode, Object constant) { - ClassFile.of().build(ClassDesc.of("MyClass"), - cb -> cb.withFlags(AccessFlag.PUBLIC) - .withMethod("", MethodTypeDesc.of(CD_void), 0, - mb -> mb.withCode( - codeb -> codeb.loadConstant(opcode, (ConstantDesc) constant)))); - } - - - @TestFactory - Stream testNegativeCases() { - return negativeCases().map(c -> dynamicTest( - c.toString(), - () -> assertThrows(IllegalArgumentException.class, () -> testNegativeCase(c.opcode, c.constant)) - )); - } - - private void testNegativeCase(Opcode opcode, Object constant) { - ClassFile.of().build(ClassDesc.of("MyClass"), - cb -> cb.withFlags(AccessFlag.PUBLIC) - .withMethod("", MethodTypeDesc.of(CD_void), 0, - mb -> mb .withCode( - codeb -> codeb.loadConstant(opcode, (ConstantDesc)constant)))); +class OpcodesValidationTest { + + @Test + void testArgumentConstant() { + assertDoesNotThrow(() -> ConstantInstruction.ofArgument(SIPUSH, 0)); + assertDoesNotThrow(() -> ConstantInstruction.ofArgument(SIPUSH, Short.MIN_VALUE)); + assertDoesNotThrow(() -> ConstantInstruction.ofArgument(SIPUSH, Short.MAX_VALUE)); + assertDoesNotThrow(() -> ConstantInstruction.ofArgument(BIPUSH, 0)); + assertDoesNotThrow(() -> ConstantInstruction.ofArgument(BIPUSH, Byte.MIN_VALUE)); + assertDoesNotThrow(() -> ConstantInstruction.ofArgument(BIPUSH, Byte.MAX_VALUE)); + + assertThrows(IllegalArgumentException.class, () -> ConstantInstruction.ofArgument(SIPUSH, (int)Short.MIN_VALUE - 1)); + assertThrows(IllegalArgumentException.class, () -> ConstantInstruction.ofArgument(SIPUSH, (int)Short.MAX_VALUE + 1)); + assertThrows(IllegalArgumentException.class, () -> ConstantInstruction.ofArgument(BIPUSH, (int)Byte.MIN_VALUE - 1)); + assertThrows(IllegalArgumentException.class, () -> ConstantInstruction.ofArgument(BIPUSH, (int)Byte.MAX_VALUE + 1)); } } diff --git a/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java b/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java index d7d9e9c267f51..d865ddad5edb2 100644 --- a/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java +++ b/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ public static void toBuilder(CodeElement model, CodeBuilder cb) { case OperatorInstruction im -> cb.with(OperatorInstruction.of(im.opcode())); case ConstantInstruction im -> - cb.loadConstant(im.opcode(), im.constantValue()); + cb.loadConstant(im.constantValue()); case MonitorInstruction im -> cb.with(MonitorInstruction.of(im.opcode())); case NopInstruction im -> From 66945e501049de3a1e1d73303928af87190ae33c Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 3 Sep 2024 15:31:09 +0000 Subject: [PATCH 22/29] 8339336: Fix build system whitespace to adhere to coding conventions Reviewed-by: erikj --- make/Bundles.gmk | 4 +- make/CompileToolsJdk.gmk | 13 +- make/CopyInterimTZDB.gmk | 9 +- make/Docs.gmk | 2 +- make/Global.gmk | 4 +- make/Images.gmk | 8 +- make/Init.gmk | 4 +- make/InitSupport.gmk | 70 ++++---- make/JrtfsJar.gmk | 3 +- make/Main.gmk | 4 +- make/MainSupport.gmk | 6 +- make/RunTests.gmk | 5 +- make/RunTestsPrebuilt.gmk | 6 +- make/RunTestsPrebuiltSpec.gmk | 6 +- make/SourceRevision.gmk | 4 +- make/StaticLibsImage.gmk | 4 +- make/TestImage.gmk | 2 +- make/ToolsHotspot.gmk | 2 +- make/ToolsJdk.gmk | 4 +- make/ZipSecurity.gmk | 21 +-- make/autoconf/Makefile.template | 2 +- make/autoconf/basic.m4 | 28 ++-- make/autoconf/basic_tools.m4 | 22 +-- make/autoconf/boot-jdk.m4 | 6 +- make/autoconf/bootcycle-spec.gmk.template | 7 +- make/autoconf/compare.sh.template | 2 +- make/autoconf/configure.ac | 48 +++--- make/autoconf/flags-cflags.m4 | 4 +- make/autoconf/hotspot.m4 | 6 +- make/autoconf/jdk-options.m4 | 12 +- make/autoconf/jdk-version.m4 | 2 +- make/autoconf/jvm-features.m4 | 30 ++-- make/autoconf/lib-tests.m4 | 4 +- make/autoconf/platform.m4 | 6 +- make/autoconf/spec.gmk.template | 16 +- make/autoconf/toolchain.m4 | 4 +- make/autoconf/util.m4 | 36 ++--- make/autoconf/util_paths.m4 | 30 ++-- make/common/CopyFiles.gmk | 2 +- make/common/Execute.gmk | 2 +- make/common/FileUtils.gmk | 4 +- make/common/JarArchive.gmk | 130 +++++++-------- make/common/JavaCompilation.gmk | 150 +++++++++--------- make/common/JdkNativeCompilation.gmk | 4 +- make/common/MakeBase.gmk | 42 ++--- make/common/MakeIO.gmk | 10 +- make/common/Modules.gmk | 8 +- make/common/NativeCompilation.gmk | 2 +- make/common/ProcessMarkdown.gmk | 4 +- make/common/TestFilesCompilation.gmk | 8 +- make/common/TextFileProcessing.gmk | 42 ++--- make/common/Utils.gmk | 10 +- make/common/ZipArchive.gmk | 48 +++--- make/common/native/CompileFile.gmk | 6 +- make/devkit/Makefile | 2 +- make/devkit/Tools.gmk | 38 ++--- make/hotspot/CopyToExplodedJdk.gmk | 3 +- make/hotspot/lib/CompileGtest.gmk | 2 +- make/hotspot/lib/CompileJvm.gmk | 2 +- make/hotspot/lib/JvmOverrideFiles.gmk | 2 +- make/ide/eclipse/CreateWorkspace.gmk | 12 +- make/ide/idea/jdk/idea.gmk | 8 +- .../visualstudio/hotspot/CreateVSProject.gmk | 2 +- .../vscode/hotspot/CreateVSCodeProject.gmk | 4 +- make/modules/java.base/Copy.gmk | 4 +- make/modules/java.base/Lib.gmk | 2 +- .../modules/java.base/gensrc/GensrcBuffer.gmk | 142 ++++++++--------- .../java.base/gensrc/GensrcExceptions.gmk | 2 +- make/modules/java.base/gensrc/GensrcMisc.gmk | 2 +- .../gensrc/GensrcModuleLoaderMap.gmk | 2 +- make/modules/java.base/lib/CoreLibraries.gmk | 2 +- .../modules/java.desktop/lib/AwtLibraries.gmk | 2 +- .../java.desktop/lib/ClientLibraries.gmk | 5 +- make/modules/java.management/Lib.gmk | 2 +- make/modules/jdk.javadoc/Gensrc.gmk | 2 +- make/modules/jdk.jdeps/Gensrc.gmk | 2 +- make/modules/jdk.jlink/Launcher.gmk | 6 +- make/modules/jdk.management/Lib.gmk | 2 +- make/test/BuildMicrobenchmark.gmk | 2 +- make/test/JtregNativeHotspot.gmk | 54 ++++--- make/test/JtregNativeJdk.gmk | 5 +- 81 files changed, 624 insertions(+), 607 deletions(-) diff --git a/make/Bundles.gmk b/make/Bundles.gmk index 0901e415a8a1a..2ed04c1906421 100644 --- a/make/Bundles.gmk +++ b/make/Bundles.gmk @@ -284,7 +284,7 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), ) ifeq ($(MACOSX_CODESIGN_MODE), hardened) # Macosx release build and code signing available. - ################################################################################ + ############################################################################ # JDK bundle $(eval $(call SetupCopyFiles, CREATE_JDK_BUNDLE_DIR_SIGNED, \ SRC := $(JDK_IMAGE_DIR), \ @@ -313,7 +313,7 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), ) PRODUCT_TARGETS += $(BUILD_JDK_BUNDLE) - ################################################################################ + ############################################################################ # JRE bundle $(eval $(call SetupCopyFiles, CREATE_JRE_BUNDLE_DIR_SIGNED, \ SRC := $(JRE_IMAGE_DIR), \ diff --git a/make/CompileToolsJdk.gmk b/make/CompileToolsJdk.gmk index feba5d8a902d7..41a19f90ace77 100644 --- a/make/CompileToolsJdk.gmk +++ b/make/CompileToolsJdk.gmk @@ -52,8 +52,7 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_JDK, \ build/tools/deps \ build/tools/docs \ build/tools/jigsaw \ - build/tools/depend \ - , \ + build/tools/depend, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \ DISABLED_WARNINGS := dangling-doc-comments options, \ JAVAC_FLAGS := \ @@ -66,17 +65,19 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_JDK, \ TARGETS += $(BUILD_TOOLS_JDK) -$(eval $(call SetupCopyFiles,COPY_NIMBUS_TEMPLATES, \ +$(eval $(call SetupCopyFiles, COPY_NIMBUS_TEMPLATES, \ SRC := $(TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus, \ DEST := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources, \ - FILES := $(wildcard $(TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template))) + FILES := $(wildcard $(TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template), \ +)) TARGETS += $(COPY_NIMBUS_TEMPLATES) -$(eval $(call SetupCopyFiles,COPY_CLDRCONVERTER_PROPERTIES, \ +$(eval $(call SetupCopyFiles, COPY_CLDRCONVERTER_PROPERTIES, \ SRC := $(TOPDIR)/make/jdk/src/classes/build/tools/cldrconverter, \ DEST := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/cldrconverter, \ - FILES := $(wildcard $(TOPDIR)/make/jdk/src/classes/build/tools/cldrconverter/*.properties))) + FILES := $(wildcard $(TOPDIR)/make/jdk/src/classes/build/tools/cldrconverter/*.properties), \ +)) TARGETS += $(COPY_CLDRCONVERTER_PROPERTIES) diff --git a/make/CopyInterimTZDB.gmk b/make/CopyInterimTZDB.gmk index ac390580aa911..e2704b3297568 100644 --- a/make/CopyInterimTZDB.gmk +++ b/make/CopyInterimTZDB.gmk @@ -30,7 +30,7 @@ include MakeBase.gmk include CopyFiles.gmk -########################################################################################## +################################################################################ ### TZDB tool needs files from java.time.zone package @@ -41,12 +41,13 @@ define tzdb_copyfiles < $(<) > $@ endef -$(eval $(call SetupCopyFiles,COPY_INTERIM_TZDB, \ +$(eval $(call SetupCopyFiles, COPY_INTERIM_TZDB, \ SRC := $(TOPDIR)/src/java.base/share/classes/java/time/zone, \ DEST := $(BUILDTOOLS_OUTPUTDIR)/interim_tzdb_classes/build/tools/tzdb, \ FILES := ZoneRules.java ZoneOffsetTransition.java ZoneOffsetTransitionRule.java Ser.java, \ - MACRO := tzdb_copyfiles)) + MACRO := tzdb_copyfiles, \ +)) -########################################################################################## +################################################################################ all: $(COPY_INTERIM_TZDB) diff --git a/make/Docs.gmk b/make/Docs.gmk index 08a9ac662cd2a..e6a98c4fbd21d 100644 --- a/make/Docs.gmk +++ b/make/Docs.gmk @@ -247,7 +247,7 @@ define create_overview_file \ \ # - ifneq ($$($1_GROUPS),) + ifneq ($$($1_GROUPS), ) $1_OVERVIEW_TEXT += \

This document is divided into \ $$(subst 2,two,$$(subst 3,three,$$(words $$($1_GROUPS)))) sections:

\ diff --git a/make/Global.gmk b/make/Global.gmk index 998ba4d2bda82..6b97b7ad05940 100644 --- a/make/Global.gmk +++ b/make/Global.gmk @@ -28,7 +28,7 @@ ### # Helper macro to allow $(info) to properly print strings beginning with spaces. -_:= +_ := help: $(info ) @@ -108,7 +108,7 @@ help: $(info $(_) TEST_OPTS="OPT1=x;..." # Generic control of all test harnesses) $(info $(_) TEST_VM_OPTS="ARG ..." # Same as setting TEST_OPTS to VM_OPTIONS="ARG ...") $(info ) - $(if $(all_confs), $(info Available configurations in $(build_dir):) $(foreach var,$(all_confs),$(info * $(var))),\ + $(if $(all_confs), $(info Available configurations in $(build_dir):) $(foreach var,$(all_confs),$(info * $(var))), \ $(info No configurations were found in $(build_dir).) $(info Run 'bash configure' to create a configuration.)) # We need a dummy rule otherwise make will complain @true diff --git a/make/Images.gmk b/make/Images.gmk index bfad1ad563c9b..5703a74afa590 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -134,11 +134,11 @@ CDS_DUMP_FLAGS = -Xmx128M -Xms128M # Param1 - VM variant (e.g., server, client, zero, ...) # Param2 - _nocoops, or empty define CreateCDSArchive - $1_$2_DUMP_EXTRA_ARG := $(if $(filter _nocoops, $2),-XX:-UseCompressedOops,) - $1_$2_DUMP_TYPE := $(if $(filter _nocoops, $2),-NOCOOPS,) + $1_$2_DUMP_EXTRA_ARG := $(if $(filter _nocoops, $2), -XX:-UseCompressedOops, ) + $1_$2_DUMP_TYPE := $(if $(filter _nocoops, $2), -NOCOOPS, ) # Only G1 supports dumping the shared heap, so explicitly use G1 if the JVM supports it. - $1_$2_CDS_DUMP_FLAGS := $(CDS_DUMP_FLAGS) $(if $(filter g1gc, $(JVM_FEATURES_$1)),-XX:+UseG1GC) + $1_$2_CDS_DUMP_FLAGS := $(CDS_DUMP_FLAGS) $(if $(filter g1gc, $(JVM_FEATURES_$1)), -XX:+UseG1GC) ifeq ($(OPENJDK_TARGET_OS), windows) $1_$2_CDS_ARCHIVE := bin/$1/classes$2.jsa @@ -235,7 +235,7 @@ endif ifeq ($(GCOV_ENABLED), true) - $(eval $(call SetupCopyFiles,COPY_GCOV_GCNO, \ + $(eval $(call SetupCopyFiles, COPY_GCOV_GCNO, \ SRC := $(OUTPUTDIR), \ DEST := $(SYMBOLS_IMAGE_DIR)/gcov, \ FILES := $(call FindFiles, $(HOTSPOT_OUTPUTDIR) \ diff --git a/make/Init.gmk b/make/Init.gmk index 61846217ecc34..8918de7d16e4b 100644 --- a/make/Init.gmk +++ b/make/Init.gmk @@ -37,7 +37,7 @@ default: # serially, regardless of -j. .NOTPARALLEL: -ifeq ($(HAS_SPEC),) +ifeq ($(HAS_SPEC), ) ############################################################################## # This is the default mode. We have not been recursively called with a SPEC. ############################################################################## @@ -168,7 +168,7 @@ ifeq ($(HAS_SPEC),) endif make-info: - ifneq ($(findstring $(LOG_LEVEL),info debug trace),) + ifneq ($(findstring $(LOG_LEVEL), info debug trace), ) $(info Running make as '$(strip $(MAKE) $(MFLAGS) \ $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))') endif diff --git a/make/InitSupport.gmk b/make/InitSupport.gmk index 6dd29b1db1091..2471d82d6dbfb 100644 --- a/make/InitSupport.gmk +++ b/make/InitSupport.gmk @@ -32,7 +32,7 @@ ifndef _INITSUPPORT_GMK _INITSUPPORT_GMK := 1 -ifeq ($(HAS_SPEC),) +ifeq ($(HAS_SPEC), ) # COMMA is defined in spec.gmk, but that is not included yet COMMA := , @@ -74,13 +74,13 @@ ifeq ($(HAS_SPEC),) # Setup information about available configurations, if any. ifneq ($(CUSTOM_ROOT), ) - build_dir=$(CUSTOM_ROOT)/build + build_dir = $(CUSTOM_ROOT)/build else - build_dir=$(topdir)/build + build_dir = $(topdir)/build endif - all_spec_files=$(wildcard $(build_dir)/*/spec.gmk) + all_spec_files = $(wildcard $(build_dir)/*/spec.gmk) # Extract the configuration names from the path - all_confs=$(patsubst %/spec.gmk, %, $(patsubst $(build_dir)/%, %, $(all_spec_files))) + all_confs = $(patsubst %/spec.gmk, %, $(patsubst $(build_dir)/%, %, $(all_spec_files))) # Check for unknown command-line variables define CheckControlVariables @@ -128,7 +128,7 @@ ifeq ($(HAS_SPEC),) ifeq ($$(CONF_CHECK), ) # Default behavior is fail CONF_CHECK := fail - else ifneq ($$(filter-out auto fail ignore, $$(CONF_CHECK)),) + else ifneq ($$(filter-out auto fail ignore, $$(CONF_CHECK)), ) $$(info Error: CONF_CHECK must be one of: auto, fail or ignore.) $$(error Cannot continue) endif @@ -147,11 +147,11 @@ ifeq ($(HAS_SPEC),) $$(info Error: Cannot use CONF_NAME=$$(CONF_NAME) and SPEC=$$(SPEC) at the same time. Choose one.) $$(error Cannot continue) endif - ifeq ($$(wildcard $$(SPEC)),) + ifeq ($$(wildcard $$(SPEC)), ) $$(info Error: Cannot locate spec.gmk, given by SPEC=$$(SPEC).) $$(error Cannot continue) endif - ifeq ($$(filter /%, $$(SPEC)),) + ifeq ($$(filter /%, $$(SPEC)), ) # If given with relative path, make it absolute SPECS := $$(CURDIR)/$$(strip $$(SPEC)) else @@ -162,7 +162,7 @@ ifeq ($(HAS_SPEC),) override SPEC := else # Use spec.gmk files in the build output directory - ifeq ($$(all_spec_files),) + ifeq ($$(all_spec_files), ) ifneq ($(CUSTOM_ROOT), ) $$(info Error: No configurations found for $$(CUSTOM_ROOT).) else @@ -180,7 +180,7 @@ ifeq ($(HAS_SPEC),) $$(error Cannot continue) endif matching_conf := $$(strip $$(filter $$(CONF_NAME), $$(all_confs))) - ifeq ($$(matching_conf),) + ifeq ($$(matching_conf), ) $$(info Error: No configurations found matching CONF_NAME=$$(CONF_NAME).) $$(info Available configurations in $$(build_dir):) $$(foreach var, $$(all_confs), $$(info * $$(var))) @@ -197,12 +197,12 @@ ifeq ($(HAS_SPEC),) SPECS := $$(build_dir)/$$(matching_conf)/spec.gmk else ifneq ($$(origin CONF), undefined) # User have given a CONF= argument. - ifeq ($$(CONF),) + ifeq ($$(CONF), ) # If given CONF=, match all configurations matching_confs := $$(strip $$(all_confs)) else # Otherwise select those that contain the given CONF string - ifeq ($$(patsubst !%,,$$(CONF)),) + ifeq ($$(patsubst !%,,$$(CONF)), ) # A CONF starting with ! means we should negate the search term matching_confs := $$(strip $$(foreach var, $$(all_confs), \ $$(if $$(findstring $$(subst !,,$$(CONF)), $$(var)), ,$$(var)))) @@ -215,12 +215,12 @@ ifeq ($(HAS_SPEC),) matching_confs := $$(CONF) # Don't repeat this output on make restarts caused by including # generated files. - ifeq ($$(MAKE_RESTARTS),) + ifeq ($$(MAKE_RESTARTS), ) $$(info Using exact match for CONF=$$(CONF) (other matches are possible)) endif endif endif - ifeq ($$(matching_confs),) + ifeq ($$(matching_confs), ) $$(info Error: No configurations found matching CONF=$$(CONF).) $$(info Available configurations in $$(build_dir):) $$(foreach var, $$(all_confs), $$(info * $$(var))) @@ -228,9 +228,9 @@ ifeq ($(HAS_SPEC),) else # Don't repeat this output on make restarts caused by including # generated files. - ifeq ($$(MAKE_RESTARTS),) + ifeq ($$(MAKE_RESTARTS), ) ifeq ($$(words $$(matching_confs)), 1) - ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),) + ifneq ($$(findstring $$(LOG_LEVEL), info debug trace), ) $$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF))) endif else @@ -272,7 +272,7 @@ ifeq ($(HAS_SPEC),) # count. main_targets_file := $$(dir $(strip $2))make-support/main-targets.gmk - ifeq ($$(MAKE_RESTARTS),) + ifeq ($$(MAKE_RESTARTS), ) # Only do this if make has not been restarted, and if we do not force it. ifeq ($(strip $1), FORCE) $$(shell rm -f $$(main_targets_file)) @@ -316,9 +316,9 @@ else # $(HAS_SPEC)=true BUILD_LOG_PIPE_SIMPLE := | $(TEE) -a $(BUILD_LOG) ifneq ($(CUSTOM_ROOT), ) - topdir=$(CUSTOM_ROOT) + topdir = $(CUSTOM_ROOT) else - topdir=$(TOPDIR) + topdir = $(TOPDIR) endif # Setup the build environment to match the requested specification on @@ -349,39 +349,39 @@ else # $(HAS_SPEC)=true ifneq ($$(findstring :, $$(COMPARE_BUILD)), ) $$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \ $$(if $$(filter PATCH=%, $$(part)), \ - $$(eval COMPARE_BUILD_PATCH=$$(strip $$(patsubst PATCH=%, %, $$(part)))) \ + $$(eval COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(part)))) \ ) \ $$(if $$(filter CONF=%, $$(part)), \ - $$(eval COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \ + $$(eval COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \ ) \ $$(if $$(filter MAKE=%, $$(part)), \ - $$(eval COMPARE_BUILD_MAKE=$$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \ + $$(eval COMPARE_BUILD_MAKE = $$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \ ) \ $$(if $$(filter COMP_OPTS=%, $$(part)), \ - $$(eval COMPARE_BUILD_COMP_OPTS=$$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \ + $$(eval COMPARE_BUILD_COMP_OPTS = $$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \ ) \ $$(if $$(filter COMP_DIR=%, $$(part)), \ - $$(eval COMPARE_BUILD_COMP_DIR=$$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \ + $$(eval COMPARE_BUILD_COMP_DIR = $$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \ ) \ $$(if $$(filter FAIL=%, $$(part)), \ - $$(eval COMPARE_BUILD_FAIL=$$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \ + $$(eval COMPARE_BUILD_FAIL = $$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \ ) \ $$(if $$(filter NODRYRUN=%, $$(part)), \ - $$(eval COMPARE_BUILD_NODRYRUN=$$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \ + $$(eval COMPARE_BUILD_NODRYRUN = $$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \ ) \ ) else # Separate handling for single field case, to allow for spaces in values. ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), ) - COMPARE_BUILD_PATCH=$$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD))) + COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD))) else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), ) - COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD)))) + COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD)))) else ifneq ($$(filter --%, $$(COMPARE_BUILD)), ) # Assume CONF if value begins with -- - COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(COMPARE_BUILD))) + COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(COMPARE_BUILD))) else # Otherwise assume patch file - COMPARE_BUILD_PATCH=$$(strip $$(COMPARE_BUILD)) + COMPARE_BUILD_PATCH = $$(strip $$(COMPARE_BUILD)) endif endif ifneq ($$(COMPARE_BUILD_PATCH), ) @@ -531,7 +531,7 @@ else # $(HAS_SPEC)=true # used by build comparisons. define WaitForJavacServerFinish $(if $(JAVAC_SERVER_DIR), \ - sleep 5\ + sleep 5 \ ) endef else @@ -544,7 +544,7 @@ else # $(HAS_SPEC)=true ############################################################################## # Store the build times in this directory. - BUILDTIMESDIR=$(OUTPUTDIR)/make-support/build-times + BUILDTIMESDIR = $(OUTPUTDIR)/make-support/build-times # Record starting time for build of a sub repository. define RecordStartTime @@ -605,7 +605,7 @@ endif # HAS_SPEC # $1: The option to look for # $2: The variable to set to "true" if the option is found define ParseLogOption - ifneq ($$(findstring $1, $$(LOG)),) + ifneq ($$(findstring $1, $$(LOG)), ) override $2 := true # First try to remove ",