diff --git a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp index 89624aeffdd04..d0d11d437e83e 100644 --- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp @@ -75,8 +75,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(hdr, obj); - ldrw(hdr, Address(hdr, Klass::access_flags_offset())); - tstw(hdr, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(hdr, Address(hdr, Klass::misc_flags_offset())); + tst(hdr, KlassFlags::_misc_is_value_based_class); br(Assembler::NE, slow_case); } diff --git a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp index 780055a611f3b..cb9eb03c580d2 100644 --- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp @@ -783,8 +783,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { Label register_finalizer; Register t = r5; __ load_klass(t, r0); - __ ldrw(t, Address(t, Klass::access_flags_offset())); - __ tbnz(t, exact_log2(JVM_ACC_HAS_FINALIZER), register_finalizer); + __ ldrb(t, Address(t, Klass::misc_flags_offset())); + __ tbnz(t, exact_log2(KlassFlags::_misc_has_finalizer), register_finalizer); __ ret(lr); __ bind(register_finalizer); diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 19af03d348806..b4c12ecd4a849 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -64,8 +64,8 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, oop); - ldrw(tmp, Address(tmp, Klass::access_flags_offset())); - tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(tmp, Address(tmp, Klass::misc_flags_offset())); + tst(tmp, KlassFlags::_misc_is_value_based_class); br(Assembler::NE, cont); } @@ -243,8 +243,8 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(t1, obj); - ldrw(t1, Address(t1, Klass::access_flags_offset())); - tstw(t1, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(t1, Address(t1, Klass::misc_flags_offset())); + tst(t1, KlassFlags::_misc_is_value_based_class); br(Assembler::NE, slow_path); } diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 117168de0c5f0..c6af74c3dcdce 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -690,8 +690,8 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, obj_reg); - ldrw(tmp, Address(tmp, Klass::access_flags_offset())); - tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(tmp, Address(tmp, Klass::misc_flags_offset())); + tst(tmp, KlassFlags::_misc_is_value_based_class); br(Assembler::NE, slow_case); } diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index f7cf99381578b..25eb339bfce71 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -2191,9 +2191,9 @@ void TemplateTable::_return(TosState state) __ ldr(c_rarg1, aaddress(0)); __ load_klass(r3, c_rarg1); - __ ldrw(r3, Address(r3, Klass::access_flags_offset())); + __ ldrb(r3, Address(r3, Klass::misc_flags_offset())); Label skip_register_finalizer; - __ tbz(r3, exact_log2(JVM_ACC_HAS_FINALIZER), skip_register_finalizer); + __ tbz(r3, exact_log2(KlassFlags::_misc_has_finalizer), skip_register_finalizer); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), c_rarg1); diff --git a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp index f1267587ce4f1..70542d278acf7 100644 --- a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp @@ -195,8 +195,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp2, obj); - ldr_u32(tmp2, Address(tmp2, Klass::access_flags_offset())); - tst(tmp2, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(tmp2, Address(tmp2, Klass::misc_flags_offset())); + tst(tmp2, KlassFlags::_misc_is_value_based_class); b(slow_case, ne); } diff --git a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp index 9862a074a687f..335baf5f16638 100644 --- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp +++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.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 @@ -504,11 +504,11 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { __ set_info("register_finalizer", dont_gc_arguments); - // Do not call runtime if JVM_ACC_HAS_FINALIZER flag is not set + // Do not call runtime if has_finalizer flag is not set __ load_klass(Rtemp, R0); - __ ldr_u32(Rtemp, Address(Rtemp, Klass::access_flags_offset())); + __ ldrb(Rtemp, Address(Rtemp, Klass::misc_flags_offset())); - __ tst(Rtemp, JVM_ACC_HAS_FINALIZER); + __ tst(Rtemp, KlassFlags::_misc_has_finalizer); __ bx(LR, eq); // Call VM diff --git a/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp b/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp index 1db30ce5c685d..900bd33fd9d46 100644 --- a/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -86,8 +86,8 @@ void C2_MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratc if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(Rscratch, Roop); - ldr_u32(Rscratch, Address(Rscratch, Klass::access_flags_offset())); - tst(Rscratch, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(Rscratch, Address(Rscratch, Klass::misc_flags_offset())); + tst(Rscratch, KlassFlags::_misc_is_value_based_class); b(done, ne); } diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 2874abafc4f69..3a81fdddb3c32 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.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 @@ -909,8 +909,8 @@ void InterpreterMacroAssembler::lock_object(Register Rlock) { if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(R0, Robj); - ldr_u32(R0, Address(R0, Klass::access_flags_offset())); - tst(R0, JVM_ACC_IS_VALUE_BASED_CLASS); + ldrb(R0, Address(R0, Klass::misc_flags_offset())); + tst(R0, KlassFlags::_misc_is_value_based_class); b(slow_case, ne); } diff --git a/src/hotspot/cpu/arm/templateTable_arm.cpp b/src/hotspot/cpu/arm/templateTable_arm.cpp index e657c65958834..80519fd89f426 100644 --- a/src/hotspot/cpu/arm/templateTable_arm.cpp +++ b/src/hotspot/cpu/arm/templateTable_arm.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 @@ -2494,8 +2494,8 @@ void TemplateTable::_return(TosState state) { assert(state == vtos, "only valid state"); __ ldr(R1, aaddress(0)); __ load_klass(Rtemp, R1); - __ ldr_u32(Rtemp, Address(Rtemp, Klass::access_flags_offset())); - __ tbz(Rtemp, exact_log2(JVM_ACC_HAS_FINALIZER), skip_register_finalizer); + __ ldrb(Rtemp, Address(Rtemp, Klass::misc_flags_offset())); + __ tbz(Rtemp, exact_log2(KlassFlags::_misc_has_finalizer), skip_register_finalizer); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), R1); diff --git a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp index abc439df82793..081d10f065ffa 100644 --- a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp @@ -86,8 +86,8 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(Rscratch, Roop); - lwz(Rscratch, in_bytes(Klass::access_flags_offset()), Rscratch); - testbitdi(CCR0, R0, Rscratch, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbz(Rscratch, in_bytes(Klass::misc_flags_offset()), Rscratch); + testbitdi(CCR0, R0, Rscratch, exact_log2(KlassFlags::_misc_is_value_based_class)); bne(CCR0, slow_int); } diff --git a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp index 63914c5d1cb93..d212d25b3ad12 100644 --- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -479,8 +479,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // Load the klass and check the has finalizer flag. __ load_klass(t, R3_ARG1); - __ lwz(t, in_bytes(Klass::access_flags_offset()), t); - __ testbitdi(CCR0, R0, t, exact_log2(JVM_ACC_HAS_FINALIZER)); + __ lbz(t, in_bytes(Klass::misc_flags_offset()), t); + __ testbitdi(CCR0, R0, t, exact_log2(KlassFlags::_misc_has_finalizer)); // Return if has_finalizer bit == 0 (CR0.eq). __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CCR0, Assembler::equal), Assembler::bhintbhBCLRisReturn); diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index 3acee737a3add..c24089ccdd583 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -970,8 +970,8 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, object); - lwz(tmp, in_bytes(Klass::access_flags_offset()), tmp); - testbitdi(CCR0, R0, tmp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbz(tmp, in_bytes(Klass::misc_flags_offset()), tmp); + testbitdi(CCR0, R0, tmp, exact_log2(KlassFlags::_misc_is_value_based_class)); bne(CCR0, slow_case); } diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index faca90990c893..e596f91704cb5 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -2561,8 +2561,8 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(temp, oop); - lwz(temp, in_bytes(Klass::access_flags_offset()), temp); - testbitdi(flag, R0, temp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbz(temp, in_bytes(Klass::misc_flags_offset()), temp); + testbitdi(flag, R0, temp, exact_log2(KlassFlags::_misc_is_value_based_class)); bne(flag, failure); } @@ -2752,8 +2752,8 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp1, obj); - lwz(tmp1, in_bytes(Klass::access_flags_offset()), tmp1); - testbitdi(flag, R0, tmp1, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbz(tmp1, in_bytes(Klass::misc_flags_offset()), tmp1); + testbitdi(flag, R0, tmp1, exact_log2(KlassFlags::_misc_is_value_based_class)); bne(flag, slow_path); } diff --git a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp index 0ee9348dde810..a55f30eb67dc4 100644 --- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp @@ -2130,8 +2130,8 @@ void TemplateTable::_return(TosState state) { // Load klass of this obj. __ load_klass(Rklass, R17_tos); - __ lwz(Rklass_flags, in_bytes(Klass::access_flags_offset()), Rklass); - __ testbitdi(CCR0, R0, Rklass_flags, exact_log2(JVM_ACC_HAS_FINALIZER)); + __ lbz(Rklass_flags, in_bytes(Klass::misc_flags_offset()), Rklass); + __ testbitdi(CCR0, R0, Rklass_flags, exact_log2(KlassFlags::_misc_has_finalizer)); __ bfalse(CCR0, Lskip_register_finalizer); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), R17_tos /* obj */); diff --git a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp index dc1a3d443ac67..1ae64b4f283ba 100644 --- a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp @@ -64,8 +64,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(hdr, obj); - lwu(hdr, Address(hdr, Klass::access_flags_offset())); - test_bit(temp, hdr, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbu(hdr, Address(hdr, Klass::misc_flags_offset())); + test_bit(temp, hdr, exact_log2(KlassFlags::_misc_is_value_based_class)); bnez(temp, slow_case, true /* is_far */); } diff --git a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp index 74f303ffb02ad..824d03640517e 100644 --- a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -797,8 +797,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { Label register_finalizer; Register t = x15; __ load_klass(t, x10); - __ lwu(t, Address(t, Klass::access_flags_offset())); - __ test_bit(t0, t, exact_log2(JVM_ACC_HAS_FINALIZER)); + __ lbu(t, Address(t, Klass::misc_flags_offset())); + __ test_bit(t0, t, exact_log2(KlassFlags::_misc_has_finalizer)); __ bnez(t0, register_finalizer); __ ret(); diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index a75bfdfc9dcf7..1e3a8bde064b3 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -68,8 +68,8 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, oop); - lwu(tmp, Address(tmp, Klass::access_flags_offset())); - test_bit(tmp, tmp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbu(tmp, Address(tmp, Klass::misc_flags_offset())); + test_bit(tmp, tmp, exact_log2(KlassFlags::_misc_is_value_based_class)); bnez(tmp, slow_path); } @@ -277,8 +277,8 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp1, obj); - lwu(tmp1, Address(tmp1, Klass::access_flags_offset())); - test_bit(tmp1, tmp1, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbu(tmp1, Address(tmp1, Klass::misc_flags_offset())); + test_bit(tmp1, tmp1, exact_log2(KlassFlags::_misc_is_value_based_class)); bnez(tmp1, slow_path); } diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index 06b7b780d139c..3eb7abb5ee3b9 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -750,8 +750,8 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, obj_reg); - lwu(tmp, Address(tmp, Klass::access_flags_offset())); - test_bit(tmp, tmp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + lbu(tmp, Address(tmp, Klass::misc_flags_offset())); + test_bit(tmp, tmp, exact_log2(KlassFlags::_misc_is_value_based_class)); bnez(tmp, slow_case); } diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index fa542343949ac..078f54adc3682 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -2098,9 +2098,9 @@ void TemplateTable::_return(TosState state) { __ ld(c_rarg1, aaddress(0)); __ load_klass(x13, c_rarg1); - __ lwu(x13, Address(x13, Klass::access_flags_offset())); + __ lbu(x13, Address(x13, Klass::misc_flags_offset())); Label skip_register_finalizer; - __ test_bit(t0, x13, exact_log2(JVM_ACC_HAS_FINALIZER)); + __ test_bit(t0, x13, exact_log2(KlassFlags::_misc_has_finalizer)); __ beqz(t0, skip_register_finalizer); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), c_rarg1); diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp index 13b080678217f..a9140a7925ebd 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp @@ -72,7 +72,7 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, Roop); - testbit(Address(tmp, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + z_tm(Address(tmp, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); branch_optimized(Assembler::bcondAllOne, slow_case); } diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp index decb3a1cafc31..41c57043d8234 100644 --- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp +++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.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. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -443,7 +443,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // Load the klass and check the has finalizer flag. Register klass = Z_ARG2; __ load_klass(klass, Z_ARG1); - __ testbit(Address(klass, Klass::access_flags_offset()), exact_log2(JVM_ACC_HAS_FINALIZER)); + __ z_tm(Address(klass, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer); __ z_bcr(Assembler::bcondAllZero, Z_R14); // Return if bit is not set. OopMap* oop_map = save_live_registers(sasm); diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 0b29c31ec96ef..e56beaa9f569c 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1007,7 +1007,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, object); - testbit(Address(tmp, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS)); + z_tm(Address(tmp, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); z_btrue(slow_case); } diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index d527b4d2aea11..50de705cd9f0c 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -3507,9 +3507,7 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(temp, oop); - z_l(temp, Address(temp, Klass::access_flags_offset())); - assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction"); - z_nilh(temp, JVM_ACC_IS_VALUE_BASED_CLASS >> 16); + z_tm(Address(temp, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); z_brne(done); } @@ -6154,9 +6152,7 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(Register obj, Registe if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp1, obj); - z_l(tmp1, Address(tmp1, Klass::access_flags_offset())); - assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction"); - z_nilh(tmp1, JVM_ACC_IS_VALUE_BASED_CLASS >> 16); + z_tm(Address(tmp1, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); z_brne(slow_path); } diff --git a/src/hotspot/cpu/s390/templateTable_s390.cpp b/src/hotspot/cpu/s390/templateTable_s390.cpp index ef68a5ac83ac7..0c9f9e031b06a 100644 --- a/src/hotspot/cpu/s390/templateTable_s390.cpp +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp @@ -2321,7 +2321,7 @@ void TemplateTable::_return(TosState state) { assert(state == vtos, "only valid state"); __ z_lg(Rthis, aaddress(0)); __ load_klass(Rklass, Rthis); - __ testbit(Address(Rklass, Klass::access_flags_offset()), exact_log2(JVM_ACC_HAS_FINALIZER)); + __ z_tm(Address(Rklass, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer); __ z_bfalse(skip_register_finalizer); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), Rthis); __ bind(skip_register_finalizer); diff --git a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp index 576592d05aa77..4dcacd00a6339 100644 --- a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp @@ -58,8 +58,7 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(hdr, obj, rscratch1); - movl(hdr, Address(hdr, Klass::access_flags_offset())); - testl(hdr, JVM_ACC_IS_VALUE_BASED_CLASS); + testb(Address(hdr, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); jcc(Assembler::notZero, slow_case); } diff --git a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp index dc051127feaec..11b39ce15eb1a 100644 --- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp +++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1166,8 +1166,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { Label register_finalizer; Register t = rsi; __ load_klass(t, rax, rscratch1); - __ movl(t, Address(t, Klass::access_flags_offset())); - __ testl(t, JVM_ACC_HAS_FINALIZER); + __ testb(Address(t, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer); __ jcc(Assembler::notZero, register_finalizer); __ ret(0); diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 5dbfdbc225d75..c2801a791cb5a 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -277,8 +277,7 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmpReg, objReg, scrReg); - movl(tmpReg, Address(tmpReg, Klass::access_flags_offset())); - testl(tmpReg, JVM_ACC_IS_VALUE_BASED_CLASS); + testb(Address(tmpReg, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); jcc(Assembler::notZero, DONE_LABEL); } @@ -597,8 +596,7 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(rax_reg, obj, t); - movl(rax_reg, Address(rax_reg, Klass::access_flags_offset())); - testl(rax_reg, JVM_ACC_IS_VALUE_BASED_CLASS); + testb(Address(rax_reg, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); jcc(Assembler::notZero, slow_path); } diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index 249506c13ffdf..f4b95d846c61e 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1175,8 +1175,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) { if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp_reg, obj_reg, rklass_decode_tmp); - movl(tmp_reg, Address(tmp_reg, Klass::access_flags_offset())); - testl(tmp_reg, JVM_ACC_IS_VALUE_BASED_CLASS); + testb(Address(tmp_reg, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class); jcc(Assembler::notZero, slow_case); } diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp index fc6844aedd6b2..5e783225fcbfc 100644 --- a/src/hotspot/cpu/x86/templateTable_x86.cpp +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp @@ -2579,8 +2579,7 @@ void TemplateTable::_return(TosState state) { Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax); __ movptr(robj, aaddress(0)); __ load_klass(rdi, robj, rscratch1); - __ movl(rdi, Address(rdi, Klass::access_flags_offset())); - __ testl(rdi, JVM_ACC_HAS_FINALIZER); + __ testb(Address(rdi, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer); Label skip_register_finalizer; __ jcc(Assembler::zero, skip_register_finalizer); diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 6b902e8280244..1d4aecda93642 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -30,9 +30,7 @@ // os::Linux defines the interface to Linux operating systems class os::Linux { - friend class CgroupSubsystem; friend class os; - friend class OSContainer; static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *); static int (*_pthread_setname_np)(pthread_t, const char*); @@ -58,7 +56,6 @@ class os::Linux { static julong available_memory(); static julong free_memory(); - static int active_processor_count(); static void initialize_system_info(); @@ -93,6 +90,7 @@ class os::Linux { bool has_steal_ticks; }; + static int active_processor_count(); static void kernel_version(long* major, long* minor); // which_logical_cpu=-1 returns accumulated ticks for all cpus. diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 1d1d9d3e1a4ed..a1e0a78837f74 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -5741,11 +5741,23 @@ void Parker::unpark() { SetEvent(_ParkHandle); } +// Platform Mutex/Monitor implementation + +PlatformMutex::PlatformMutex() { + InitializeCriticalSection(&_mutex); +} + PlatformMutex::~PlatformMutex() { DeleteCriticalSection(&_mutex); } -// Platform Monitor implementation +PlatformMonitor::PlatformMonitor() { + InitializeConditionVariable(&_cond); +} + +PlatformMonitor::~PlatformMonitor() { + // There is no DeleteConditionVariable API +} // Must already be locked int PlatformMonitor::wait(uint64_t millis) { diff --git a/src/hotspot/os/windows/os_windows.inline.hpp b/src/hotspot/os/windows/os_windows.inline.hpp index bb2da39d42283..3aa88c36958a7 100644 --- a/src/hotspot/os/windows/os_windows.inline.hpp +++ b/src/hotspot/os/windows/os_windows.inline.hpp @@ -61,18 +61,6 @@ inline bool os::numa_has_group_homing() { return false; } // Platform Mutex/Monitor implementation -inline PlatformMutex::PlatformMutex() { - InitializeCriticalSection(&_mutex); -} - -inline PlatformMonitor::PlatformMonitor() { - InitializeConditionVariable(&_cond); -} - -inline PlatformMonitor::~PlatformMonitor() { - // There is no DeleteConditionVariable API -} - inline void PlatformMutex::lock() { EnterCriticalSection(&_mutex); } diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index dc4475a4b8101..a2e903edc342f 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -1389,6 +1389,11 @@ void GraphBuilder::jsr(int dest) { // If the bytecodes are strange (jumping out of a jsr block) then we // might end up trying to re-parse a block containing a jsr which // has already been activated. Watch for this case and bail out. + if (next_bci() >= method()->code_size()) { + // This can happen if the subroutine does not terminate with a ret, + // effectively turning the jsr into a goto. + BAILOUT("too-complicated jsr/ret structure"); + } for (ScopeData* cur_scope_data = scope_data(); cur_scope_data != nullptr && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope(); cur_scope_data = cur_scope_data->parent()) { @@ -3736,6 +3741,9 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee, bool ignore_return) { bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) { // Introduce a new callee continuation point - all Ret instructions // will be replaced with Gotos to this point. + if (next_bci() >= method()->code_size()) { + return false; + } BlockBegin* cont = block_at(next_bci()); assert(cont != nullptr, "continuation must exist (BlockListBuilder starts a new block after a jsr"); diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index b2695ac2e7873..f8d24295a12e5 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -463,7 +463,7 @@ void ClassListParser::check_class_name(const char* class_name) { err = "class name too long"; } else { assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be"); - if (!UTF8::is_legal_utf8((const unsigned char*)class_name, (int)len, /*version_leq_47*/false)) { + if (!UTF8::is_legal_utf8((const unsigned char*)class_name, len, /*version_leq_47*/false)) { err = "class name is not valid UTF8"; } } @@ -849,4 +849,3 @@ void ClassListParser::parse_constant_pool_tag() { ClassPrelinker::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list); } } - diff --git a/src/hotspot/share/ci/ciInstanceKlass.cpp b/src/hotspot/share/ci/ciInstanceKlass.cpp index 240bb25ae3aa8..a9342eeada48b 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.cpp +++ b/src/hotspot/share/ci/ciInstanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) : AccessFlags access_flags = ik->access_flags(); _flags = ciFlags(access_flags); - _has_finalizer = access_flags.has_finalizer(); + _has_finalizer = ik->has_finalizer(); _has_subklass = flags().is_final() ? subklass_false : subklass_unknown; _init_state = ik->init_state(); _has_nonstatic_fields = ik->has_nonstatic_fields(); diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp index 6e70d69f05d8f..efdd2512f9024 100644 --- a/src/hotspot/share/ci/ciKlass.cpp +++ b/src/hotspot/share/ci/ciKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -226,6 +226,15 @@ jint ciKlass::access_flags() { ) } +// ------------------------------------------------------------------ +// ciKlass::misc_flags +klass_flags_t ciKlass::misc_flags() { + assert(is_loaded(), "not loaded"); + GUARDED_VM_ENTRY( + return get_Klass()->misc_flags(); + ) +} + // ------------------------------------------------------------------ // ciKlass::print_impl // diff --git a/src/hotspot/share/ci/ciKlass.hpp b/src/hotspot/share/ci/ciKlass.hpp index 2dd5a5e2c0b7b..58a62b248a4e8 100644 --- a/src/hotspot/share/ci/ciKlass.hpp +++ b/src/hotspot/share/ci/ciKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,6 +121,9 @@ class ciKlass : public ciType { // Fetch Klass::access_flags. jint access_flags(); + // Fetch Klass::misc_flags. + klass_flags_t misc_flags(); + // What kind of ciObject is this? bool is_klass() const { return true; } diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 407078d64fc57..46421ccc90c18 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -4559,7 +4559,8 @@ void ClassFileParser::verify_legal_utf8(const unsigned char* buffer, int length, TRAPS) const { assert(_need_verify, "only called when _need_verify is true"); - if (!UTF8::is_legal_utf8(buffer, length, _major_version <= 47)) { + // Note: 0 <= length < 64K, as it comes from a u2 entry in the CP. + if (!UTF8::is_legal_utf8(buffer, static_cast(length), _major_version <= 47)) { classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", THREAD); } } @@ -5173,9 +5174,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, ik->set_has_nonstatic_concrete_methods(_has_nonstatic_concrete_methods); ik->set_declares_nonstatic_concrete_methods(_declares_nonstatic_concrete_methods); - if (_is_hidden) { - ik->set_is_hidden(); - } + assert(!_is_hidden || ik->is_hidden(), "must be set already"); // Set PackageEntry for this_klass oop cl = ik->class_loader(); diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index e32d124013d8b..b9a559cf9779f 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -285,8 +285,7 @@ Symbol* SystemDictionary::class_name_symbol(const char* name, Symbol* exception, return nullptr; } // Callers should ensure that the name is never an illegal UTF8 string. - assert(UTF8::is_legal_utf8((const unsigned char*)name, - static_cast(name_len), false), + assert(UTF8::is_legal_utf8((const unsigned char*)name, name_len, false), "Class name is not a valid utf8 string."); // Make a new symbol for the class name. diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 8bb06e6dca4dd..ce7f862a7b6c2 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -274,9 +274,16 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { return warn_excluded(k, "Has been redefined"); } if (!k->is_hidden() && k->shared_classpath_index() < 0 && is_builtin(k)) { - // These are classes loaded from unsupported locations (such as those loaded by JVMTI native - // agent during dump time). - return warn_excluded(k, "Unsupported location"); + if (k->name()->starts_with("java/lang/invoke/BoundMethodHandle$Species_")) { + // This class is dynamically generated by the JDK + ResourceMark rm; + log_info(cds)("Skipping %s because it is dynamically generated", k->name()->as_C_string()); + return true; // exclude without warning + } else { + // These are classes loaded from unsupported locations (such as those loaded by JVMTI native + // agent during dump time). + return warn_excluded(k, "Unsupported location"); + } } if (k->signers() != nullptr) { // We cannot include signed classes in the archive because the certificates diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index 074846e2e7919..260da40b87a42 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp @@ -893,7 +893,7 @@ void Dependencies::DepStream::print_dependency(outputStream* st, Klass* witness, void Dependencies::DepStream::initial_asserts(size_t byte_limit) { assert(must_be_in_vm(), "raw oops here"); _byte_limit = byte_limit; - _type = (DepType)(end_marker-1); // defeat "already at end" assert + _type = undefined_dependency; // defeat "already at end" assert assert((_code!=nullptr) + (_deps!=nullptr) == 1, "one or t'other"); } #endif //ASSERT diff --git a/src/hotspot/share/code/dependencies.hpp b/src/hotspot/share/code/dependencies.hpp index 124db0b136933..d11c51a66dc66 100644 --- a/src/hotspot/share/code/dependencies.hpp +++ b/src/hotspot/share/code/dependencies.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,6 +103,9 @@ class Dependencies: public ResourceObj { // type now includes N, that is, all super types of N. // enum DepType { + // _type is initially set to -1, to prevent "already at end" assert + undefined_dependency = -1, + end_marker = 0, // An 'evol' dependency simply notes that the contents of the diff --git a/src/hotspot/share/compiler/methodLiveness.cpp b/src/hotspot/share/compiler/methodLiveness.cpp index 1b764882d1099..7d65b20a1595e 100644 --- a/src/hotspot/share/compiler/methodLiveness.cpp +++ b/src/hotspot/share/compiler/methodLiveness.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -222,6 +222,9 @@ void MethodLiveness::init_basic_blocks() { dest = _block_map->at(bytes.get_dest()); assert(dest != nullptr, "branch destination must start a block."); dest->add_normal_predecessor(current_block); + if (bci + Bytecodes::length_for(code) >= method_len) { + break; + } BasicBlock *jsrExit = _block_map->at(current_block->limit_bci()); assert(jsrExit != nullptr, "jsr return bci must start a block."); jsr_exit_list->append(jsrExit); @@ -232,6 +235,9 @@ void MethodLiveness::init_basic_blocks() { dest = _block_map->at(bytes.get_far_dest()); assert(dest != nullptr, "branch destination must start a block."); dest->add_normal_predecessor(current_block); + if (bci + Bytecodes::length_for(code) >= method_len) { + break; + } BasicBlock *jsrExit = _block_map->at(current_block->limit_bci()); assert(jsrExit != nullptr, "jsr return bci must start a block."); jsr_exit_list->append(jsrExit); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 4c66c526151b9..5789b44e6189e 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -172,7 +172,6 @@ class PrepareRegionsClosure : public G1HeapRegionClosure { bool do_heap_region(G1HeapRegion* hr) { hr->prepare_for_full_gc(); - hr->uninstall_group_cardset(); G1CollectedHeap::heap()->prepare_region_for_full_compaction(hr); _collector->before_marking_update_attribute_table(hr); return false; diff --git a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp index 4c93aca84928f..910f878ef7fbf 100644 --- a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp @@ -37,6 +37,8 @@ void G1FullGCResetMetadataTask::G1ResetMetadataClosure::reset_region_metadata(G1 } bool G1FullGCResetMetadataTask::G1ResetMetadataClosure::do_heap_region(G1HeapRegion* hr) { + hr->uninstall_group_cardset(); + uint const region_idx = hr->hrm_index(); if (!_collector->is_compaction_target(region_idx)) { assert(!hr->is_free(), "all free regions should be compaction targets"); diff --git a/src/hotspot/share/gc/z/zRememberedSet.cpp b/src/hotspot/share/gc/z/zRememberedSet.cpp index cb92e38db2e77..ed1dcfaf14d55 100644 --- a/src/hotspot/share/gc/z/zRememberedSet.cpp +++ b/src/hotspot/share/gc/z/zRememberedSet.cpp @@ -78,8 +78,8 @@ bool ZRememberedSet::is_cleared_previous() const { } void ZRememberedSet::clear_all() { - clear_current(); - clear_previous(); + _bitmap[0].clear_large(); + _bitmap[1].clear_large(); } void ZRememberedSet::clear_current() { diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 1526f81295b2a..df77e8a2882ee 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -274,6 +274,7 @@ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ nonstatic_field(Klass, _bitmap, uintx) \ nonstatic_field(Klass, _hash_slot, uint8_t) \ + nonstatic_field(Klass, _misc_flags._flags, u1) \ \ nonstatic_field(LocalVariableTableElement, start_bci, u2) \ nonstatic_field(LocalVariableTableElement, length, u2) \ @@ -482,10 +483,6 @@ declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \ \ declare_constant(JVM_ACC_WRITTEN_FLAGS) \ - declare_constant(JVM_ACC_HAS_FINALIZER) \ - declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ - declare_constant(JVM_ACC_IS_HIDDEN_CLASS) \ - declare_constant(JVM_ACC_IS_VALUE_BASED_CLASS) \ declare_constant(FieldInfo::FieldFlags::_ff_injected) \ declare_constant(FieldInfo::FieldFlags::_ff_stable) \ declare_preprocessor_constant("JVM_ACC_VARARGS", JVM_ACC_VARARGS) \ @@ -733,6 +730,10 @@ \ declare_constant(InstanceKlassFlags::_misc_has_nonstatic_concrete_methods) \ declare_constant(InstanceKlassFlags::_misc_declares_nonstatic_concrete_methods) \ + declare_constant(KlassFlags::_misc_is_hidden_class) \ + declare_constant(KlassFlags::_misc_is_value_based_class) \ + declare_constant(KlassFlags::_misc_has_finalizer) \ + declare_constant(KlassFlags::_misc_is_cloneable_fast) \ \ declare_constant(JumpData::taken_off_set) \ declare_constant(JumpData::displacement_off_set) \ diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 650279db1bee3..431c7a0e60387 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -2659,8 +2659,8 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl array_klasses()->restore_unshareable_info(class_loader_data(), Handle(), CHECK); } - // Initialize @ValueBased class annotation - if (DiagnoseSyncOnValueBasedClasses && has_value_based_class_annotation()) { + // Initialize @ValueBased class annotation if not already set in the archived klass. + if (DiagnoseSyncOnValueBasedClasses && has_value_based_class_annotation() && !is_value_based()) { set_is_value_based(); } } diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 964bb030b960e..f3b625064fbc7 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -65,7 +65,7 @@ void Klass::set_java_mirror(Handle m) { } bool Klass::is_cloneable() const { - return _access_flags.is_cloneable_fast() || + return _misc_flags.is_cloneable_fast() || is_subtype_of(vmClasses::Cloneable_klass()); } @@ -76,7 +76,7 @@ void Klass::set_is_cloneable() { } else if (is_instance_klass() && InstanceKlass::cast(this)->reference_type() != REF_NONE) { // Reference cloning should not be intrinsified and always happen in JVM_Clone. } else { - _access_flags.set_is_cloneable_fast(); + _misc_flags.set_is_cloneable_fast(true); } } @@ -975,6 +975,7 @@ void Klass::oop_print_on(oop obj, outputStream* st) { // print class st->print(BULLET"klass: "); obj->klass()->print_value_on(st); + st->print(BULLET"flags: "); _misc_flags.print_on(st); st->cr(); st->cr(); } diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 6ec6ac889be71..ce74830a3112a 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -27,6 +27,7 @@ #include "memory/iterator.hpp" #include "memory/memRegion.hpp" +#include "oops/klassFlags.hpp" #include "oops/markWord.hpp" #include "oops/metadata.hpp" #include "oops/oop.hpp" @@ -165,6 +166,8 @@ class Klass : public Metadata { // Keep it away from the beginning of a Klass to avoid cacheline // contention that may happen when a nearby object is modified. AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. + // Some flags created by the JVM, not in the class file itself, + // are in _misc_flags below. JFR_ONLY(DEFINE_TRACE_ID_FIELD;) @@ -194,6 +197,8 @@ class Klass : public Metadata { }; #endif + KlassFlags _misc_flags; + CDS_JAVA_HEAP_ONLY(int _archived_mirror_index;) protected: @@ -428,6 +433,7 @@ class Klass : public Metadata { static ByteSize next_sibling_offset() { return byte_offset_of(Klass, _next_sibling); } #endif static ByteSize bitmap_offset() { return byte_offset_of(Klass, _bitmap); } + static ByteSize misc_flags_offset() { return byte_offset_of(Klass, _misc_flags._flags); } // Unpacking layout_helper: static const int _lh_neutral_value = 0; // neutral non-array non-instance value @@ -692,12 +698,14 @@ class Klass : public Metadata { bool is_super() const { return _access_flags.is_super(); } bool is_synthetic() const { return _access_flags.is_synthetic(); } void set_is_synthetic() { _access_flags.set_is_synthetic(); } - bool has_finalizer() const { return _access_flags.has_finalizer(); } - void set_has_finalizer() { _access_flags.set_has_finalizer(); } - bool is_hidden() const { return access_flags().is_hidden_class(); } - void set_is_hidden() { _access_flags.set_is_hidden_class(); } - bool is_value_based() { return _access_flags.is_value_based_class(); } - void set_is_value_based() { _access_flags.set_is_value_based_class(); } + bool has_finalizer() const { return _misc_flags.has_finalizer(); } + void set_has_finalizer() { _misc_flags.set_has_finalizer(true); } + bool is_hidden() const { return _misc_flags.is_hidden_class(); } + void set_is_hidden() { _misc_flags.set_is_hidden_class(true); } + bool is_value_based() const { return _misc_flags.is_value_based_class(); } + void set_is_value_based() { _misc_flags.set_is_value_based_class(true); } + + klass_flags_t misc_flags() const { return _misc_flags.value(); } inline bool is_non_strong_hidden() const; diff --git a/src/hotspot/share/oops/klass.inline.hpp b/src/hotspot/share/oops/klass.inline.hpp index a72868a08d890..f549940ef9595 100644 --- a/src/hotspot/share/oops/klass.inline.hpp +++ b/src/hotspot/share/oops/klass.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,8 +37,7 @@ inline oop Klass::klass_holder() const { } inline bool Klass::is_non_strong_hidden() const { - return access_flags().is_hidden_class() && - class_loader_data()->has_class_mirror_holder(); + return is_hidden() && class_loader_data()->has_class_mirror_holder(); } // Iff the class loader (or mirror for non-strong hidden classes) is alive the diff --git a/src/hotspot/share/oops/klassFlags.cpp b/src/hotspot/share/oops/klassFlags.cpp new file mode 100644 index 0000000000000..6399762e8df56 --- /dev/null +++ b/src/hotspot/share/oops/klassFlags.cpp @@ -0,0 +1,34 @@ +/* + * 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 "oops/klassFlags.hpp" +#include "utilities/ostream.hpp" + +void KlassFlags::print_on(outputStream* st) const { +#define KLASS_FLAGS_PRINT(name, ignore) \ + if (name()) st->print(#name " "); + KLASS_FLAGS_DO(KLASS_FLAGS_PRINT) +#undef KLASS_FLAGS_PRINT +} diff --git a/src/hotspot/share/oops/klassFlags.hpp b/src/hotspot/share/oops/klassFlags.hpp new file mode 100644 index 0000000000000..3e71bb3c1b3cc --- /dev/null +++ b/src/hotspot/share/oops/klassFlags.hpp @@ -0,0 +1,78 @@ +/* + * 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. + * + */ + +#ifndef SHARE_OOPS_KLASSFLAGS_HPP +#define SHARE_OOPS_KLASSFLAGS_HPP + +#include "utilities/globalDefinitions.hpp" + +class outputStream; + +// The Klass class contains only parse-time flags and are used by generated code, even though +// most apply to InstanceKlass, access is more straightforward through Klass pointers. +// These flags are JVM internal and not part of the AccessFlags classfile specification. + +using klass_flags_t = u1; + +class KlassFlags { + friend class VMStructs; + friend class JVMCIVMStructs; + + public: +#define KLASS_FLAGS_DO(flag) \ + flag(is_hidden_class , 1 << 0) \ + flag(is_value_based_class , 1 << 1) \ + flag(has_finalizer , 1 << 2) \ + flag(is_cloneable_fast , 1 << 3) \ + /* end of list */ + +#define KLASS_FLAGS_ENUM_NAME(name, value) _misc_##name = value, + enum { + KLASS_FLAGS_DO(KLASS_FLAGS_ENUM_NAME) + }; +#undef KLASS_FLAGS_ENUM_NAME + + // These flags are write-once before the class is published and then read-only + // so don't require atomic updates. + klass_flags_t _flags; + + public: + KlassFlags() : _flags(0) {} + + klass_flags_t value() const { return _flags; } + + // Create getters and setters for the flag values. +#define KLASS_FLAGS_GET_SET(name, ignore) \ + bool name() const { return (_flags & _misc_##name) != 0; } \ + void set_##name(bool b) { \ + assert(!name(), "set once"); \ + if (b) _flags |= _misc_##name; \ + } + KLASS_FLAGS_DO(KLASS_FLAGS_GET_SET) +#undef KLASS_FLAGS_GET_SET + + void print_on(outputStream* st) const; +}; + +#endif // SHARE_OOPS_KLASSFLAGS_HPP diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index a9d73364e2d00..0ea3bfd122af0 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1701,6 +1701,8 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::access_flags_offset())) alias_type(idx)->set_rewritable(false); + if (flat->offset() == in_bytes(Klass::misc_flags_offset())) + alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::java_mirror_offset())) alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::secondary_super_cache_offset())) @@ -5196,7 +5198,20 @@ void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) { ss.print(" %d", iter); } if (n != nullptr) { - ss.print(": %d %s ", n->_idx, NodeClassNames[n->Opcode()]); + ss.print(": %d %s", n->_idx, NodeClassNames[n->Opcode()]); + if (n->is_Call()) { + CallNode* call = n->as_Call(); + if (call->_name != nullptr) { + // E.g. uncommon traps etc. + ss.print(" - %s", call->_name); + } else if (call->is_CallJava()) { + CallJavaNode* call_java = call->as_CallJava(); + if (call_java->method() != nullptr) { + ss.print(" -"); + call_java->method()->print_short_name(&ss); + } + } + } } const char* name = ss.as_string(); diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 24901855b91a1..c95a450272989 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -3860,13 +3860,14 @@ Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror, } //--------------------(inline_native_Class_query helpers)--------------------- -// Use this for JVM_ACC_INTERFACE, JVM_ACC_IS_CLONEABLE_FAST, JVM_ACC_HAS_FINALIZER. +// Use this for JVM_ACC_INTERFACE. // Fall through if (mods & mask) == bits, take the guard otherwise. -Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region) { +Node* LibraryCallKit::generate_klass_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region, + ByteSize offset, const Type* type, BasicType bt) { // Branch around if the given klass has the given modifier bit set. // Like generate_guard, adds a new path onto the region. - Node* modp = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); - Node* mods = make_load(nullptr, modp, TypeInt::INT, T_INT, MemNode::unordered); + Node* modp = basic_plus_adr(kls, in_bytes(offset)); + Node* mods = make_load(nullptr, modp, type, bt, MemNode::unordered); Node* mask = intcon(modifier_mask); Node* bits = intcon(modifier_bits); Node* mbit = _gvn.transform(new AndINode(mods, mask)); @@ -3875,10 +3876,18 @@ Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, return generate_fair_guard(bol, region); } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { - return generate_access_flags_guard(kls, JVM_ACC_INTERFACE, 0, region); + return generate_klass_flags_guard(kls, JVM_ACC_INTERFACE, 0, region, + Klass::access_flags_offset(), TypeInt::INT, T_INT); } + +// Use this for testing if Klass is_hidden, has_finalizer, and is_cloneable_fast. +Node* LibraryCallKit::generate_misc_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region) { + return generate_klass_flags_guard(kls, modifier_mask, modifier_bits, region, + Klass::misc_flags_offset(), TypeInt::UBYTE, T_BOOLEAN); +} + Node* LibraryCallKit::generate_hidden_class_guard(Node* kls, RegionNode* region) { - return generate_access_flags_guard(kls, JVM_ACC_IS_HIDDEN_CLASS, 0, region); + return generate_misc_flags_guard(kls, KlassFlags::_misc_is_hidden_class, 0, region); } //-------------------------inline_native_Class_query------------------- @@ -5320,12 +5329,12 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { // The object must be easily cloneable and must not have a finalizer. // Both of these conditions may be checked in a single test. // We could optimize the test further, but we don't care. - generate_access_flags_guard(obj_klass, - // Test both conditions: - JVM_ACC_IS_CLONEABLE_FAST | JVM_ACC_HAS_FINALIZER, - // Must be cloneable but not finalizer: - JVM_ACC_IS_CLONEABLE_FAST, - slow_region); + generate_misc_flags_guard(obj_klass, + // Test both conditions: + KlassFlags::_misc_is_cloneable_fast | KlassFlags::_misc_has_finalizer, + // Must be cloneable but not finalizer: + KlassFlags::_misc_is_cloneable_fast, + slow_region); } if (!stopped()) { diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp index 4ae9d0216e9fd..dd74734802f65 100644 --- a/src/hotspot/share/opto/library_call.hpp +++ b/src/hotspot/share/opto/library_call.hpp @@ -156,9 +156,11 @@ class LibraryCallKit : public GraphKit { region, null_path, offset); } - Node* generate_access_flags_guard(Node* kls, - int modifier_mask, int modifier_bits, - RegionNode* region); + Node* generate_klass_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region, + ByteSize offset, const Type* type, BasicType bt); + Node* generate_misc_flags_guard(Node* kls, + int modifier_mask, int modifier_bits, + RegionNode* region); Node* generate_interface_guard(Node* kls, RegionNode* region); Node* generate_hidden_class_guard(Node* kls, RegionNode* region); Node* generate_array_guard(Node* kls, RegionNode* region) { diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 2d79857b62a78..eee14e5ba03f1 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1981,6 +1981,12 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); return TypeInt::make(klass->access_flags()); } + if (tkls->offset() == in_bytes(Klass::misc_flags_offset())) { + // The field is Klass::_misc_flags. Return its (constant) value. + // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) + assert(this->Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); + return TypeInt::make(klass->misc_flags()); + } if (tkls->offset() == in_bytes(Klass::layout_helper_offset())) { // The field is Klass::_layout_helper. Return its constant value if known. assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp index 05627450585ff..50ccc1473229d 100644 --- a/src/hotspot/share/opto/parse1.cpp +++ b/src/hotspot/share/opto/parse1.cpp @@ -2123,10 +2123,10 @@ void Parse::call_register_finalizer() { Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() ); Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), klass_addr, TypeInstPtr::KLASS)); - Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset())); - Node* access_flags = make_load(nullptr, access_flags_addr, TypeInt::INT, T_INT, MemNode::unordered); + Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::misc_flags_offset())); + Node* access_flags = make_load(nullptr, access_flags_addr, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered); - Node* mask = _gvn.transform(new AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER))); + Node* mask = _gvn.transform(new AndINode(access_flags, intcon(KlassFlags::_misc_has_finalizer))); Node* check = _gvn.transform(new CmpINode(mask, intcon(0))); Node* test = _gvn.transform(new BoolNode(check, BoolTest::ne)); diff --git a/src/hotspot/share/prims/jniCheck.cpp b/src/hotspot/share/prims/jniCheck.cpp index 87543686c3ccb..8c1f9f53b343d 100644 --- a/src/hotspot/share/prims/jniCheck.cpp +++ b/src/hotspot/share/prims/jniCheck.cpp @@ -475,7 +475,7 @@ void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) { } // Verify that the class name given is a valid utf8 string - if (!UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false)) { + if (!UTF8::is_legal_utf8((const unsigned char*)name, strlen(name), false)) { char msg[JVM_MAXPATHLEN]; jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", fatal_non_utf8_class_name1, name, fatal_non_utf8_class_name2); ReportJNIFatalError(thr, msg); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 6425f5f583f36..bf9874956bae2 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -809,7 +809,7 @@ JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env, // into the constant pool. return nullptr; } - assert(UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false), "illegal UTF name"); + assert(UTF8::is_legal_utf8((const unsigned char*)name, strlen(name), false), "illegal UTF name"); TempNewSymbol h_name = SymbolTable::new_symbol(name); Klass* k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL); diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index fe9620586be3b..40c15e10c5a91 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -2015,8 +2015,6 @@ /************************************************************/ \ \ declare_constant(JVM_ACC_WRITTEN_FLAGS) \ - declare_constant(JVM_ACC_HAS_FINALIZER) \ - declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ \ declare_constant(JVM_CONSTANT_Utf8) \ declare_constant(JVM_CONSTANT_Unicode) \ diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 78bf179e03afd..74ccbd20ac142 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.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 @@ -40,14 +40,7 @@ enum { // flags actually put in .class file JVM_ACC_WRITTEN_FLAGS = 0x00007FFF, - // HotSpot-specific access flags - // These Klass flags should be migrated, to a field such as InstanceKlass::_misc_flags, - // or to a similar flags field in Klass itself. // Do not add new ACC flags here. - JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method - JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code - JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden - JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class }; @@ -77,12 +70,6 @@ class AccessFlags { // Attribute flags bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; } - // Klass* flags - bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; } - bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; } - bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; } - bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; } - // get .class file flags jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); } @@ -102,13 +89,6 @@ class AccessFlags { // attribute flags void set_is_synthetic() { _flags |= JVM_ACC_SYNTHETIC; } - // Klass* flags - // These are set at classfile parsing time so do not require atomic access. - void set_has_finalizer() { _flags |= JVM_ACC_HAS_FINALIZER; } - void set_is_cloneable_fast() { _flags |= JVM_ACC_IS_CLONEABLE_FAST; } - void set_is_hidden_class() { _flags |= JVM_ACC_IS_HIDDEN_CLASS; } - void set_is_value_based_class() { _flags |= JVM_ACC_IS_VALUE_BASED_CLASS; } - public: // Conversion jshort as_short() const { return (jshort)_flags; } diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index f730b37b8fffa..10405a0604887 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -288,7 +288,7 @@ void Exceptions::fthrow(JavaThread* thread, const char* file, int line, Symbol* // parameter controls a check for a specific character appearing in the "name", which is only // allowed for classfile versions <= 47. We pass `true` so that we allow such strings as this code // know nothing about the actual string content. - assert(UTF8::is_legal_utf8((const unsigned char*)msg, (int)strlen(msg), true), "must be"); + assert(UTF8::is_legal_utf8((const unsigned char*)msg, strlen(msg), true), "must be"); _throw_msg(thread, file, line, h_name, msg); } diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index e2ec0909f4500..f7fa0dbe96b5f 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -4647,7 +4647,7 @@ public String descriptorString() { return Wrapper.forPrimitiveType(this).basicTypeString(); if (isArray()) { - return "[" + componentType.descriptorString(); + return "[".concat(componentType.descriptorString()); } else if (isHidden()) { String name = getName(); int index = name.indexOf('/'); @@ -4660,11 +4660,7 @@ public String descriptorString() { .toString(); } else { String name = getName().replace('.', '/'); - return new StringBuilder(name.length() + 2) - .append('L') - .append(name) - .append(';') - .toString(); + return StringConcatHelper.concat("L", name, ";"); } } diff --git a/src/java.base/share/classes/java/lang/StringCoding.java b/src/java.base/share/classes/java/lang/StringCoding.java index 293fbdb78dc85..c02af28c37d8b 100644 --- a/src/java.base/share/classes/java/lang/StringCoding.java +++ b/src/java.base/share/classes/java/lang/StringCoding.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -34,6 +35,45 @@ class StringCoding { private StringCoding() { } + /** + * Count the number of leading non-zero ascii chars in the range. + */ + public static int countNonZeroAscii(String s) { + byte[] value = s.value(); + if (s.isLatin1()) { + return countNonZeroAsciiLatin1(value, 0, value.length); + } else { + return countNonZeroAsciiUTF16(value, 0, s.length()); + } + } + + /** + * Count the number of non-zero ascii chars in the range. + */ + public static int countNonZeroAsciiLatin1(byte[] ba, int off, int len) { + int limit = off + len; + for (int i = off; i < limit; i++) { + if (ba[i] <= 0) { + return i - off; + } + } + return len; + } + + /** + * Count the number of leading non-zero ascii chars in the range. + */ + public static int countNonZeroAsciiUTF16(byte[] ba, int off, int strlen) { + int limit = off + strlen; + for (int i = off; i < limit; i++) { + char c = StringUTF16.charAt(ba, i); + if (c == 0 || c > 0x7F) { + return i - off; + } + } + return strlen; + } + public static boolean hasNegatives(byte[] ba, int off, int len) { return countPositives(ba, off, len) != len; } diff --git a/src/java.base/share/classes/java/lang/StringConcatHelper.java b/src/java.base/share/classes/java/lang/StringConcatHelper.java index ae2b969340905..d0c558ed93a1a 100644 --- a/src/java.base/share/classes/java/lang/StringConcatHelper.java +++ b/src/java.base/share/classes/java/lang/StringConcatHelper.java @@ -783,4 +783,20 @@ static int checkOverflow(int value) { } throw new OutOfMemoryError("Overflow: String length out of range"); } + + @ForceInline + private static String concat0(String prefix, String str, String suffix) { + byte coder = (byte) (prefix.coder() | str.coder() | suffix.coder()); + int len = prefix.length() + str.length(); + byte[] buf = newArrayWithSuffix(suffix, len, coder); + prepend(len, coder, buf, str, prefix); + return new String(buf, coder); + } + + @ForceInline + static String concat(String prefix, Object value, String suffix) { + if (prefix == null) prefix = "null"; + if (suffix == null) suffix = "null"; + return concat0(prefix, stringOf(value), suffix); + } } diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 503167bc2dd0d..682b6ca2c2a2c 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2569,6 +2569,9 @@ public Stream layers(ClassLoader loader) { public int countPositives(byte[] bytes, int offset, int length) { return StringCoding.countPositives(bytes, offset, length); } + public int countNonZeroAscii(String s) { + return StringCoding.countNonZeroAscii(s); + } public String newStringNoRepl(byte[] bytes, Charset cs) throws CharacterCodingException { return String.newStringNoRepl(bytes, cs); } @@ -2650,6 +2653,10 @@ public String join(String prefix, String suffix, String delimiter, String[] elem return String.join(prefix, suffix, delimiter, elements, size); } + public String concat(String prefix, Object value, String suffix) { + return StringConcatHelper.concat(prefix, value, suffix); + } + public Object classData(Class c) { return c.getClassData(); } diff --git a/src/java.base/share/classes/java/lang/constant/ClassDesc.java b/src/java.base/share/classes/java/lang/constant/ClassDesc.java index 0c714850a8fa3..b93d95223529e 100644 --- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java +++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java @@ -36,6 +36,7 @@ import static jdk.internal.constant.ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS; import static jdk.internal.constant.ConstantUtils.arrayDepth; import static jdk.internal.constant.ConstantUtils.binaryToInternal; +import static jdk.internal.constant.ConstantUtils.concat; import static jdk.internal.constant.ConstantUtils.forPrimitiveType; import static jdk.internal.constant.ConstantUtils.internalToBinary; import static jdk.internal.constant.ConstantUtils.validateBinaryClassName; @@ -83,7 +84,7 @@ public sealed interface ClassDesc */ static ClassDesc of(String name) { validateBinaryClassName(name); - return ClassDesc.ofDescriptor("L" + binaryToInternal(name) + ";"); + return ClassDesc.ofDescriptor(concat("L", binaryToInternal(name), ";")); } /** @@ -109,7 +110,7 @@ static ClassDesc of(String name) { */ static ClassDesc ofInternalName(String name) { validateInternalClassName(name); - return ClassDesc.ofDescriptor("L" + name + ";"); + return ClassDesc.ofDescriptor(concat("L", name, ";")); } /** @@ -132,8 +133,8 @@ static ClassDesc of(String packageName, String className) { return of(className); } validateMemberName(className, false); - return ofDescriptor("L" + binaryToInternal(packageName) + - "/" + className + ";"); + return ofDescriptor('L' + binaryToInternal(packageName) + + '/' + className + ';'); } /** @@ -361,7 +362,7 @@ else if (isArray()) { ClassDesc c = this; for (int i=0; i 65535) { - throw new IllegalArgumentException("string too long"); - } - pool.writeU1(tag); - pool.writeU2(charLen); - for (int i = 0; i < charLen; ++i) { - char c = stringValue.charAt(i); - if (c >= '\001' && c <= '\177') { - // Optimistic writing -- hope everything is bytes - // If not, we bail out, and alternate path patches the length - pool.writeU1((byte) c); - } - else { - int charLength = stringValue.length(); - int byteLength = i; - char c1; - for (int j = i; j < charLength; ++j) { - c1 = (stringValue).charAt(j); - if (c1 >= '\001' && c1 <= '\177') { - byteLength++; - } else if (c1 > '\u07FF') { - byteLength += 3; - } else { - byteLength += 2; - } - } - if (byteLength > 65535) { - throw new IllegalArgumentException(); - } - int byteLengthFinal = byteLength; - pool.patchInt(pool.size() - i - 2, 2, byteLengthFinal); - for (int j = i; j < charLength; ++j) { - c1 = (stringValue).charAt(j); - if (c1 >= '\001' && c1 <= '\177') { - pool.writeU1((byte) c1); - } else if (c1 > '\u07FF') { - pool.writeU1((byte) (0xE0 | c1 >> 12 & 0xF)); - pool.writeU1((byte) (0x80 | c1 >> 6 & 0x3F)); - pool.writeU1((byte) (0x80 | c1 & 0x3F)); - } else { - pool.writeU1((byte) (0xC0 | c1 >> 6 & 0x1F)); - pool.writeU1((byte) (0x80 | c1 & 0x3F)); - } - } - break; - } - } + pool.writeUTF(stringValue); } } } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.java index 255e5e21cf0da..0c317065162bd 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.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 @@ -34,7 +35,11 @@ import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.PoolEntry; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; + public final class BufWriterImpl implements BufWriter { + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); private final ConstantPoolBuilder constantPool; private final ClassFileImpl context; @@ -152,6 +157,52 @@ public void writeBytes(BufWriterImpl other) { writeBytes(other.elems, 0, other.offset); } + @SuppressWarnings("deprecation") + void writeUTF(String str) { + int strlen = str.length(); + int countNonZeroAscii = JLA.countNonZeroAscii(str); + int utflen = strlen; + if (countNonZeroAscii != strlen) { + for (int i = countNonZeroAscii; i < strlen; i++) { + int c = str.charAt(i); + if (c >= 0x80 || c == 0) + utflen += (c >= 0x800) ? 2 : 1; + } + } + if (utflen > 65535) { + throw new IllegalArgumentException("string too long"); + } + reserveSpace(utflen + 2); + + int offset = this.offset; + byte[] elems = this.elems; + + elems[offset ] = (byte) (utflen >> 8); + elems[offset + 1] = (byte) utflen; + offset += 2; + + str.getBytes(0, countNonZeroAscii, elems, offset); + offset += countNonZeroAscii; + + for (int i = countNonZeroAscii; i < strlen; ++i) { + char c = str.charAt(i); + if (c >= '\001' && c <= '\177') { + elems[offset++] = (byte) c; + } else if (c > '\u07FF') { + elems[offset ] = (byte) (0xE0 | c >> 12 & 0xF); + elems[offset + 1] = (byte) (0x80 | c >> 6 & 0x3F); + elems[offset + 2] = (byte) (0x80 | c & 0x3F); + offset += 3; + } else { + elems[offset ] = (byte) (0xC0 | c >> 6 & 0x1F); + elems[offset + 1] = (byte) (0x80 | c & 0x3F); + offset += 2; + } + } + + this.offset = offset; + } + @Override public void writeBytes(byte[] arr, int start, int length) { reserveSpace(length); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java index 609333048d0d3..bdee788c9da77 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java @@ -35,9 +35,10 @@ import java.lang.constant.ConstantDescs; import java.lang.constant.MethodTypeDesc; import java.lang.reflect.AccessFlag; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.Objects; -import java.util.TreeMap; import static java.lang.classfile.ClassFile.*; @@ -46,6 +47,7 @@ public class StackMapDecoder { private static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247, SAME_EXTENDED = 251; + private static final StackMapFrameInfo[] NO_STACK_FRAME_INFOS = new StackMapFrameInfo[0]; private final ClassReader classReader; private final int pos; @@ -103,15 +105,20 @@ public static void writeFrames(BufWriter b, List entries) { mi.methodTypeSymbol(), (mi.methodFlags() & ACC_STATIC) != 0); int prevOffset = -1; - var map = new TreeMap(); + // avoid using method handles due to early bootstrap + StackMapFrameInfo[] infos = entries.toArray(NO_STACK_FRAME_INFOS); //sort by resolved label offsets first to allow unordered entries - for (var fr : entries) { - map.put(dcb.labelToBci(fr.target()), fr); - } - b.writeU2(map.size()); - for (var me : map.entrySet()) { - int offset = me.getKey(); - var fr = me.getValue(); + Arrays.sort(infos, new Comparator() { + public int compare(final StackMapFrameInfo o1, final StackMapFrameInfo o2) { + return Integer.compare(dcb.labelToBci(o1.target()), dcb.labelToBci(o2.target())); + } + }); + b.writeU2(infos.length); + for (var fr : infos) { + int offset = dcb.labelToBci(fr.target()); + if (offset == prevOffset) { + throw new IllegalArgumentException("Duplicated stack frame bytecode index: " + offset); + } writeFrame(buf, offset - prevOffset - 1, prevLocals, fr); prevOffset = offset; prevLocals = fr.locals(); diff --git a/src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java b/src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java index f58bead542f83..5640f849ab6b1 100644 --- a/src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java +++ b/src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java @@ -35,12 +35,16 @@ import java.util.List; import java.util.Set; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; import static jdk.internal.constant.PrimitiveClassDescImpl.*; /** * Helper methods for the implementation of {@code java.lang.constant}. */ public final class ConstantUtils { + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + /** an empty constant descriptor */ public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0]; public static final ClassDesc[] EMPTY_CLASSDESC = new ClassDesc[0]; @@ -66,7 +70,7 @@ private ConstantUtils() {} * @param binaryName a binary name */ public static ClassDesc binaryNameToDesc(String binaryName) { - return ReferenceClassDescImpl.ofValidated("L" + binaryToInternal(binaryName) + ";"); + return ReferenceClassDescImpl.ofValidated(concat("L", binaryToInternal(binaryName), ";")); } /** @@ -378,4 +382,8 @@ private static IllegalArgumentException maxArrayTypeDescDimensions() { "Cannot create an array type descriptor with more than %d dimensions", ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS)); } + + public static String concat(String prefix, Object value, String suffix) { + return JLA.concat(prefix, value, suffix); + } } 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 5d43c28a66711..83b11b7ce686b 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -304,20 +304,25 @@ public boolean isNative() { @Override public final Optional asOverlappingSlice(MemorySegment other) { - AbstractMemorySegmentImpl that = (AbstractMemorySegmentImpl)Objects.requireNonNull(other); - if (unsafeGetBase() == that.unsafeGetBase()) { // both either native or heap + final AbstractMemorySegmentImpl that = (AbstractMemorySegmentImpl)Objects.requireNonNull(other); + if (overlaps(that)) { + final long offsetToThat = that.address() - this.address(); + final long newOffset = offsetToThat >= 0 ? offsetToThat : 0; + return Optional.of(asSlice(newOffset, Math.min(this.byteSize() - newOffset, that.byteSize() + offsetToThat))); + } + return Optional.empty(); + } + + @ForceInline + private boolean overlaps(AbstractMemorySegmentImpl that) { + if (unsafeGetBase() == that.unsafeGetBase()) { // both either native or the same heap segment final long thisStart = this.unsafeGetOffset(); final long thatStart = that.unsafeGetOffset(); final long thisEnd = thisStart + this.byteSize(); final long thatEnd = thatStart + that.byteSize(); - - if (thisStart < thatEnd && thisEnd > thatStart) { //overlap occurs - long offsetToThat = that.address() - this.address(); - long newOffset = offsetToThat >= 0 ? offsetToThat : 0; - return Optional.of(asSlice(newOffset, Math.min(this.byteSize() - newOffset, that.byteSize() + offsetToThat))); - } + return (thisStart < thatEnd && thisEnd > thatStart); //overlap occurs? } - return Optional.empty(); + return false; } @Override @@ -645,6 +650,64 @@ private static Object bufferRef(Buffer buffer) { } } + // COPY_NATIVE_THRESHOLD must be a power of two and should be greater than 2^3 + private static final long COPY_NATIVE_THRESHOLD = 1 << 6; + + @ForceInline + public static void copy(AbstractMemorySegmentImpl src, long srcOffset, + AbstractMemorySegmentImpl dst, long dstOffset, + long size) { + + Utils.checkNonNegativeIndex(size, "size"); + // Implicit null check for src and dst + src.checkAccess(srcOffset, size, true); + dst.checkAccess(dstOffset, size, false); + + if (size <= 0) { + // Do nothing + } else if (size < COPY_NATIVE_THRESHOLD && !src.overlaps(dst)) { + // 0 < size < FILL_NATIVE_LIMIT : 0...0X...XXXX + // + // Strictly, we could check for !src.asSlice(srcOffset, size).overlaps(dst.asSlice(dstOffset, size) but + // this is a bit slower and it likely very unusual there is any difference in the outcome. Also, if there + // is an overlap, we could tolerate one particular direction of overlap (but not the other). + + // 0...0X...X000 + final int limit = (int) (size & (COPY_NATIVE_THRESHOLD - 8)); + int offset = 0; + for (; offset < limit; offset += 8) { + final long v = SCOPED_MEMORY_ACCESS.getLong(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset); + SCOPED_MEMORY_ACCESS.putLong(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v); + } + int remaining = (int) size - offset; + // 0...0X00 + if (remaining >= 4) { + final int v = SCOPED_MEMORY_ACCESS.getInt(src.sessionImpl(), src.unsafeGetBase(),src.unsafeGetOffset() + srcOffset + offset); + SCOPED_MEMORY_ACCESS.putInt(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v); + offset += 4; + remaining -= 4; + } + // 0...00X0 + if (remaining >= 2) { + final short v = SCOPED_MEMORY_ACCESS.getShort(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset); + SCOPED_MEMORY_ACCESS.putShort(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v); + offset += 2; + remaining -=2; + } + // 0...000X + if (remaining == 1) { + final byte v = SCOPED_MEMORY_ACCESS.getByte(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset); + SCOPED_MEMORY_ACCESS.putByte(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v); + } + // We have now fully handled 0...0X...XXXX + } else { + // For larger sizes, the transition to native code pays off + SCOPED_MEMORY_ACCESS.copyMemory(src.sessionImpl(), dst.sessionImpl(), + src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset, + dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset, size); + } + } + @ForceInline public static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset, diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java index e3335dfb3c65c..2f310effc87f4 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java @@ -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. * 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,10 +56,6 @@ public AccessFlags(long flags) { public long getValue () { return flags; } - // Klass* flags - public boolean hasFinalizer () { return (flags & JVM_ACC_HAS_FINALIZER ) != 0; } - public boolean isCloneable () { return (flags & JVM_ACC_IS_CLONEABLE ) != 0; } - public void printOn(PrintStream tty) { // prints only .class flags and not the hotspot internal flags if (isPublic ()) tty.print("public " ); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java index ce869afad8aca..5947e32861e0a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java @@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -230,6 +230,4 @@ public Klass arrayKlassImpl(boolean orNull) { public boolean isAbstract() { return getAccessFlagsObj().isAbstract(); } public boolean isSuper() { return getAccessFlagsObj().isSuper(); } public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); } - public boolean hasFinalizer() { return getAccessFlagsObj().hasFinalizer(); } - public boolean isCloneable() { return getAccessFlagsObj().isCloneable(); } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java index 21fca913a3e00..25f40ec443f50 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java @@ -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 @@ -103,12 +103,6 @@ public interface ClassConstants // flags actually put in .class file public static final long JVM_ACC_WRITTEN_FLAGS = 0x00007FFF; - // Klass* flags - // True if klass has a non-empty finalize() method - public static final long JVM_ACC_HAS_FINALIZER = 0x40000000; - // True if klass supports the Clonable interface - public static final long JVM_ACC_IS_CLONEABLE = 0x80000000; - // flags accepted by set_field_flags public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java index 46e7280bbb7ca..91c9e73b532b9 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,6 +170,11 @@ public int getAccessFlags() { return UNSAFE.getInt(getKlassPointer() + config.klassAccessFlagsOffset); } + public int getMiscFlags() { + HotSpotVMConfig config = config(); + return UNSAFE.getInt(getKlassPointer() + config.klassMiscFlagsOffset); + } + @Override public ResolvedJavaType getComponentType() { if (componentType == null) { @@ -373,7 +378,7 @@ public AssumptionResult hasFinalizableSubclass() { @Override public boolean hasFinalizer() { - return (getAccessFlags() & config().jvmAccHasFinalizer) != 0; + return (getMiscFlags() & config().jvmAccHasFinalizer) != 0; } @Override @@ -1110,7 +1115,7 @@ public ResolvedJavaField resolveField(UnresolvedJavaField unresolvedJavaField, R @Override public boolean isCloneableWithAllocation() { - return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0; + return (getMiscFlags() & config().jvmAccIsCloneableFast) != 0; } @Override diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 954e1f6b20173..16d9cf3625ef6 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -98,6 +98,7 @@ String getHostArchitectureName() { final int instanceKlassFieldInfoStreamOffset = getFieldOffset("InstanceKlass::_fieldinfo_stream", Integer.class, "Array*"); final int instanceKlassAnnotationsOffset = getFieldOffset("InstanceKlass::_annotations", Integer.class, "Annotations*"); final int instanceKlassMiscFlagsOffset = getFieldOffset("InstanceKlass::_misc_flags._flags", Integer.class, "u2"); + final int klassMiscFlagsOffset = getFieldOffset("Klass::_misc_flags._flags", Integer.class, "u1"); final int klassVtableStartOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_start_offset", Integer.class, "int"); final int klassVtableLengthOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_length_offset", Integer.class, "int"); @@ -113,10 +114,10 @@ String getHostArchitectureName() { final int arrayU1DataOffset = getFieldOffset("Array::_data", Integer.class); final int arrayU2DataOffset = getFieldOffset("Array::_data", Integer.class); - final int jvmAccHasFinalizer = getConstant("JVM_ACC_HAS_FINALIZER", Integer.class); + final int jvmAccHasFinalizer = getConstant("KlassFlags::_misc_has_finalizer", Integer.class); final int jvmFieldFlagInternalShift = getConstant("FieldInfo::FieldFlags::_ff_injected", Integer.class); final int jvmFieldFlagStableShift = getConstant("FieldInfo::FieldFlags::_ff_stable", Integer.class); - final int jvmAccIsCloneableFast = getConstant("JVM_ACC_IS_CLONEABLE_FAST", Integer.class); + final int jvmAccIsCloneableFast = getConstant("KlassFlags::_misc_is_cloneable_fast", Integer.class); // These modifiers are not public in Modifier so we get them via vmStructs. final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class); diff --git a/src/jdk.jdi/share/classes/com/sun/tools/jdi/TargetVM.java b/src/jdk.jdi/share/classes/com/sun/tools/jdi/TargetVM.java index 2a9e4555099ce..5023a03d514b7 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/TargetVM.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/TargetVM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,8 +123,9 @@ public void run() { byte b[] = connection.readPacket(); if (b.length == 0) { done = true; + } else { + p = Packet.fromByteArray(b); } - p = Packet.fromByteArray(b); } catch (IOException e) { done = true; } diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index 8d6b74c8132b6..9d91cad1ddeae 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -51,5 +51,3 @@ vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 829 vmTestbase/nsk/stress/thread/thread006.java 8321476 linux-all gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64 - -runtime/interpreter/LastJsrTest.java 8338924 generic-all diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 1b139063b5d66..6ff3dec89a1c1 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -118,8 +118,6 @@ runtime/ErrorHandling/TestDwarf.java#checkDecoder 8305489 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le runtime/Thread/TestAlwaysPreTouchStacks.java 8335167 macosx-aarch64 runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x64 -runtime/exceptionMsgs/NoClassDefFoundError/NoClassDefFoundErrorTest.java 8339316 generic-all - applications/jcstress/copy.java 8229852 linux-all diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/dumpingWithAgent/DumpingWithJavaAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/dumpingWithAgent/DumpingWithJavaAgent.java index c814a9a406585..74ddfcebe1b24 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/dumpingWithAgent/DumpingWithJavaAgent.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/dumpingWithAgent/DumpingWithJavaAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,6 +76,7 @@ public static void main(String[] args) throws Throwable { output.shouldContain(warningMessages[0]); output.shouldContain(warningMessages[1]); output.shouldContain("inside SimpleAgent"); + output.shouldContain("Skipping java/lang/invoke/BoundMethodHandle$Species_LLLL because it is dynamically generated"); // CDS dumping with a java agent with the AllowArchvingWithJavaAgent diagnostic option. output = TestCommon.testDump(appJar, TestCommon.list("Hello"), diff --git a/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java b/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java index 913a304ae38a3..fd9cffe002dab 100644 --- a/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java +++ b/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java @@ -23,18 +23,20 @@ /* * @test - * @bug 8335664 + * @bug 8335664 8338924 * @summary Ensure a program that ends with a JSR does not crash * @library /test/lib * @compile LastJsr.jasm * @compile LastJsrReachable.jasm - * @run main/othervm LastJsrTest + * @run main/othervm -Xbatch LastJsrTest */ public class LastJsrTest { public static void main(String[] args) { - LastJsr.test(); - LastJsrReachable.test(); + for (int i = 0; i < 1000; ++i) { + LastJsr.test(); + LastJsrReachable.test(); + } System.out.println("PASSED"); } } diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 697fe82187ca3..47a2e13b460cf 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -470,9 +470,6 @@ sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java java/awt/Window/8159168/SetShapeTest.java 8274106 macosx-aarch64 java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8274106 macosx-aarch64 -# This test fails on macOS 14 -java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java 8324782 macosx-all - # Wayland related java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java 8280991 linux-x64 diff --git a/test/jdk/java/awt/Choice/SelectCurrentItemTest/SelectCurrentItemTest.java b/test/jdk/java/awt/Choice/SelectCurrentItemTest/SelectCurrentItemTest.java deleted file mode 100644 index 3d3f8c807938a..0000000000000 --- a/test/jdk/java/awt/Choice/SelectCurrentItemTest/SelectCurrentItemTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2002, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/* - @test - @bug 4902933 8197810 - @summary Test that selecting the current item doesnot send an ItemEvent - @key headful - @run main SelectCurrentItemTest -*/ - -import java.awt.Choice; -import java.awt.Robot; -import java.awt.Frame; -import java.awt.BorderLayout; -import java.awt.AWTException; -import java.awt.Point; -import java.awt.Dimension; -import java.awt.event.InputEvent; -import java.awt.event.ItemListener; -import java.awt.event.WindowListener; -import java.awt.event.ItemEvent; -import java.awt.event.WindowEvent; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class SelectCurrentItemTest implements ItemListener, WindowListener { - //Declare things used in the test, like buttons and labels here - private Frame frame; - private Choice theChoice; - private Robot robot; - - private CountDownLatch latch = new CountDownLatch(1); - private volatile boolean passed = true; - - private void init() - { - try { - robot = new Robot(); - robot.setAutoDelay(500); - } catch (AWTException e) { - throw new RuntimeException("Unable to create Robot. Test fails."); - } - - frame = new Frame("SelectCurrentItemTest"); - frame.setLayout(new BorderLayout()); - theChoice = new Choice(); - for (int i = 0; i < 10; i++) { - theChoice.add(new String("Choice Item " + i)); - } - theChoice.addItemListener(this); - frame.add(theChoice); - frame.addWindowListener(this); - - frame.setLocation(1,20); - robot.mouseMove(10, 30); - frame.pack(); - frame.setVisible(true); - } - - public static void main(String... args) { - SelectCurrentItemTest test = new SelectCurrentItemTest(); - test.init(); - try { - test.latch.await(12000, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) {} - test.robot.waitForIdle(); - - try { - if (!test.passed) { - throw new RuntimeException("TEST FAILED."); - } - } finally { - test.frame.dispose(); - } - } - - private void run() { - try {Thread.sleep(1000);} catch (InterruptedException e){} - // get loc of Choice on screen - Point loc = theChoice.getLocationOnScreen(); - // get bounds of Choice - Dimension size = theChoice.getSize(); - robot.mouseMove(loc.x + size.width - 10, loc.y + size.height / 2); - - robot.setAutoDelay(250); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - - robot.delay(1000); - - robot.mouseMove(loc.x + size.width / 2, loc.y + size.height); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - robot.waitForIdle(); - latch.countDown(); - } - - @Override public void itemStateChanged(ItemEvent e) { - System.out.println("ItemEvent received. Test fails"); - passed = false; - } - - @Override public void windowOpened(WindowEvent e) { - System.out.println("windowActivated()"); - (new Thread(this::run)).start(); - } - - @Override public void windowActivated(WindowEvent e) {} - @Override public void windowDeactivated(WindowEvent e) {} - @Override public void windowClosed(WindowEvent e) {} - @Override public void windowClosing(WindowEvent e) {} - @Override public void windowIconified(WindowEvent e) {} - @Override public void windowDeiconified(WindowEvent e) {} -} diff --git a/test/jdk/java/awt/Choice/SelectItem/SelectCurrentItemTest.java b/test/jdk/java/awt/Choice/SelectItem/SelectCurrentItemTest.java new file mode 100644 index 0000000000000..9bfcfeb9a97bc --- /dev/null +++ b/test/jdk/java/awt/Choice/SelectItem/SelectCurrentItemTest.java @@ -0,0 +1,207 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +/* + * @test + * @bug 4902933 8197810 + * @summary Test that selecting the current item does not send an ItemEvent + * @key headful + * @run main SelectCurrentItemTest +*/ +public class SelectCurrentItemTest + extends WindowAdapter + implements ItemListener { + private static Frame frame; + private static Choice choice; + + private final Robot robot; + + private final CountDownLatch windowOpened = new CountDownLatch(1); + private final CountDownLatch mouseClicked = new CountDownLatch(1); + + protected final CountDownLatch itemStateChanged = new CountDownLatch(1); + + protected SelectCurrentItemTest() throws AWTException { + robot = new Robot(); + robot.setAutoDelay(250); + } + + private void createUI() { + frame = new Frame(getClass().getName()); + frame.setLayout(new BorderLayout()); + + choice = new Choice(); + for (int i = 0; i < 10; i++) { + choice.add("Choice Item " + i); + } + choice.addItemListener(this); + choice.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("mouseClicked()"); + mouseClicked.countDown(); + } + }); + + frame.add(choice, BorderLayout.CENTER); + + frame.addWindowListener(this); + + frame.setLocationRelativeTo(null); + frame.setResizable(false); + frame.pack(); + frame.setVisible(true); + } + + protected final void runTest() + throws InterruptedException, InvocationTargetException { + try { + doTest(); + } finally { + EventQueue.invokeAndWait(this::dispose); + } + } + + private void doTest() + throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(this::createUI); + + if (!windowOpened.await(2, TimeUnit.SECONDS)) { + throw new RuntimeException("Frame is not open in time"); + } + robot.waitForIdle(); + + final int initialIndex = getSelectedIndex(); + + final Rectangle choiceRect = getChoiceRect(); + + // Open the choice popup + robot.mouseMove(choiceRect.x + choiceRect.width - 10, + choiceRect.y + choiceRect.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!mouseClicked.await(500, TimeUnit.MILLISECONDS)) { + throw new RuntimeException("Mouse is not clicked in time"); + } + robot.waitForIdle(); + + // Click an item in the choice popup + final Point pt = getClickLocation(choiceRect); + robot.mouseMove(pt.x, pt.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.waitForIdle(); + + checkItemStateChanged(); + + final int currentIndex = getSelectedIndex(); + System.out.println("initialIndex = " + initialIndex); + System.out.println("currentIndex = " + currentIndex); + checkSelectedIndex(initialIndex, currentIndex); + } + + protected void checkItemStateChanged() throws InterruptedException { + if (itemStateChanged.await(500, TimeUnit.MILLISECONDS)) { + throw new RuntimeException("ItemEvent is received but unexpected"); + } + } + + protected void checkSelectedIndex(final int initialIndex, + final int currentIndex) { + if (initialIndex != currentIndex) { + throw new RuntimeException("Selected index in Choice should not change"); + } + } + + /** + * {@return the location for clicking choice popup to select an item} + * @param choiceRect the bounds of the Choice component + */ + protected Point getClickLocation(final Rectangle choiceRect) { + // Click on the first item in the popup, it's the selected item + return new Point(choiceRect.x + choiceRect.width / 2, + choiceRect.y + choiceRect.height + 3); + } + + private int getSelectedIndex() + throws InterruptedException, InvocationTargetException { + AtomicInteger index = new AtomicInteger(); + EventQueue.invokeAndWait(() -> index.set(choice.getSelectedIndex())); + return index.get(); + } + + private Rectangle getChoiceRect() + throws InterruptedException, InvocationTargetException { + AtomicReference rect = new AtomicReference<>(); + EventQueue.invokeAndWait( + () -> rect.set(new Rectangle(choice.getLocationOnScreen(), + choice.getSize()))); + return rect.get(); + } + + public static void main(String... args) throws Exception { + new SelectCurrentItemTest().runTest(); + } + + private void dispose() { + if (frame != null) { + frame.dispose(); + } + } + + @Override + public final void itemStateChanged(ItemEvent e) { + System.out.println("itemStateChanged: " + e); + itemStateChanged.countDown(); + } + + @Override + public final void windowOpened(WindowEvent e) { + System.out.println("windowActivated()"); + windowOpened.countDown(); + } + +} diff --git a/test/jdk/java/awt/Choice/SelectItem/SelectNewItemTest.java b/test/jdk/java/awt/Choice/SelectItem/SelectNewItemTest.java new file mode 100644 index 0000000000000..1dba3fd905b66 --- /dev/null +++ b/test/jdk/java/awt/Choice/SelectItem/SelectNewItemTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Point; +import java.awt.Rectangle; +import java.util.concurrent.TimeUnit; + +/* + * @test + * @bug 8215921 + * @summary Test that selecting a different item does send an ItemEvent + * @key headful + * @run main SelectNewItemTest +*/ +public final class SelectNewItemTest + extends SelectCurrentItemTest { + + private SelectNewItemTest() throws AWTException { + super(); + } + + @Override + protected void checkItemStateChanged() throws InterruptedException { + if (!itemStateChanged.await(500, TimeUnit.MILLISECONDS)) { + throw new RuntimeException("ItemEvent is not received"); + } + } + + @Override + protected void checkSelectedIndex(final int initialIndex, + final int currentIndex) { + if (initialIndex == currentIndex) { + throw new RuntimeException("Selected index in Choice should've changed"); + } + } + + @Override + protected Point getClickLocation(final Rectangle choiceRect) { + // Click a different item the popup, not the first one + return new Point(choiceRect.x + choiceRect.width / 2, + choiceRect.y + choiceRect.height * 3); + } + + public static void main(String... args) throws Exception { + new SelectNewItemTest().runTest(); + } + +} diff --git a/test/jdk/java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java b/test/jdk/java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java deleted file mode 100644 index 502c5a161dff4..0000000000000 --- a/test/jdk/java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/* - @test - @bug 8215921 - @summary Test that selecting a different item does send an ItemEvent - @key headful - @run main SelectNewItemTest -*/ - -import java.awt.Choice; -import java.awt.Robot; -import java.awt.Frame; -import java.awt.BorderLayout; -import java.awt.AWTException; -import java.awt.Point; -import java.awt.Dimension; -import java.awt.event.InputEvent; -import java.awt.event.ItemListener; -import java.awt.event.WindowListener; -import java.awt.event.ItemEvent; -import java.awt.event.WindowEvent; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class SelectNewItemTest implements ItemListener, WindowListener { - //Declare things used in the test, like buttons and labels here - private Frame frame; - private Choice theChoice; - private Robot robot; - - private CountDownLatch latch = new CountDownLatch(1); - private volatile boolean passed = false; - - private void init() - { - try { - robot = new Robot(); - robot.setAutoDelay(500); - } catch (AWTException e) { - throw new RuntimeException("Unable to create Robot. Test fails."); - } - - frame = new Frame("SelectNewItemTest"); - frame.setLayout(new BorderLayout()); - theChoice = new Choice(); - for (int i = 0; i < 10; i++) { - theChoice.add(new String("Choice Item " + i)); - } - theChoice.addItemListener(this); - frame.add(theChoice); - frame.addWindowListener(this); - - frame.setLocation(1,20); - frame.setSize(200, 50); - robot.mouseMove(10, 30); - frame.pack(); - frame.setVisible(true); - } - - public static void main(String... args) { - SelectNewItemTest test = new SelectNewItemTest(); - test.init(); - try { - test.latch.await(12000, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) {} - test.robot.waitForIdle(); - - try { - if (!test.passed) { - throw new RuntimeException("TEST FAILED."); - } - } finally { - test.frame.dispose(); - } - } - - private void run() { - try { - Thread.sleep(1000); - - Point loc = theChoice.getLocationOnScreen(); - int selectedIndex = theChoice.getSelectedIndex(); - Dimension size = theChoice.getSize(); - - robot.mouseMove(loc.x + size.width - 10, loc.y + size.height / 2); - - robot.setAutoDelay(250); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - - robot.delay(1000); - - //make sure that the mouse moves to a different item, so that - //itemStateChanged is called. - robot.mouseMove(loc.x + size.width / 2, loc.y + 3 * size.height); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(); - - if (selectedIndex == theChoice.getSelectedIndex()) - throw new RuntimeException("Test case failed - expected to select" + - " a different item than " + selectedIndex); - - selectedIndex = theChoice.getSelectedIndex(); - //now click on the same item and make sure that item event is - //not generated. - robot.delay(1000); - robot.mouseMove(loc.x + size.width - 10, loc.y + size.height / 2); - - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - //Make sure that the popup menu scrolls back to show the index from - //beginning, so that the second mouse click happens on the previously - //selected item. - //For example, on windows, it automatically scrolls the list to show - //the currently selected item just below the choice, which can - //throw off the test. - if (System.getProperty("os.name").toLowerCase().startsWith("win")) { - robot.mouseWheel(-100); - } - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - - robot.delay(1000); - robot.mouseMove(loc.x + size.width / 2, loc.y + 3 * size.height); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(); - - if (selectedIndex != theChoice.getSelectedIndex()) - throw new RuntimeException("Test failed. Expected to select the same item " + - "located at: " + selectedIndex + " but got an item selected at: " + theChoice.getSelectedIndex()); - } catch(InterruptedException e) { - throw new RuntimeException(e.getCause()); - } finally { - latch.countDown(); - } - } - - @Override public void itemStateChanged(ItemEvent e) { - if (!passed) { - System.out.println("ItemEvent received. Test passes"); - passed = true; - } else { - System.out.println("ItemEvent received for second click. Test fails"); - passed = false; - } - } - - @Override public void windowOpened(WindowEvent e) { - System.out.println("windowActivated()"); - (new Thread(this::run)).start(); - } - - @Override public void windowActivated(WindowEvent e) {} - @Override public void windowDeactivated(WindowEvent e) {} - @Override public void windowClosed(WindowEvent e) {} - @Override public void windowClosing(WindowEvent e) {} - @Override public void windowIconified(WindowEvent e) {} - @Override public void windowDeiconified(WindowEvent e) {} -} diff --git a/test/jdk/java/foreign/TestSegmentCopy.java b/test/jdk/java/foreign/TestSegmentCopy.java index 88636bf5420ce..9a4500b2f5a1a 100644 --- a/test/jdk/java/foreign/TestSegmentCopy.java +++ b/test/jdk/java/foreign/TestSegmentCopy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -30,7 +30,6 @@ import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteOrder; import java.util.ArrayList; @@ -76,6 +75,94 @@ public void testByteCopy(SegmentKind kind1, SegmentKind kind2) { } } + @Test(dataProvider = "conjunctSegments") + public void testCopy5ArgInvariants(MemorySegment src, MemorySegment dst) { + assertThrows(IndexOutOfBoundsException.class, () -> MemorySegment.copy(src, 0, dst, 0, -1)); + assertThrows(IndexOutOfBoundsException.class, () -> MemorySegment.copy(src, -1, dst, 0, src.byteSize())); + assertThrows(IndexOutOfBoundsException.class, () -> MemorySegment.copy(src, 0, dst, -1, src.byteSize())); + assertThrows(IndexOutOfBoundsException.class, () -> MemorySegment.copy(src, 1, dst, 0, src.byteSize())); + assertThrows(IndexOutOfBoundsException.class, () -> MemorySegment.copy(src, 0, dst, 1, src.byteSize())); + } + + @Test(dataProvider = "conjunctSegments") + public void testConjunctCopy7ArgRight(MemorySegment src, MemorySegment dst) { + testConjunctCopy(src, 0, dst, 1, CopyOp.of7Arg()); + } + + @Test(dataProvider = "conjunctSegments") + public void testConjunctCopy5ArgRight(MemorySegment src, MemorySegment dst) { + testConjunctCopy(src, 0, dst, 1, CopyOp.of5Arg()); + } + + @Test(dataProvider = "conjunctSegments") + public void testConjunctCopy7ArgLeft(MemorySegment src, MemorySegment dst) { + testConjunctCopy(src, 1, dst, 0, CopyOp.of7Arg()); + } + + @Test(dataProvider = "conjunctSegments") + public void testConjunctCopy5ArgLeft(MemorySegment src, MemorySegment dst) { + testConjunctCopy(src, 1, dst, 0, CopyOp.of5Arg()); + } + + void testConjunctCopy(MemorySegment src, long srcOffset, MemorySegment dst, long dstOffset, CopyOp op) { + if (src.byteSize() < 4 || src.address() != dst.address()) { + // Only test larger segments where the skew is zero + return; + } + + try (var arena = Arena.ofConfined()) { + // Create a disjoint segment for expected behavior + MemorySegment disjoint = arena.allocate(dst.byteSize()); + disjoint.copyFrom(src); + op.copy(src, srcOffset, disjoint, dstOffset, 3); + byte[] expected = disjoint.toArray(JAVA_BYTE); + + // Do a conjoint copy + op.copy(src, srcOffset, dst, dstOffset, 3); + byte[] actual = dst.toArray(JAVA_BYTE); + + assertEquals(actual, expected); + } + } + + @FunctionalInterface + interface CopyOp { + void copy(MemorySegment src, long srcOffset, MemorySegment dst, long dstOffset, long bytes); + + static CopyOp of5Arg() { + return MemorySegment::copy; + } + + static CopyOp of7Arg() { + return (MemorySegment src, long srcOffset, MemorySegment dst, long dstOffset, long bytes) -> + MemorySegment.copy(src, JAVA_BYTE, srcOffset, dst, JAVA_BYTE, dstOffset, bytes); + } + + } + + @Test(dataProvider = "segmentKinds") + public void testByteCopySizes(SegmentKind kind1, SegmentKind kind2) { + + record Offsets(int src, int dst){} + + for (Offsets offsets : List.of(new Offsets(3, 7), new Offsets(7, 3))) { + for (int size = 0; size < 513; size++) { + MemorySegment src = kind1.makeSegment(size + offsets.src()); + MemorySegment dst = kind2.makeSegment(size + offsets.dst()); + //prepare source slice + for (int i = 0; i < size; i++) { + src.set(JAVA_BYTE, i + offsets.src(), (byte) i); + } + //perform copy + MemorySegment.copy(src, offsets.src(), dst, offsets.dst(), size); + //check that copy actually worked + for (int i = 0; i < size; i++) { + assertEquals(dst.get(JAVA_BYTE, i + offsets.dst()), (byte) i); + } + } + } + } + @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "segmentKinds") public void testReadOnlyCopy(SegmentKind kind1, SegmentKind kind2) { MemorySegment s1 = kind1.makeSegment(TEST_BYTE_SIZE); @@ -277,6 +364,28 @@ static Object[][] segmentKinds() { return cases.toArray(Object[][]::new); } + @DataProvider + static Object[][] conjunctSegments() { + List cases = new ArrayList<>(); + for (SegmentKind kind : SegmentKind.values()) { + // Different paths might be taken in the implementation depending on the + // size, type, and address of the underlying segments. + for (int len : new int[]{0, 1, 7, 512}) { + for (int offset : new int[]{-1, 0, 1}) { + MemorySegment segment = kind.makeSegment(len + 2); + MemorySegment src = segment.asSlice(1 + offset, len); + MemorySegment dst = segment.asSlice(1, len); + for (int i = 0; i < len; i++) { + src.set(JAVA_BYTE, i, (byte) i); + } + // src = 0, 1, ... , len-1 + cases.add(new Object[]{src, dst}); + } + } + } + return cases.toArray(Object[][]::new); + } + @DataProvider static Object[][] types() { return Arrays.stream(Type.values()) diff --git a/test/jdk/java/lang/String/CountNonZeroAscii.java b/test/jdk/java/lang/String/CountNonZeroAscii.java new file mode 100644 index 0000000000000..d4b8a4fb1ebb4 --- /dev/null +++ b/test/jdk/java/lang/String/CountNonZeroAscii.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/* + * @test + * @modules java.base/jdk.internal.access + * @summary test latin1 String countNonZeroAscii + * @run main/othervm -XX:+CompactStrings CountNonZeroAscii + * @run main/othervm -XX:-CompactStrings CountNonZeroAscii + */ +public class CountNonZeroAscii { + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + public static void main(String [] args) { + byte[] bytes = new byte[1000]; + + Arrays.fill(bytes, (byte) 'A'); + String s = new String(bytes, StandardCharsets.ISO_8859_1); + assertEquals(bytes.length, JLA.countNonZeroAscii(s)); + + for (int i = 0; i < bytes.length; i++) { + for (int j = Byte.MIN_VALUE; j <= 0; j++) { + bytes[i] = (byte) j; + s = new String(bytes, StandardCharsets.ISO_8859_1); + assertEquals(i, JLA.countNonZeroAscii(s)); + } + bytes[i] = (byte) 'A'; + } + } + + static void assertEquals(int expected, int actual) { + if (expected != actual) { + throw new AssertionError("Expected " + expected + " but got " + actual); + } + } +} diff --git a/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java b/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java index 96ef9edc57100..5b21c07f71e35 100644 --- a/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java +++ b/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java @@ -99,6 +99,7 @@ private void createGUI() { frame.setLocation(200, 200); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); button.setPreferredSize(new Dimension(300, 300)); + button.setFocusPainted(false); button.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent fe) { focusGainedLatch.countDown(); @@ -124,9 +125,8 @@ public void runTest() throws Exception { try { robot = new Robot(); - robot.setAutoWaitForIdle(true); - robot.setAutoDelay(200); - + robot.waitForIdle(); + robot.delay(1000); if (focusGainedLatch.await(3, TimeUnit.SECONDS)) { System.out.println("Button focus gained..."); } else { @@ -142,17 +142,18 @@ public void runTest() throws Exception { // some platforms may not support maximize frame if (frame.getToolkit().isFrameStateSupported( JFrame.MAXIMIZED_BOTH)) { - robot.waitForIdle(); // maximize frame from normal size frame.setExtendedState(JFrame.MAXIMIZED_BOTH); System.out.println("Frame is maximized"); robot.waitForIdle(); + robot.delay(100); if (frame.getToolkit().isFrameStateSupported(JFrame.NORMAL)) { System.out.println("Frame is back to normal"); // resize from maximum size to normal frame.setExtendedState(JFrame.NORMAL); - + robot.waitForIdle(); + robot.delay(100); // capture image of JButton after resize System.out.println( "Getting image of JButton after resize..image2"); @@ -209,9 +210,8 @@ private BufferedImage getButtonImage() { } private void disposeFrame() { - if (frame != null) { + if(frame != null) { frame.dispose(); - frame = null; } } diff --git a/test/jdk/sun/security/validator/samedn.sh b/test/jdk/sun/security/validator/samedn.sh index 6a30b14715721..a38d6e7099003 100644 --- a/test/jdk/sun/security/validator/samedn.sh +++ b/test/jdk/sun/security/validator/samedn.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 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 @@ -62,10 +62,11 @@ $KT -genkeypair -alias ca1 -dname CN=CA -keyalg rsa -sigalg md5withrsa -ext bc - $KT -genkeypair -alias ca2 -dname CN=CA -keyalg rsa -sigalg sha1withrsa -ext bc -startdate -1y $KT -genkeypair -alias user -dname CN=User -keyalg rsa -# 2. Signing: ca -> user +# 2. Signing: ca -> user. The startdate is set to 1 minute in the past to ensure the certificate +# is valid at the time of validation and to prevent any issues with timing discrepancies -$KT -certreq -alias user | $KT -gencert -rfc -alias ca1 > samedn1.certs -$KT -certreq -alias user | $KT -gencert -rfc -alias ca2 > samedn2.certs +$KT -certreq -alias user | $KT -gencert -rfc -alias ca1 -startdate -1M > samedn1.certs +$KT -certreq -alias user | $KT -gencert -rfc -alias ca2 -startdate -1M > samedn2.certs # 3. Append the ca file diff --git a/test/micro/org/openjdk/bench/java/lang/classfile/Utf8EntryWriteTo.java b/test/micro/org/openjdk/bench/java/lang/classfile/Utf8EntryWriteTo.java new file mode 100644 index 0000000000000..a124b0792688a --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/classfile/Utf8EntryWriteTo.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 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 + * 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.classfile; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.lang.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.*; +import java.lang.constant.*; +import java.nio.charset.StandardCharsets; +import java.util.HexFormat; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +import static java.lang.classfile.ClassFile.*; +import static java.lang.constant.ConstantDescs.*; + +import jdk.internal.classfile.impl.*; +/** + * Test various operations on + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 1, time = 2) +@Measurement(iterations = 3, time = 1) +@Fork(jvmArgsAppend = "--enable-preview", value = 3) +@State(Scope.Thread) +public class Utf8EntryWriteTo { + static final ClassDesc STRING_BUILDER = ClassDesc.ofDescriptor("Ljava/lang/StringBuilder;"); + static final MethodTypeDesc MTD_append = MethodTypeDesc.of(STRING_BUILDER, CD_String); + static final MethodTypeDesc MTD_String = MethodTypeDesc.of(CD_String); + static final ClassDesc CLASS_DESC = ClassDesc.ofDescriptor("Lorg/openjdk/bench/java/lang/classfile/String$$StringConcat;"); + + @Param({"ascii", "utf8_2_bytes", "utf8_3_bytes", "emoji"}) + public String charType; + ConstantPoolBuilder poolBuilder; + ClassEntry thisClass; + + @Setup + public void setup() throws Exception { + byte[] bytes = HexFormat.of().parseHex( + switch (charType) { + case "ascii" -> "78"; + case "utf8_2_bytes" -> "c2a9"; + case "utf8_3_bytes" -> "e6b8a9"; + case "emoji" -> "e29da3efb88f"; + default -> throw new IllegalArgumentException("bad charType: " + charType); + } + ); + String s = new String(bytes, 0, bytes.length, StandardCharsets.UTF_8); + String[] constants = new String[128]; + for (int i = 0; i < constants.length; i++) { + constants[i] = "A".repeat(i).concat(s); + } + + poolBuilder = ConstantPoolBuilder.of(); + thisClass = poolBuilder.classEntry(CLASS_DESC); + for (var c : constants) { + poolBuilder.utf8Entry(c); + } + } + + @Benchmark + public void writeTo(Blackhole bh) { + bh.consume(ClassFile + .of() + .build(thisClass, poolBuilder, (ClassBuilder clb) -> {})); + } +} diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/CopyTest.java b/test/micro/org/openjdk/bench/java/lang/foreign/CopyTest.java new file mode 100644 index 0000000000000..8996b1de11742 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/foreign/CopyTest.java @@ -0,0 +1,107 @@ +/* + * 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.concurrent.TimeUnit; + +import static java.lang.foreign.ValueLayout.*; + +@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 CopyTest { + + @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", + "33", "36", "40", "44", "48", "52", "56", "60", "63", "64", "128"}) + public int ELEM_SIZE; + + byte[] srcArray; + byte[] dstArray; + MemorySegment heapSrcSegment; + MemorySegment heapDstSegment; + MemorySegment nativeSrcSegment; + MemorySegment nativeDstSegment; + ByteBuffer srcBuffer; + ByteBuffer dstBuffer; + + @Setup + public void setup() { + srcArray = new byte[ELEM_SIZE]; + dstArray = new byte[ELEM_SIZE]; + heapSrcSegment = MemorySegment.ofArray(srcArray); + heapDstSegment = MemorySegment.ofArray(dstArray); + nativeSrcSegment = Arena.ofAuto().allocate(ELEM_SIZE); + nativeDstSegment = Arena.ofAuto().allocate(ELEM_SIZE); + srcBuffer = ByteBuffer.wrap(srcArray); + dstBuffer = ByteBuffer.wrap(dstArray); + } + + @Benchmark + public void array_copy() { + System.arraycopy(srcArray, 0, dstArray, 0, ELEM_SIZE); + } + + @Benchmark + public void heap_segment_copy5Arg() { + MemorySegment.copy(heapSrcSegment, 0, heapDstSegment, 0, ELEM_SIZE); + } + + @Benchmark + public void native_segment_copy5Arg() { + MemorySegment.copy(nativeSrcSegment, 0, nativeDstSegment, 0, ELEM_SIZE); + } + + @Benchmark + public void heap_segment_copy7arg() { + MemorySegment.copy(heapSrcSegment, JAVA_BYTE, 0, heapDstSegment, JAVA_BYTE, 0, ELEM_SIZE); + } + + @Benchmark + public void buffer_copy() { + dstBuffer.put(srcBuffer); + } + +}