From 0562caa4cb2b4ef35bb6a62ce081cafa877d93de Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 8 Jan 2020 19:12:20 +0100 Subject: [PATCH 01/54] 8236487: JFR Recorder Thread crashed due to "assert(_chunkwriter.is_valid()) failed: invariant" Reviewed-by: mgronlun, mseledtsov --- .../share/jfr/recorder/service/jfrRecorderService.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp index ccfc614b965..1fd337657de 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -671,7 +671,9 @@ void JfrRecorderService::invoke_flush() { void JfrRecorderService::flushpoint() { MutexLocker lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); - invoke_flush(); + if (_chunkwriter.is_valid()) { + invoke_flush(); + } } void JfrRecorderService::process_full_buffers() { From be6b4aab40aca925250d074f945124ca8ce77163 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 8 Jan 2020 15:18:58 -0500 Subject: [PATCH 02/54] 8236692: static final fields without initializer are accepted by javac Reviewed-by: mcimadamore --- .../com/sun/tools/javac/comp/Flow.java | 40 +++++++++++-------- .../javac/records/RecordCompilationTests.java | 12 ++++++ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 89e444adf47..26a58e1f7b4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1855,21 +1855,17 @@ public class Flow { /** Check that trackable variable is initialized. */ - boolean checkInit(DiagnosticPosition pos, VarSymbol sym, boolean compactConstructor) { - return checkInit(pos, sym, Errors.VarMightNotHaveBeenInitialized(sym), compactConstructor); + void checkInit(DiagnosticPosition pos, VarSymbol sym) { + checkInit(pos, sym, Errors.VarMightNotHaveBeenInitialized(sym)); } - boolean checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey, boolean compactConstructor) { + void checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey) { if ((sym.adr >= firstadr || sym.owner.kind != TYP) && trackable(sym) && !inits.isMember(sym.adr)) { - if (sym.owner.kind != TYP || !compactConstructor || !uninits.isMember(sym.adr)) { log.error(pos, errkey); - } inits.incl(sym.adr); - return false; } - return true; } /** Utility method to reset several Bits instances. @@ -2099,15 +2095,27 @@ public class Flow { // the ctor is default(synthesized) or not if (isSynthesized && !isCompactConstructor) { checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), - var, Errors.VarNotInitializedInDefaultConstructor(var), isCompactConstructor); - } else { - boolean wasInitialized = checkInit(TreeInfo.diagEndPos(tree.body), var, isCompactConstructor && tree.completesNormally); - if (!wasInitialized && var.owner.kind == TYP && isCompactConstructor && uninits.isMember(var.adr) && tree.completesNormally) { + var, Errors.VarNotInitializedInDefaultConstructor(var)); + } else if (isCompactConstructor) { + boolean isInstanceRecordField = var.enclClass().isRecord() && + (var.flags_field & (Flags.PRIVATE | Flags.FINAL | Flags.GENERATED_MEMBER | Flags.RECORD)) != 0 && + !var.isStatic() && + var.owner.kind == TYP; + if (isInstanceRecordField) { + boolean notInitialized = !inits.isMember(var.adr); + if (notInitialized && uninits.isMember(var.adr) && tree.completesNormally) { /* this way we indicate Lower that it should generate an initialization for this field * in the compact constructor */ - var.flags_field |= UNINITIALIZED_FIELD; + var.flags_field |= UNINITIALIZED_FIELD; + } else { + checkInit(TreeInfo.diagEndPos(tree.body), var); + } + } else { + checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), var); } + } else { + checkInit(TreeInfo.diagEndPos(tree.body), var); } } } @@ -2124,7 +2132,7 @@ public class Flow { Assert.check(exit instanceof AssignPendingExit); inits.assign(((AssignPendingExit) exit).exit_inits); for (int i = firstadr; i < nextadr; i++) { - checkInit(exit.tree.pos(), vardecls[i].sym, isCompactConstructor); + checkInit(exit.tree.pos(), vardecls[i].sym); } } } @@ -2666,7 +2674,7 @@ public class Flow { super.visitSelect(tree); if (TreeInfo.isThisQualifier(tree.selected) && tree.sym.kind == VAR) { - checkInit(tree.pos(), (VarSymbol)tree.sym, false); + checkInit(tree.pos(), (VarSymbol)tree.sym); } } @@ -2727,7 +2735,7 @@ public class Flow { public void visitIdent(JCIdent tree) { if (tree.sym.kind == VAR) { - checkInit(tree.pos(), (VarSymbol)tree.sym, false); + checkInit(tree.pos(), (VarSymbol)tree.sym); referenced(tree.sym); } } diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java index f8af16a8696..bf4f18f373b 100644 --- a/test/langtools/tools/javac/records/RecordCompilationTests.java +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java @@ -406,6 +406,18 @@ public class RecordCompilationTests extends CompilationTestCase { // x is not DA nor DU in the body of the constructor hence error assertFail("compiler.err.var.might.not.have.been.initialized", "record R(int x) { # }", "public R { if (x < 0) { this.x = -x; } }"); + + // if static fields are not DA then error + assertFail("compiler.err.var.might.not.have.been.initialized", + "record R() { # }", "static final String x;"); + + // ditto + assertFail("compiler.err.var.might.not.have.been.initialized", + "record R() { # }", "static final String x; public R {}"); + + // ditto + assertFail("compiler.err.var.might.not.have.been.initialized", + "record R(int i) { # }", "static final String x; public R {}"); } public void testReturnInCanonical_Compact() { From 450b97f593274610233b3ddeceb06e33bd9731a3 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Thu, 12 Dec 2019 18:34:30 +0100 Subject: [PATCH 03/54] 8234974: Shenandoah: Do concurrent roots even when no evacuation is necessary Reviewed-by: zgu --- .../share/gc/shenandoah/shenandoahBarrierSet.cpp | 2 +- .../gc/shenandoah/shenandoahClosures.inline.hpp | 6 ++++-- .../share/gc/shenandoah/shenandoahCodeRoots.cpp | 6 ++++-- .../share/gc/shenandoah/shenandoahCodeRoots.hpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 14 ++++++++++---- .../share/gc/shenandoah/shenandoahUnload.cpp | 4 ++-- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index bc227b965d2..4d0bfa4b7f5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -264,7 +264,7 @@ oop ShenandoahBarrierSet::load_reference_barrier_native_impl(oop obj, T* load_ad } ShenandoahMarkingContext* const marking_context = _heap->marking_context(); - if (_heap->is_evacuation_in_progress() && !marking_context->is_marked(obj)) { + if (_heap->is_concurrent_root_in_progress() && !marking_context->is_marked(obj)) { Thread* thr = Thread::current(); if (thr->is_Java_thread()) { return NULL; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp index 7f8809a07ac..ab61567c4be 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp @@ -111,12 +111,13 @@ ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() : template void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); T o = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); if (_heap->in_collection_set(obj)) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); shenandoah_assert_marked(p, obj); oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (resolved == obj) { @@ -139,11 +140,12 @@ ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsC } void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); oop obj = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(obj)) { if (_heap->in_collection_set(obj)) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); shenandoah_assert_marked(p, obj); oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (resolved == obj) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 7829bfb6d84..11073985a70 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -155,7 +155,7 @@ void ShenandoahCodeRoots::flush_nmethod(nmethod* nm) { } } -void ShenandoahCodeRoots::prepare_concurrent_unloading() { +void ShenandoahCodeRoots::arm_nmethods() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); _disarmed_value ++; // 0 is reserved for new nmethod @@ -224,7 +224,9 @@ public: // Heal oops and disarm ShenandoahEvacOOMScope evac_scope; - ShenandoahNMethod::heal_nmethod(nm); + if (_heap->is_evacuation_in_progress()) { + ShenandoahNMethod::heal_nmethod(nm); + } ShenandoahNMethod::disarm_nmethod(nm); // Clear compiled ICs and exception caches diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp index 42661f4f870..4347192a578 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp @@ -109,7 +109,7 @@ public: // Concurrent nmethod unloading support static void unlink(WorkGang* workers, bool unloading_occurred); static void purge(WorkGang* workers); - static void prepare_concurrent_unloading(); + static void arm_nmethods(); static int disarmed_value() { return _disarmed_value; } static int* disarmed_value_address() { return &_disarmed_value; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 4b7b58d7ef6..3f2d4412068 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -542,6 +542,7 @@ void ShenandoahHeap::print_on(outputStream* st) const { if (is_degenerated_gc_in_progress()) st->print("degenerated gc, "); if (is_full_gc_in_progress()) st->print("full gc, "); if (is_full_gc_move_in_progress()) st->print("full gc move, "); + if (is_concurrent_root_in_progress()) st->print("concurrent roots, "); if (cancelled_gc()) { st->print("cancelled"); @@ -1540,6 +1541,11 @@ void ShenandoahHeap::op_final_mark() { _free_set->rebuild(); } + if (!is_degenerated_gc_in_progress()) { + prepare_concurrent_roots(); + prepare_concurrent_unloading(); + } + // If collection set has candidates, start evacuation. // Otherwise, bypass the rest of the cycle. if (!collection_set()->is_empty()) { @@ -1554,8 +1560,9 @@ void ShenandoahHeap::op_final_mark() { set_has_forwarded_objects(true); if (!is_degenerated_gc_in_progress()) { - prepare_concurrent_roots(); - prepare_concurrent_unloading(); + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + ShenandoahCodeRoots::arm_nmethods(); + } evacuate_and_update_roots(); } @@ -1669,7 +1676,7 @@ public: }; void ShenandoahHeap::op_roots() { - if (is_evacuation_in_progress()) { + if (is_concurrent_root_in_progress()) { if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { _unloader.unload(); } @@ -2235,7 +2242,6 @@ void ShenandoahHeap::prepare_concurrent_roots() { void ShenandoahHeap::prepare_concurrent_unloading() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { - ShenandoahCodeRoots::prepare_concurrent_unloading(); _unloader.prepare(); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index 1022cdd5b90..3d2dc79e2de 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -79,7 +79,7 @@ class ShenandoahIsUnloadingBehaviour : public IsUnloadingBehaviour { public: virtual bool is_unloading(CompiledMethod* method) const { nmethod* const nm = method->as_nmethod(); - guarantee(ShenandoahHeap::heap()->is_evacuation_in_progress(), "Only this phase"); + guarantee(ShenandoahHeap::heap()->is_concurrent_root_in_progress(), "Only this phase"); ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); ShenandoahReentrantLocker locker(data->lock()); ShenandoahIsUnloadingOopClosure cl; @@ -166,7 +166,7 @@ public: void ShenandoahUnload::unload() { assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?"); - if (!ShenandoahHeap::heap()->is_evacuation_in_progress()) { + if (!ShenandoahHeap::heap()->is_concurrent_root_in_progress()) { return; } From 0591a66b909abfd650b886e4cf6213d0aedd4701 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 12 Dec 2019 15:20:53 -0500 Subject: [PATCH 04/54] 8235842: Shenandoah: Implement native LRB for narrow oop Reviewed-by: rkennke --- src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index 4d0bfa4b7f5..153af9cea32 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -252,9 +252,7 @@ oop ShenandoahBarrierSet::load_reference_barrier_native(oop obj, oop* load_addr) } oop ShenandoahBarrierSet::load_reference_barrier_native(oop obj, narrowOop* load_addr) { - // Assumption: narrow oop version should not be used anywhere. - ShouldNotReachHere(); - return NULL; + return load_reference_barrier_native_impl(obj, load_addr); } template From 950ebec4a919de61f1f2c2db6f0f08d01beb6fb9 Mon Sep 17 00:00:00 2001 From: Aditya Mandaleeka Date: Fri, 20 Dec 2019 19:51:00 +0100 Subject: [PATCH 05/54] 8236179: C1 register allocation error with T_ADDRESS Reviewed-by: rkennke, vlivanov, roland, mdoerr --- src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp | 2 ++ src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp | 4 ++-- src/hotspot/cpu/arm/c1_FrameMap_arm.cpp | 4 +++- src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp | 4 ++++ src/hotspot/cpu/s390/c1_FrameMap_s390.cpp | 2 ++ src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp | 4 ++-- src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp | 2 ++ src/hotspot/cpu/x86/c1_FrameMap_x86.cpp | 2 ++ src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp | 4 ++-- src/hotspot/share/c1/c1_FrameMap.hpp | 4 ++++ 10 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp index b461affefe2..4257e3445ea 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp @@ -49,6 +49,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index f9a96e04de7..45632635f44 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -759,7 +759,7 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (is_reference_type(type)) { __ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix())); __ verify_oop(src->as_register()); - } else if (type == T_METADATA || type == T_DOUBLE) { + } else if (type == T_METADATA || type == T_DOUBLE || type == T_ADDRESS) { __ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix())); } else { __ strw(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix())); @@ -872,7 +872,7 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (is_reference_type(type)) { __ ldr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); __ verify_oop(dest->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ ldr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); } else { __ ldrw(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); diff --git a/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp b/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp index cb234675241..bd74c3f83b4 100644 --- a/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp +++ b/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp @@ -80,10 +80,12 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { Register reg = r_1->as_Register(); if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { opr = as_long_opr(reg, r_2->as_Register()); - } else if (type == T_OBJECT || type == T_ARRAY) { + } else if (is_reference_type(type)) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { // PreferInterpreterNativeStubs should ensure we never need to // handle a long opr passed as R3+stack_slot diff --git a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp index f73e6b1be5f..7de34093cfe 100644 --- a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp @@ -54,6 +54,10 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { opr = as_long_opr(reg); } else if (is_reference_type(type)) { opr = as_oop_opr(reg); + } else if (type == T_METADATA) { + opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp index 12dda5e344e..d639de695b3 100644 --- a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp +++ b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp @@ -50,6 +50,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index afacc715bde..3c6e7e460ad 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -1007,7 +1007,7 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (is_reference_type(type)) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); __ verify_oop(dest->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); } else { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), false); @@ -1035,7 +1035,7 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (is_reference_type(type)) { __ verify_oop(src->as_register()); __ reg2mem_opt(src->as_register(), dst, true); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ reg2mem_opt(src->as_register(), dst, true); } else { __ reg2mem_opt(src->as_register(), dst, false); diff --git a/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp b/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp index 22d980aba76..2e2e737d850 100644 --- a/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp +++ b/src/hotspot/cpu/sparc/c1_FrameMap_sparc.cpp @@ -55,6 +55,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp b/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp index 958065f3521..f25cefb8a44 100644 --- a/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp +++ b/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp @@ -54,6 +54,8 @@ LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { opr = as_oop_opr(reg); } else if (type == T_METADATA) { opr = as_metadata_opr(reg); + } else if (type == T_ADDRESS) { + opr = as_address_opr(reg); } else { opr = as_opr(reg); } diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index b508084ad6b..4fb9dd1bb27 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -935,7 +935,7 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (is_reference_type(type)) { __ verify_oop(src->as_register()); __ movptr (dst, src->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ movptr (dst, src->as_register()); } else { __ movl (dst, src->as_register()); @@ -1116,7 +1116,7 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (is_reference_type(type)) { __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); __ verify_oop(dest->as_register()); - } else if (type == T_METADATA) { + } else if (type == T_METADATA || type == T_ADDRESS) { __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); } else { __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); diff --git a/src/hotspot/share/c1/c1_FrameMap.hpp b/src/hotspot/share/c1/c1_FrameMap.hpp index b993e231fa8..eca2460ee3a 100644 --- a/src/hotspot/share/c1/c1_FrameMap.hpp +++ b/src/hotspot/share/c1/c1_FrameMap.hpp @@ -185,6 +185,10 @@ class FrameMap : public CompilationResourceObj { return LIR_OprFact::single_cpu_metadata(cpu_reg2rnr(r)); } + static LIR_Opr as_address_opr(Register r) { + return LIR_OprFact::single_cpu_address(cpu_reg2rnr(r)); + } + FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size); bool finalize_frame(int nof_slots); From 773b7b6c4bb99dfb3527fe8438959b42a1f17517 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 17 Dec 2019 18:23:33 +0100 Subject: [PATCH 06/54] 8236106: [TESTBUG] Shenandoah: Make TestThreadFailure more resilient Reviewed-by: zgu --- test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java index a31c5ed4133..e00ddbac94c 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java @@ -63,7 +63,7 @@ public class TestThreadFailure { { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-Xmx64m", + "-Xmx32m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestThreadFailure.class.getName(), From 49b1cc8ee65bf218507fc4fa3d245bc2fbca4dbb Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 7 Jan 2020 13:45:10 +0100 Subject: [PATCH 07/54] 8236181: C2: Remove useless step_over_gc_barrier() in int->bool conversion Reviewed-by: thartmann, roland --- src/hotspot/share/opto/cfgnode.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 0327d0c6317..146d53f8a14 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -1449,10 +1449,7 @@ static Node *is_x2logic( PhaseGVN *phase, PhiNode *phi, int true_path ) { } else return NULL; // Build int->bool conversion - Node *in1 = cmp->in(1); - BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); - in1 = bs->step_over_gc_barrier(in1); - Node *n = new Conv2BNode(in1); + Node *n = new Conv2BNode(cmp->in(1)); if( flipped ) n = new XorINode( phase->transform(n), phase->intcon(1) ); From 9e09ba5e138b3d8ada816ded9c17e10358575299 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 7 Jan 2020 08:53:37 -0500 Subject: [PATCH 08/54] 8236681: Shenandoah: Disable concurrent class unloading flag if no class unloading for the GC cycle Reviewed-by: rkennke --- .../share/gc/shenandoah/shenandoahConcurrentRoots.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp index 2d8478f262b..a04b7e1642b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved. * * 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 @@ -47,6 +47,8 @@ bool ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() { } bool ShenandoahConcurrentRoots::should_do_concurrent_class_unloading() { + ShenandoahHeap* const heap = ShenandoahHeap::heap(); return can_do_concurrent_class_unloading() && - !ShenandoahHeap::heap()->is_stw_gc_in_progress(); + heap->unload_classes() && + !heap->is_stw_gc_in_progress(); } From ba6cedcf2466356ba5283f47a95fb6fffc73d875 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 7 Jan 2020 21:53:52 +0100 Subject: [PATCH 09/54] 8236732: Shenandoah: Stricter placement for oom-evac scopes Reviewed-by: zgu --- src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp | 8 ++------ .../share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp | 1 - src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp | 2 -- .../share/gc/shenandoah/shenandoahEvacOOMHandler.cpp | 8 -------- .../share/gc/shenandoah/shenandoahEvacOOMHandler.hpp | 6 ------ src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp | 1 + .../share/gc/shenandoah/shenandoahParallelCleaning.cpp | 1 - .../share/gc/shenandoah/shenandoahTraversalGC.cpp | 9 --------- .../share/gc/shenandoah/shenandoahTraversalGC.inline.hpp | 1 + 9 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index 153af9cea32..e2ad72d656a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -199,12 +199,8 @@ oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) { _heap->in_collection_set(obj) && obj == fwd) { Thread *t = Thread::current(); - if (t->is_GC_task_thread()) { - return _heap->evacuate_object(obj, t); - } else { - ShenandoahEvacOOMScope oom_evac_scope; - return _heap->evacuate_object(obj, t); - } + ShenandoahEvacOOMScope oom_evac_scope; + return _heap->evacuate_object(obj, t); } else { return fwd; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp index 300b04303e5..65938aad6dc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp @@ -57,7 +57,6 @@ bool ShenandoahBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { } // Heal oops and disarm - ShenandoahEvacOOMScope scope; ShenandoahNMethod::heal_nmethod(nm); ShenandoahNMethod::disarm_nmethod(nm); return true; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 11073985a70..46c9ee45eae 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -215,7 +215,6 @@ public: if (nm->is_unloading()) { ShenandoahReentrantLocker locker(nm_data->lock()); - ShenandoahEvacOOMScope evac_scope; unlink(nm); return; } @@ -223,7 +222,6 @@ public: ShenandoahReentrantLocker locker(nm_data->lock()); // Heal oops and disarm - ShenandoahEvacOOMScope evac_scope; if (_heap->is_evacuation_in_progress()) { ShenandoahNMethod::heal_nmethod(nm); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp index 64944d9974b..55bf51c5bd7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp @@ -123,11 +123,3 @@ ShenandoahEvacOOMScope::ShenandoahEvacOOMScope() { ShenandoahEvacOOMScope::~ShenandoahEvacOOMScope() { ShenandoahHeap::heap()->leave_evacuation(); } - -ShenandoahEvacOOMScopeLeaver::ShenandoahEvacOOMScopeLeaver() { - ShenandoahHeap::heap()->leave_evacuation(); -} - -ShenandoahEvacOOMScopeLeaver::~ShenandoahEvacOOMScopeLeaver() { - ShenandoahHeap::heap()->enter_evacuation(); -} diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp index b81b45cc7e6..19305a8bb17 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.hpp @@ -119,10 +119,4 @@ public: ~ShenandoahEvacOOMScope(); }; -class ShenandoahEvacOOMScopeLeaver : public StackObj { -public: - ShenandoahEvacOOMScopeLeaver(); - ~ShenandoahEvacOOMScopeLeaver(); -}; - #endif // SHARE_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp index ff30be1b1bb..27b34b5d4fb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp @@ -174,6 +174,7 @@ void ShenandoahNMethod::heal_nmethod(nmethod* nm) { assert(data != NULL, "Sanity"); assert(data->lock()->owned_by_self(), "Must hold the lock"); + ShenandoahEvacOOMScope evac_scope; ShenandoahEvacuateUpdateRootsClosure cl; data->oops_do(&cl, true /*fix relocation*/); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp b/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp index 4fef09ddbd3..08b750dd611 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp @@ -41,7 +41,6 @@ ShenandoahClassUnloadingTask::ShenandoahClassUnloadingTask(BoolObjectClosure* is } void ShenandoahClassUnloadingTask::work(uint worker_id) { - ShenandoahEvacOOMScope scope; _code_cache_task.work(worker_id); // Clean all klasses that were not unloaded. // The weak metadata in klass doesn't need to be diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp index 205d1b4bc86..5fd46980d53 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp @@ -173,7 +173,6 @@ public: void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahObjToScanQueueSet* queues = _heap->traversal_gc()->task_queues(); ShenandoahObjToScanQueue* q = queues->queue(worker_id); @@ -214,7 +213,6 @@ public: void work(uint worker_id) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); // Drain all outstanding work in queues. @@ -237,7 +235,6 @@ public: void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc(); ShenandoahObjToScanQueueSet* queues = traversal_gc->task_queues(); @@ -542,7 +539,6 @@ void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worke if (work == 0) { // No more work, try to terminate - ShenandoahEvacOOMScopeLeaver oom_scope_leaver; ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers); ShenandoahTerminationTimingsTracker term_tracker(worker_id); ShenandoahTerminatorTerminator tt(_heap); @@ -811,7 +807,6 @@ private: template inline void do_oop_work(T* p) { - ShenandoahEvacOOMScope evac_scope; _traversal_gc->process_oop(p, _thread, _queue, _mark_context); } @@ -834,7 +829,6 @@ private: template inline void do_oop_work(T* p) { - ShenandoahEvacOOMScope evac_scope; _traversal_gc->process_oop(p, _thread, _queue, _mark_context); } @@ -861,7 +855,6 @@ public: assert(worker_id == 0, "The code below is single-threaded, only one worker is expected"); ShenandoahParallelWorkerSession worker_session(worker_id); ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); - ShenandoahEvacOOMScope oom_evac_scope; ShenandoahHeap* sh = ShenandoahHeap::heap(); @@ -968,7 +961,6 @@ public: assert(sh->process_references(), "why else would we be here?"); shenandoah_assert_rp_isalive_installed(); - ShenandoahEvacOOMScope evac_scope; traversal_gc->main_loop(_worker_id, _terminator, false); if (_reset_terminator) { @@ -1010,7 +1002,6 @@ public: } void work(uint worker_id) { - ShenandoahEvacOOMScope oom_evac_scope; assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); ShenandoahHeap* heap = ShenandoahHeap::heap(); ShenandoahTraversalDrainMarkingStackClosure complete_gc(worker_id, _terminator); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp index d1506194fa5..86c36238ddf 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp @@ -51,6 +51,7 @@ void ShenandoahTraversalGC::process_oop(T* p, Thread* thread, ShenandoahObjToSca } else if (_heap->in_collection_set(obj)) { oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (obj == forw) { + ShenandoahEvacOOMScope evac_scope; forw = _heap->evacuate_object(obj, thread); } shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc()); From 7ed4930a8ef66e9c82523d83f88210b4bf9d780b Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 8 Jan 2020 13:25:03 -0800 Subject: [PATCH 10/54] 8236098: AlgorithmConstraints:permits method not throwing IAEx when primitives are empty Reviewed-by: xuelei --- .../classes/sun/security/ssl/ServerHello.java | 10 +++++++--- .../util/DisabledAlgorithmConstraints.java | 13 +++++++++++-- .../security/util/LegacyAlgorithmConstraints.java | 14 +++++++++++++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ssl/ServerHello.java b/src/java.base/share/classes/sun/security/ssl/ServerHello.java index 0cea8de56b7..62bdfee1950 100644 --- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java +++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,11 @@ package sun.security.ssl; import java.io.IOException; import java.nio.ByteBuffer; import java.security.AlgorithmConstraints; +import java.security.CryptoPrimitive; import java.security.GeneralSecurityException; import java.text.MessageFormat; import java.util.Arrays; +import java.util.EnumSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -434,7 +436,7 @@ final class ServerHello { continue; } if (!ServerHandshakeContext.legacyAlgorithmConstraints.permits( - null, cs.name, null)) { + EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), cs.name, null)) { legacySuites.add(cs); continue; } @@ -723,7 +725,9 @@ final class ServerHello { } if ((legacySuite == null) && - !legacyConstraints.permits(null, cs.name, null)) { + !legacyConstraints.permits( + EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), + cs.name, null)) { legacySuite = cs; continue; } diff --git a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java index 066852a5b3f..bca45afbf9c 100644 --- a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java +++ b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,6 +128,11 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { @Override public final boolean permits(Set primitives, String algorithm, AlgorithmParameters parameters) { + if (primitives == null || primitives.isEmpty()) { + throw new IllegalArgumentException("The primitives cannot be null" + + " or empty."); + } + if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) { return false; } @@ -216,7 +221,11 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { private boolean checkConstraints(Set primitives, String algorithm, Key key, AlgorithmParameters parameters) { - // check the key parameter, it cannot be null. + if (primitives == null || primitives.isEmpty()) { + throw new IllegalArgumentException("The primitives cannot be null" + + " or empty."); + } + if (key == null) { throw new IllegalArgumentException("The key cannot be null"); } diff --git a/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java b/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java index e4e5cedc105..1f0c17ccf0b 100644 --- a/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java +++ b/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,17 +51,29 @@ public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints { @Override public final boolean permits(Set primitives, String algorithm, AlgorithmParameters parameters) { + if (primitives == null || primitives.isEmpty()) { + throw new IllegalArgumentException("The primitives cannot be null" + + " or empty."); + } return checkAlgorithm(legacyAlgorithms, algorithm, decomposer); } @Override public final boolean permits(Set primitives, Key key) { + if (primitives == null || primitives.isEmpty()) { + throw new IllegalArgumentException("The primitives cannot be null" + + " or empty."); + } return true; } @Override public final boolean permits(Set primitives, String algorithm, Key key, AlgorithmParameters parameters) { + if (primitives == null || primitives.isEmpty()) { + throw new IllegalArgumentException("The primitives cannot be null" + + " or empty."); + } return checkAlgorithm(legacyAlgorithms, algorithm, decomposer); } From 0239771501b508aa7b8430a2df93909fd18d45f0 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 8 Jan 2020 22:44:34 +0100 Subject: [PATCH 11/54] 8236264: Remove jdk.jfr.Recording::setFlushInterval and jdk.jfr.Recording::getFlushInterval Reviewed-by: rehn, mseledtsov --- .../share/classes/jdk/jfr/Recording.java | 6 +- .../jdk/jfr/consumer/RecordingStream.java | 17 +--- .../jdk/jfr/internal/dcmd/DCmdStart.java | 6 +- .../recordingstream/TestSetEndTime.java | 3 +- .../recordingstream/TestSetFlushInterval.java | 62 ------------- .../security/TestStreamingRemote.java | 3 +- .../streaming/TestInProcessMigration.java | 3 +- .../recording/time/TestSetFlushInterval.java | 86 ------------------- .../jfr/startupargs/TestFlushInterval.java | 13 ++- 9 files changed, 20 insertions(+), 179 deletions(-) delete mode 100644 test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetFlushInterval.java delete mode 100644 test/jdk/jdk/jfr/api/recording/time/TestSetFlushInterval.java diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java index ab9c69dfeae..2728b956b5c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -424,7 +424,7 @@ public final class Recording implements Closeable { * * @since 14 */ - public void setFlushInterval(Duration interval) { + /*package private*/ void setFlushInterval(Duration interval) { Objects.nonNull(interval); if (interval.isNegative()) { throw new IllegalArgumentException("Stream interval can't be negative"); @@ -439,7 +439,7 @@ public final class Recording implements Closeable { * * @since 14 */ - public Duration getFlushInterval() { + /*package private*/ Duration getFlushInterval() { return internal.getFlushInterval(); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java index 70d13baf98c..054770a8dcb 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,6 @@ public final class RecordingStream implements AutoCloseable, EventStream { Utils.checkAccessFlightRecorder(); AccessControlContext acc = AccessController.getContext(); this.recording = new Recording(); - this.recording.setFlushInterval(Duration.ofMillis(1000)); try { PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); this.directoryStream = new EventDirectoryStream(acc, null, SecuritySupport.PRIVILIGED, pr); @@ -267,20 +266,6 @@ public final class RecordingStream implements AutoCloseable, EventStream { recording.setMaxSize(maxSize); } - /** - * Determines how often events are made available for streaming. - * - * @param interval the interval at which events are made available to the - * stream, no {@code null} - * - * @throws IllegalArgumentException if {@code interval} is negative - * - * @throws IllegalStateException if the stream is closed - */ - public void setFlushInterval(Duration interval) { - recording.setFlushInterval(interval); - } - @Override public void setReuse(boolean reuse) { directoryStream.setReuse(reuse); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java index 5237d85d761..d46e682b752 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; import jdk.jfr.internal.OldObjectSample; +import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.Type; @@ -186,7 +187,8 @@ final class DCmdStart extends AbstractDCmd { } if (flush != null) { - recording.setFlushInterval(Duration.ofNanos(flush)); + PlatformRecording p = PrivateAccess.getInstance().getPlatformRecording(recording); + p.setFlushInterval(Duration.ofNanos(flush)); } if (maxSize != null) { diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java index 700c895f42d..2d70233a2af 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,6 @@ public final class TestSetEndTime { CountDownLatch closed = new CountDownLatch(1); AtomicInteger count = new AtomicInteger(); try (RecordingStream rs = new RecordingStream()) { - rs.setFlushInterval(Duration.ofSeconds(1)); rs.onEvent(e -> { count.incrementAndGet(); }); diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetFlushInterval.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetFlushInterval.java deleted file mode 100644 index 0891b37cb42..00000000000 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetFlushInterval.java +++ /dev/null @@ -1,62 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.api.consumer.recordingstream; - -import java.time.Duration; - -import jdk.jfr.consumer.RecordingStream; -import jdk.test.lib.jfr.EventNames; - -/** - * @test - * @summary Tests RecordingStream::setFlushInterval - * @key jfr - * @requires vm.hasJFR - * @library /test/lib - * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetFlushInterval - */ -public class TestSetFlushInterval { - - public static void main(String... args) throws Exception { - Duration expectedDuration = Duration.ofMillis(1001); - try (RecordingStream r = new RecordingStream()) { - r.setFlushInterval(expectedDuration); - r.enable(EventNames.ActiveRecording); - r.onEvent(e -> { - System.out.println(e); - Duration duration = e.getDuration("flushInterval"); - if (expectedDuration.equals(duration)) { - System.out.println("Closing recording"); - r.close(); - return; - } - System.out.println("Flush interval not set, was " + duration + - ", but expected " + expectedDuration); - }); - r.start(); - } - } -} diff --git a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java index ef2612f4386..370cb0a9ceb 100644 --- a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java +++ b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,6 @@ public class TestStreamingRemote { public static void main(String... args) throws Exception { try (Recording r = new Recording()) { - r.setFlushInterval(Duration.ofSeconds(1)); r.start(); String repository = System.getProperty("jdk.jfr.repository"); Path policy = createPolicyFile(repository); diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java index eb701deb45d..61f54815c04 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,6 @@ public class TestInProcessMigration { System.out.println("Started es.startAsync()"); try (Recording r = new Recording()) { - r.setFlushInterval(Duration.ofSeconds(1)); r.start(); // Chunk in default repository MigrationEvent e1 = new MigrationEvent(); diff --git a/test/jdk/jdk/jfr/api/recording/time/TestSetFlushInterval.java b/test/jdk/jdk/jfr/api/recording/time/TestSetFlushInterval.java deleted file mode 100644 index 3b73533dcd6..00000000000 --- a/test/jdk/jdk/jfr/api/recording/time/TestSetFlushInterval.java +++ /dev/null @@ -1,86 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.api.recording.time; - -import java.time.Duration; -import java.util.concurrent.CountDownLatch; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.EventStream; -import jdk.test.lib.Asserts; - -/** - * @test - * @key jfr - * @summary Test Recording::SetFlushInterval(...) and - * Recording::getFlushInterval() - * @requires vm.hasJFR - * @library /test/lib - * @run main/othervm jdk.jfr.api.recording.time.TestSetFlushInterval - */ - -public class TestSetFlushInterval { - - public static void main(String[] args) throws Throwable { - testSetGet(); - testSetNull(); - testFlush(); - } - - static void testFlush() throws Exception { - CountDownLatch flush = new CountDownLatch(1); - try (EventStream es = EventStream.openRepository()) { - es.onFlush(() -> { - flush.countDown(); - }); - es.startAsync(); - try (Recording r = new Recording()) { - r.setFlushInterval(Duration.ofSeconds(1)); - r.start(); - flush.await(); - } - } - } - - static void testSetNull() { - try (Recording r = new Recording()) { - r.setFlushInterval(null); - Asserts.fail("Expected NullPointerException"); - } catch (NullPointerException npe) { - // as expected - } - } - - static void testSetGet() { - try (Recording r = new Recording()) { - Duration a = Duration.ofNanos(21378461289374646L); - r.setFlushInterval(a); - Duration b = r.getFlushInterval(); - Asserts.assertEQ(a, b); - } - } - -} diff --git a/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java b/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java index 882af097735..88c50be949a 100644 --- a/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java +++ b/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import java.time.Duration; import jdk.jfr.FlightRecorder; import jdk.jfr.Recording; +import jdk.jfr.internal.PlatformRecording; +import jdk.jfr.internal.PrivateAccess; /** * @test @@ -36,14 +38,17 @@ import jdk.jfr.Recording; * @key jfr * @requires vm.hasJFR * @library /test/lib /test/jdk - * @run main/othervm -XX:StartFlightRecording=flush-interval=1s jdk.jfr.startupargs.TestFlushInterval + * @modules jdk.jfr/jdk.jfr.internal + * @run main/othervm -XX:StartFlightRecording=flush-interval=2s jdk.jfr.startupargs.TestFlushInterval */ public class TestFlushInterval { public static void main(String[] args) throws Exception { for (Recording r : FlightRecorder.getFlightRecorder().getRecordings()) { - Duration d = r.getFlushInterval(); - if (d.equals(Duration.ofSeconds(1))) { + PrivateAccess p = PrivateAccess.getInstance(); + PlatformRecording pr = p.getPlatformRecording(r); + Duration d = pr.getFlushInterval(); + if (d.equals(Duration.ofSeconds(2))) { return; //OK } else { throw new Exception("Unexpected flush-interval " + d); From e5b0568e1c7b56a5ba7f3edecf826a463a70144a Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Wed, 8 Jan 2020 23:12:45 +0000 Subject: [PATCH 12/54] 8236769: Clarify javadoc of memory access API Reviewed-by: chegar --- .../jdk/incubator/foreign/MemoryAddress.java | 8 ++- .../jdk/incubator/foreign/MemoryLayout.java | 21 ++++++-- test/jdk/java/foreign/TestTypeAccess.java | 54 +++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 test/jdk/java/foreign/TestTypeAccess.java diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java index 73c1c6a6957..111ed671673 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java @@ -74,7 +74,13 @@ public interface MemoryAddress { /** * Compares the specified object with this address for equality. Returns {@code true} if and only if the specified - * object is also a address, and it is equal to this address. + * object is also an address, and it refers to the same memory location as this address. + * + * @apiNote two addresses might be considered equal despite their associated segments differ. This + * can happen, for instance, if the segment associated with one address is a slice + * (see {@link MemorySegment#asSlice(long, long)}) of the segment associated with the other address. Moreover, + * two addresses might be considered equals despite differences in the temporal bounds associated with their + * corresponding segments (this is possible, for example, as a result of calls to {@link MemorySegment#acquire()}). * * @param that the object to be compared for equality with this address. * @return {@code true} if the specified object is equal to this address. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java index bbb44e07594..45f02ba5228 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java @@ -55,14 +55,14 @@ import java.util.OptionalLong; *

* Non-platform classes should not implement {@linkplain MemoryLayout} directly. * - *

Size, alignment and byte order

+ *

Size, alignment and byte order

* * All layouts have a size; layout size for value and padding layouts is always explicitly denoted; this means that a layout description * always has the same size in bits, regardless of the platform in which it is used. For derived layouts, the size is computed * as follows: *
    *
  • for a finite sequence layout S whose element layout is E and size is L, - * the size of S is that of E, multiplied by L
  • + * the size of S is that of E, multiplied by L *
  • the size of an unbounded sequence layout is unknown
  • *
  • for a group layout G with member layouts M1, M2, ... Mn whose sizes are * S1, S2, ... Sn, respectively, the size of G is either S1 + S2 + ... + Sn or @@ -180,6 +180,9 @@ public interface MemoryLayout extends Constable { *
  • {@code A=512} is the most strict alignment required by the x86/SV ABI (for AVX-512 data).
  • *
* + * If no explicit alignment constraint was set on this layout (see {@link #withBitAlignment(long)}), + * then this method returns the natural alignment constraint (in bits) associated with this layout. + * * @return the layout alignment constraint, in bits. */ long bitAlignment(); @@ -195,6 +198,9 @@ public interface MemoryLayout extends Constable { *
  • {@code A=64} is the most strict alignment required by the x86/SV ABI (for AVX-512 data).
  • * * + * If no explicit alignment constraint was set on this layout (see {@link #withBitAlignment(long)}), + * then this method returns the natural alignment constraint (in bytes) associated with this layout. + * * @return the layout alignment constraint, in bytes. * @throws UnsupportedOperationException if {@code bitAlignment()} is not a multiple of 8. */ @@ -352,7 +358,16 @@ E * (S + I * F) /** * Compares the specified object with this layout for equality. Returns {@code true} if and only if the specified - * object is also a layout, and it is equal to this layout. + * object is also a layout, and it is equal to this layout. Two layouts are considered equal if they are of + * the same kind, have the same size, name and alignment constraints. Furthermore, depending on the layout kind, additional + * conditions must be satisfied: + *
      + *
    • two value layouts are considered equal if they have the same endianness (see {@link ValueLayout#order()})
    • + *
    • two sequence layouts are considered equal if they have the same element count (see {@link SequenceLayout#elementCount()}), and + * if their element layouts (see {@link SequenceLayout#elementLayout()}) are also equal
    • + *
    • two group layouts are considered equal if they are of the same kind (see {@link GroupLayout#isStruct()}, + * {@link GroupLayout#isUnion()}) and if their member layouts (see {@link GroupLayout#memberLayouts()}) are also equal
    • + *
    * * @param that the object to be compared for equality with this layout. * @return {@code true} if the specified object is equal to this layout. diff --git a/test/jdk/java/foreign/TestTypeAccess.java b/test/jdk/java/foreign/TestTypeAccess.java new file mode 100644 index 00000000000..b555f0987ac --- /dev/null +++ b/test/jdk/java/foreign/TestTypeAccess.java @@ -0,0 +1,54 @@ +/* + * 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 + * @run testng TestTypeAccess + */ + +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.MemoryLayouts; +import org.testng.annotations.*; + +import java.lang.invoke.VarHandle; +import java.lang.invoke.WrongMethodTypeException; + +public class TestTypeAccess { + + static final VarHandle INT_HANDLE = MemoryLayouts.JAVA_INT.varHandle(int.class); + + @Test(expectedExceptions=ClassCastException.class) + public void testMemoryAddressCoordinateAsString() { + try (MemorySegment s = MemorySegment.allocateNative(8)) { + int v = (int)INT_HANDLE.get("string"); + } + } + + @Test(expectedExceptions=WrongMethodTypeException.class) + public void testMemoryCoordinatePrimitive() { + try (MemorySegment s = MemorySegment.allocateNative(8)) { + int v = (int)INT_HANDLE.get(1); + } + } +} From 0a4d6f6925e6bde2f5474b0ffd29fb686fe5be92 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 9 Jan 2020 02:31:10 +0100 Subject: [PATCH 13/54] Added tag jdk-14+31 for changeset d54ce919da90 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 186dfdb09c2..b6ddc23da28 100644 --- a/.hgtags +++ b/.hgtags @@ -603,3 +603,4 @@ c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21 2069b4bfd23b56b6fc659fba8b75aaaa23debbe0 jdk-14+28 563fa900fa17c290ae516c7a3a69e8c069dde304 jdk-14+29 d54ce919da90dab361995bb4d87be9851f00537a jdk-14+30 +d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31 From cd74b2a23d1c6560d6bcd741fd70da840e4a81bc Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 9 Jan 2020 02:34:23 +0100 Subject: [PATCH 14/54] Added tag jdk-14+31 for changeset decd3d2953b6 --- .hgtags | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.hgtags b/.hgtags index b6ddc23da28..f90e093b502 100644 --- a/.hgtags +++ b/.hgtags @@ -604,3 +604,5 @@ c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21 563fa900fa17c290ae516c7a3a69e8c069dde304 jdk-14+29 d54ce919da90dab361995bb4d87be9851f00537a jdk-14+30 d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31 +d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31 +decd3d2953b640f1043ee76953ff89238bff92e8 jdk-14+31 From 6e467d4d02c1211f999713f3b8055339820bad03 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 9 Jan 2020 17:25:05 +0530 Subject: [PATCH 15/54] 8225561: jlink --help doesn't state that ALL-MODULE-PATH is accepted for --add-modules Reviewed-by: alanb --- .../share/classes/jdk/tools/jlink/resources/jlink.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties index 34d4d1bf245..fec33911612 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties @@ -46,7 +46,8 @@ main.opt.module-path=\ \ if it exists. main.opt.add-modules=\ -\ --add-modules [,...] Root modules to resolve +\ --add-modules [,...] Root modules to resolve in addition to the\n\ +\ initial modules. can also be ALL-MODULE-PATH. main.opt.limit-modules=\ \ --limit-modules [,...] Limit the universe of observable\n\ From b1df8adbf883b4e25722015061800b9edadd7e4e Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Thu, 9 Jan 2020 12:04:22 +0000 Subject: [PATCH 16/54] 8236779: static field in implementation class erroneously leaking in memory access javadoc Reviewed-by: chegar --- .../share/classes/jdk/incubator/foreign/AbstractLayout.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java index 94ae1a462fc..42a5b1312bb 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java @@ -140,7 +140,7 @@ abstract class AbstractLayout implements MemoryLayout { /*** Helper constants for implementing Layout::describeConstable ***/ - public static final DirectMethodHandleDesc BSM_GET_STATIC_FINAL + static final DirectMethodHandleDesc BSM_GET_STATIC_FINAL = ConstantDescs.ofConstantBootstrap(ConstantDescs.CD_ConstantBootstraps, "getStaticFinal", ConstantDescs.CD_Object, ConstantDescs.CD_Class); From 863f74161128dc6e4797078815a0408a02ccbd12 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 9 Jan 2020 16:14:14 +0100 Subject: [PATCH 17/54] 8236140: assert(!VerifyHashTableKeys || _hash_lock == 0) failed: remove node from hash table before modifying it Add missing rehashing for modified node in InitializeNode::complete_stores(). Reviewed-by: neliasso, thartmann --- src/hotspot/share/opto/memnode.cpp | 4 +- src/hotspot/share/opto/memnode.hpp | 2 +- .../macronodes/TestCompleteVolatileStore.java | 79 +++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/macronodes/TestCompleteVolatileStore.java diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index b1cec387a74..c7b44a1b22d 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -4170,7 +4170,7 @@ intptr_t InitializeNode::find_next_fullword_store(uint start, PhaseGVN* phase) { Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, intptr_t header_size, Node* size_in_bytes, - PhaseGVN* phase) { + PhaseIterGVN* phase) { assert(!is_complete(), "not already complete"); assert(stores_are_sane(phase), ""); assert(allocation() != NULL, "must be present"); @@ -4262,7 +4262,7 @@ Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, } // Collect the store and move on: - st->set_req(MemNode::Memory, inits); + phase->replace_input_of(st, MemNode::Memory, inits); inits = st; // put it on the linearized chain set_req(i, zmem); // unhook from previous position diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp index 7f145853696..ab07e5b920f 100644 --- a/src/hotspot/share/opto/memnode.hpp +++ b/src/hotspot/share/opto/memnode.hpp @@ -1402,7 +1402,7 @@ public: // Called when the associated AllocateNode is expanded into CFG. Node* complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, intptr_t header_size, Node* size_in_bytes, - PhaseGVN* phase); + PhaseIterGVN* phase); private: void remove_extra_zeroes(); diff --git a/test/hotspot/jtreg/compiler/macronodes/TestCompleteVolatileStore.java b/test/hotspot/jtreg/compiler/macronodes/TestCompleteVolatileStore.java new file mode 100644 index 00000000000..74b24b662e7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/macronodes/TestCompleteVolatileStore.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8236140 + * @requires vm.gc.Serial + * @summary Tests proper rehashing of a captured volatile field StoreL node when completing it. + * @run main/othervm -Xbatch -XX:+UseSerialGC -XX:CompileCommand=compileonly,compiler.macronodes.TestCompleteVolatileStore::test + * compiler.macronodes.TestCompleteVolatileStore + */ + +package compiler.macronodes; + +public class TestCompleteVolatileStore { + int i1 = 4; + + public void test() { + /* + * The store to the volatile field 'l1' (StoreL) of 'a' is captured in the Initialize node of 'a' + * (i.e. additional input to it) and completed in InitializeNode::complete_stores. + * Since 'l1' is volatile, the hash of the StoreL is non-zero triggering the hash assertion failure. + */ + A a = new A(); + + // Make sure that the CheckCastPP node of 'a' is used in the input chain of the Intialize node of 'b' + B b = new B(a); + + // Make sure 'b' is non-scalar-replacable to avoid eliminating all allocations + B[] arr = new B[i1]; + arr[i1-3] = b; + } + + public static void main(String[] strArr) { + TestCompleteVolatileStore _instance = new TestCompleteVolatileStore(); + for (int i = 0; i < 10_000; i++ ) { + _instance.test(); + } + } +} + +class A { + // Needs to be volatile to have a non-zero hash for the StoreL node. + volatile long l1; + + A() { + // StoreL gets captured and is later processed in InitializeNode::complete_stores while expanding the allocation node. + this.l1 = 256; + } +} + +class B { + A a; + + B(A a) { + this.a = a; + } +} + From 7cd4d9ac6a135c2fb336a6d288530ac0e00bf566 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 9 Jan 2020 08:31:29 -0800 Subject: [PATCH 18/54] 8236582: (fc) FileChannel.map fails with InternalError when security manager enabled Reviewed-by: alanb --- .../jdk/internal/misc/ExtendedMapMode.java | 8 +++- .../FileChannel/MapWithSecurityManager.java | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java diff --git a/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java b/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java index bad9192e0b0..f6304b7b20e 100644 --- a/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java +++ b/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java @@ -27,8 +27,11 @@ package jdk.internal.misc; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; import java.nio.channels.FileChannel.MapMode; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; /** * JDK-specific map modes implemented in java.base. @@ -36,10 +39,11 @@ import java.nio.channels.FileChannel.MapMode; public class ExtendedMapMode { static final MethodHandle MAP_MODE_CONSTRUCTOR; - static { try { - var lookup = MethodHandles.privateLookupIn(MapMode.class, MethodHandles.lookup()); + PrivilegedExceptionAction pae = () -> + MethodHandles.privateLookupIn(MapMode.class, MethodHandles.lookup()); + Lookup lookup = AccessController.doPrivileged(pae); var methodType = MethodType.methodType(void.class, String.class); MAP_MODE_CONSTRUCTOR = lookup.findConstructor(MapMode.class, methodType); } catch (Exception e) { diff --git a/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java b/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java new file mode 100644 index 00000000000..a7990140307 --- /dev/null +++ b/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8236582 + * @summary Tests the map method when running with a security manager + */ + +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.Path; + +public class MapWithSecurityManager { + public static void main(String[] args) throws IOException { + Path tempFile = Files.createTempFile("test", "test"); + try (FileChannel ch = FileChannel.open(tempFile)) { + System.setSecurityManager(new SecurityManager()); + ch.map(FileChannel.MapMode.READ_ONLY, 0, 0); + } + } +} From d8e3d8af7bea456ebc8f491595883ad54efd4b70 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 9 Jan 2020 08:31:41 -0800 Subject: [PATCH 19/54] 8236804: java/nio/channels/FileChannel/MapWithSecurityManager.java should be run in othervm mode Reviewed-by: chegar, lancea --- .../java/nio/channels/FileChannel/MapWithSecurityManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java b/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java index a7990140307..37626cf6797 100644 --- a/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java +++ b/test/jdk/java/nio/channels/FileChannel/MapWithSecurityManager.java @@ -24,6 +24,7 @@ /* @test * @bug 8236582 * @summary Tests the map method when running with a security manager + * @run main/othervm MapWithSecurityManager */ import java.io.IOException; From d94f8c91c9f5e72732611589eb39df93d289fde1 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 10 Jan 2020 01:36:48 +0000 Subject: [PATCH 20/54] 8229847: AttachProvider javadoc page needs an update Replace Sun references with Oracle references in AttachProvider javadoc Reviewed-by: amenkov, dholmes --- .../classes/com/sun/tools/attach/spi/AttachProvider.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java b/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java index 0ca0539f4ef..ac99b40d587 100644 --- a/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java +++ b/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java @@ -46,17 +46,18 @@ import java.util.ServiceLoader; *

    An attach provider implementation is typically tied to a Java virtual * machine implementation, version, or even mode of operation. That is, a specific * provider implementation will typically only be capable of attaching to - * a specific Java virtual machine implementation or version. For example, Sun's + * a specific Java virtual machine implementation or version. For example, Oracle's * JDK implementation ships with provider implementations that can only attach to - * Sun's HotSpot virtual machine. In general, if an environment + * Oracle's HotSpot virtual machine. In general, if an environment * consists of Java virtual machines of different versions and from different * vendors then there will be an attach provider implementation for each * family of implementations or versions. * *

    An attach provider is identified by its {@link #name name} and * {@link #type type}. The name is typically, but not required to - * be, a name that corresponds to the VM vendor. The Sun JDK implementation, - * for example, ships with attach providers that use the name "sun". The + * be, a name that corresponds to the VM vendor. The Oracle JDK implementation, + * for example, ships with attach providers that use the package name "sun" + * (for historical reasons). The * type typically corresponds to the attach mechanism. For example, an * implementation that uses the Doors inter-process communication mechanism * might use the type "doors". The purpose of the name and type is to From efc96d1c076a6dfc804f8f539c8c4065cd2e08ae Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Fri, 10 Jan 2020 02:52:25 +0000 Subject: [PATCH 21/54] 8236897: Fix the copyright header for pkcs11gcm2.h Add the "Classpath" exception to existing header Reviewed-by: weijun --- .../share/native/libj2pkcs11/pkcs11gcm2.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h index 447a95973d1..6e5cbfa10eb 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h @@ -1,10 +1,12 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or From b81bfcbff117d197e71db4a4f044a0e733dad531 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Fri, 10 Jan 2020 07:21:32 -0500 Subject: [PATCH 22/54] 8236902: Shenandoah: Missing string dedup roots in all root scanner Reviewed-by: rkennke --- .../share/gc/shenandoah/shenandoahRootProcessor.hpp | 3 ++- .../gc/shenandoah/shenandoahRootProcessor.inline.hpp | 5 ++++- .../share/gc/shenandoah/shenandoahTraversalGC.cpp | 5 +---- .../jtreg/gc/shenandoah/jvmti/TestHeapDump.java | 11 ++++++++++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp index 5702f33dce1..a56d1230d1f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2015, 2020, Red Hat, Inc. All rights reserved. * * 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 @@ -226,6 +226,7 @@ private: ShenandoahThreadRoots _thread_roots; ShenandoahCodeCacheRoots _code_roots; ShenandoahVMRoots _vm_roots; + ShenandoahStringDedupRoots _dedup_roots; ShenandoahClassLoaderDataRoots _cld_roots; public: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp index 67669c16194..5be19fd5cdb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved. * * 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 @@ -250,6 +250,9 @@ void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDC if (code != NULL && !ShenandoahConcurrentScanCodeRoots) { _code_roots.code_blobs_do(code, worker_id); } + + AlwaysTrueClosure always_true; + _dedup_roots.oops_do(&always_true, oops, worker_id); } template diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp index 5fd46980d53..9ebe130e230 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved. * * 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 @@ -193,9 +193,6 @@ public: } else { _rp->roots_do(worker_id, &roots_cl, &cld_cl, &code_cl); } - - AlwaysTrueClosure is_alive; - _dedup_roots.oops_do(&is_alive, &roots_cl, worker_id); } } }; diff --git a/test/hotspot/jtreg/gc/shenandoah/jvmti/TestHeapDump.java b/test/hotspot/jtreg/gc/shenandoah/jvmti/TestHeapDump.java index fed358d24ad..35f861c952c 100644 --- a/test/hotspot/jtreg/gc/shenandoah/jvmti/TestHeapDump.java +++ b/test/hotspot/jtreg/gc/shenandoah/jvmti/TestHeapDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2020, Red Hat, Inc. All rights reserved. * * 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 @@ -40,6 +40,15 @@ * @run main/othervm/native/timeout=300 -agentlib:TestHeapDump -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx128m -XX:ShenandoahGCHeuristics=aggressive -XX:-UseCompressedOops TestHeapDump */ +/** + * @test TestHeapDump + * @summary Tests JVMTI heap dumps + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled + * @compile TestHeapDump.java + * @run main/othervm/native/timeout=300 -agentlib:TestHeapDump -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx128m -XX:ShenandoahGCHeuristics=aggressive -XX:+UseStringDeduplication TestHeapDump + */ + import java.lang.ref.Reference; public class TestHeapDump { From d6a2a079d16feead9ec5b897d098f659271dbc64 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 8 Jan 2020 14:22:30 +0100 Subject: [PATCH 23/54] 8236772: Fix build for windows 32-bit after 8212160 and 8234331 Reviewed-by: clanger --- src/hotspot/share/utilities/count_leading_zeros.hpp | 2 +- .../jvmti/CompiledMethodLoad/libCompiledZombie.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/utilities/count_leading_zeros.hpp b/src/hotspot/share/utilities/count_leading_zeros.hpp index 1a4b2540ad5..612a6efbc3a 100644 --- a/src/hotspot/share/utilities/count_leading_zeros.hpp +++ b/src/hotspot/share/utilities/count_leading_zeros.hpp @@ -108,8 +108,8 @@ template struct CountLeadingZerosImpl { template struct CountLeadingZerosImpl { static unsigned doit(T v) { - unsigned long index; #ifdef _LP64 + unsigned long index; _BitScanReverse64(&index, v); return 63u - index; #else diff --git a/test/hotspot/jtreg/serviceability/jvmti/CompiledMethodLoad/libCompiledZombie.cpp b/test/hotspot/jtreg/serviceability/jvmti/CompiledMethodLoad/libCompiledZombie.cpp index c9c66117295..fbff3c847f1 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/CompiledMethodLoad/libCompiledZombie.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/CompiledMethodLoad/libCompiledZombie.cpp @@ -67,7 +67,8 @@ void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { jvmti->RunAgentThread(agent_thread, GenerateEventsThread, NULL, JVMTI_THREAD_NORM_PRIORITY); } -jint Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { jvmtiEnv* jvmti; vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0); From 89f7e1925e42d1f1c9a8b65bd0a8c8a55f5038ba Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Fri, 10 Jan 2020 16:30:02 +0100 Subject: [PATCH 24/54] 8236555: [s390] Fix VerifyOops Reviewed-by: goetz, lucy --- src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp | 4 +- src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp | 20 ++--- .../cpu/s390/c1_MacroAssembler_s390.cpp | 17 ++-- src/hotspot/cpu/s390/c1_Runtime1_s390.cpp | 6 +- .../s390/gc/g1/g1BarrierSetAssembler_s390.cpp | 4 +- .../gc/shared/barrierSetAssembler_s390.cpp | 2 +- src/hotspot/cpu/s390/interp_masm_s390.cpp | 4 +- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 88 ++++++++++++++++--- src/hotspot/cpu/s390/macroAssembler_s390.hpp | 7 ++ src/hotspot/cpu/s390/methodHandles_s390.cpp | 12 +-- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 8 +- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 16 ++++ 12 files changed, 139 insertions(+), 49 deletions(-) diff --git a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp index 42815aadebb..7fe43487325 100644 --- a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp +++ b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp @@ -294,7 +294,7 @@ void PatchingStub::align_patch_site(MacroAssembler* masm) { void PatchingStub::emit_code(LIR_Assembler* ce) { // Copy original code here. assert(NativeGeneralJump::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF, - "not enough room for call"); + "not enough room for call, need %d", _bytes_to_copy); NearLabel call_patch; @@ -331,7 +331,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { } #endif } else { - // Make a copy the code which is going to be patched. + // Make a copy of the code which is going to be patched. for (int i = 0; i < _bytes_to_copy; i++) { address ptr = (address)(_pc_start + i); int a_byte = (*ptr) & 0xFF; diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index 3c6e7e460ad..262474bf621 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -897,7 +897,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P bool needs_patching = (patch_code != lir_patch_none); if (addr->base()->type() == T_OBJECT) { - __ verify_oop(src); + __ verify_oop(src, FILE_AND_LINE); } PatchingStub* patch = NULL; @@ -972,7 +972,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P } else { __ z_lg(dest->as_register(), disp_value, disp_reg, src); } - __ verify_oop(dest->as_register()); + __ verify_oop(dest->as_register(), FILE_AND_LINE); break; } case T_FLOAT: @@ -1006,7 +1006,7 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (dest->is_single_cpu()) { if (is_reference_type(type)) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); - __ verify_oop(dest->as_register()); + __ verify_oop(dest->as_register(), FILE_AND_LINE); } else if (type == T_METADATA || type == T_ADDRESS) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); } else { @@ -1033,7 +1033,7 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool po if (src->is_single_cpu()) { const Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); if (is_reference_type(type)) { - __ verify_oop(src->as_register()); + __ verify_oop(src->as_register(), FILE_AND_LINE); __ reg2mem_opt(src->as_register(), dst, true); } else if (type == T_METADATA || type == T_ADDRESS) { __ reg2mem_opt(src->as_register(), dst, true); @@ -1079,7 +1079,7 @@ void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) { ShouldNotReachHere(); } if (is_reference_type(to_reg->type())) { - __ verify_oop(to_reg->as_register()); + __ verify_oop(to_reg->as_register(), FILE_AND_LINE); } } @@ -1095,7 +1095,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, bool needs_patching = (patch_code != lir_patch_none); if (addr->base()->is_oop_register()) { - __ verify_oop(dest); + __ verify_oop(dest, FILE_AND_LINE); } PatchingStub* patch = NULL; @@ -1130,7 +1130,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, assert(disp_reg != Z_R0 || Immediate::is_simm20(disp_value), "should have set this up"); if (is_reference_type(type)) { - __ verify_oop(from->as_register()); + __ verify_oop(from->as_register(), FILE_AND_LINE); } bool short_disp = Immediate::is_uimm12(disp_value); @@ -2412,7 +2412,7 @@ void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { op->klass()->as_register(), *op->stub()->entry()); __ bind(*op->stub()->continuation()); - __ verify_oop(op->obj()->as_register()); + __ verify_oop(op->obj()->as_register(), FILE_AND_LINE); } void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { @@ -2548,7 +2548,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } assert(obj != k_RInfo, "must be different"); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); // Get object class. // Not a safepoint as obj null check happens earlier. @@ -3009,7 +3009,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { assert(do_null || do_update, "why are we here?"); assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); if (do_null || tmp1 != obj DEBUG_ONLY(|| true)) { __ z_ltgr(tmp1, obj); diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp index b2680769dcf..a357f79ffcc 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp @@ -40,7 +40,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { Label ic_miss, ic_hit; - verify_oop(receiver); + verify_oop(receiver, FILE_AND_LINE); int klass_offset = oopDesc::klass_offset_in_bytes(); if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) { @@ -83,7 +83,7 @@ void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hd assert_different_registers(hdr, obj, disp_hdr); NearLabel done; - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); // Load object header. z_lg(hdr, Address(obj, hdr_offset)); @@ -158,7 +158,7 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_ // Load object. z_lg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); } - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); // Test if object header is pointing to the displaced header, and if so, restore // the displaced header in the object. If the object header is not pointing to // the displaced header, get the object header instead. @@ -278,7 +278,7 @@ void C1_MacroAssembler::initialize_object( // call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id))); // } - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); } void C1_MacroAssembler::allocate_array( @@ -336,16 +336,15 @@ void C1_MacroAssembler::allocate_array( // call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id))); // } - verify_oop(obj); + verify_oop(obj, FILE_AND_LINE); } #ifndef PRODUCT void C1_MacroAssembler::verify_stack_oop(int stack_offset) { - Unimplemented(); - // if (!VerifyOops) return; - // verify_oop_addr(Address(SP, stack_offset + STACK_BIAS)); + if (!VerifyOops) return; + verify_oop_addr(Address(Z_SP, stack_offset), FILE_AND_LINE); } void C1_MacroAssembler::verify_not_null_oop(Register r) { @@ -354,7 +353,7 @@ void C1_MacroAssembler::verify_not_null_oop(Register r) { compareU64_and_branch(r, (intptr_t)0, bcondNotEqual, not_null); stop("non-null oop required"); bind(not_null); - verify_oop(r); + verify_oop(r, FILE_AND_LINE); } void C1_MacroAssembler::invalidate_registers(Register preserve1, diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp index eeb934bfdaa..e7526d17c6d 100644 --- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp +++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp @@ -339,7 +339,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { oop_maps->add_gc_map(call_offset, map); restore_live_registers_except_r2(sasm); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); __ z_br(Z_R14); } break; @@ -405,7 +405,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { oop_maps->add_gc_map(call_offset, map); restore_live_registers_except_r2(sasm); - __ verify_oop(obj); + __ verify_oop(obj, FILE_AND_LINE); __ z_br(Z_R14); } break; @@ -423,7 +423,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { restore_live_registers_except_r2(sasm); // Z_R2,: new multi array - __ verify_oop(Z_R2); + __ verify_oop(Z_R2, FILE_AND_LINE); __ z_br(Z_R14); } break; diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index d0bb0c0e41c..2bdfa801053 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -400,11 +400,11 @@ void G1BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value __ z_tmll(tmp1, JNIHandles::weak_tag_mask); // Test for jweak tag. __ z_braz(Lnot_weak); - __ verify_oop(value); + __ verify_oop(value, FILE_AND_LINE); DecoratorSet decorators = IN_NATIVE | ON_PHANTOM_OOP_REF; g1_write_barrier_pre(masm, decorators, (const Address*)NULL, value, noreg, tmp1, tmp2, true); __ bind(Lnot_weak); - __ verify_oop(value); + __ verify_oop(value, FILE_AND_LINE); __ bind(Ldone); } diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp index f99100dcb6d..2fce9a4589b 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp @@ -108,7 +108,7 @@ void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, __ z_nill(value, ~JNIHandles::weak_tag_mask); __ z_lg(value, 0, value); // Resolve (untagged) jobject. - __ verify_oop(value); + __ verify_oop(value, FILE_AND_LINE); __ bind(Ldone); } diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 48af3cf0cf3..cbee39e3eae 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1664,7 +1664,7 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, Address mdo_addr, compareU64_and_branch(obj, (intptr_t)0, Assembler::bcondEqual, null_seen); } - verify_oop(obj); + MacroAssembler::verify_oop(obj, FILE_AND_LINE); load_klass(klass, obj); // Klass seen before, nothing to do (regardless of unknown bit). @@ -2073,7 +2073,7 @@ void InterpreterMacroAssembler::access_local_int(Register index, Register dst) { } void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { - if (state == atos) { MacroAssembler::verify_oop(reg); } + if (state == atos) { MacroAssembler::verify_oop(reg, FILE_AND_LINE); } } // Inline assembly for: diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 49fb3492783..e774e0a9748 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -3587,7 +3587,7 @@ void MacroAssembler::get_vm_result(Register oop_result) { z_lg(oop_result, Address(Z_thread, JavaThread::vm_result_offset())); clear_mem(Address(Z_thread, JavaThread::vm_result_offset()), sizeof(void*)); - verify_oop(oop_result); + verify_oop(oop_result, FILE_AND_LINE); } void MacroAssembler::get_vm_result_2(Register result) { @@ -6813,26 +6813,94 @@ void MacroAssembler::verify_thread() { } } +// Save and restore functions: Exclude Z_R0. +void MacroAssembler::save_volatile_regs(Register dst, int offset, bool include_fp, bool include_flags) { + z_stmg(Z_R1, Z_R5, offset, dst); offset += 5 * BytesPerWord; + if (include_fp) { + z_std(Z_F0, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F1, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F2, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F3, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F4, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F5, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F6, Address(dst, offset)); offset += BytesPerWord; + z_std(Z_F7, Address(dst, offset)); offset += BytesPerWord; + } + if (include_flags) { + Label done; + z_mvi(Address(dst, offset), 2); // encoding: equal + z_bre(done); + z_mvi(Address(dst, offset), 4); // encoding: higher + z_brh(done); + z_mvi(Address(dst, offset), 1); // encoding: lower + bind(done); + } +} +void MacroAssembler::restore_volatile_regs(Register src, int offset, bool include_fp, bool include_flags) { + z_lmg(Z_R1, Z_R5, offset, src); offset += 5 * BytesPerWord; + if (include_fp) { + z_ld(Z_F0, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F1, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F2, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F3, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F4, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F5, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F6, Address(src, offset)); offset += BytesPerWord; + z_ld(Z_F7, Address(src, offset)); offset += BytesPerWord; + } + if (include_flags) { + z_cli(Address(src, offset), 2); // see encoding above + } +} + // Plausibility check for oops. void MacroAssembler::verify_oop(Register oop, const char* msg) { if (!VerifyOops) return; BLOCK_COMMENT("verify_oop {"); - Register tmp = Z_R0; - unsigned int nbytes_save = 5*BytesPerWord; - address entry = StubRoutines::verify_oop_subroutine_entry_address(); + unsigned int nbytes_save = (5 + 8 + 1) * BytesPerWord; + address entry_addr = StubRoutines::verify_oop_subroutine_entry_address(); save_return_pc(); - push_frame_abi160(nbytes_save); - z_stmg(Z_R1, Z_R5, frame::z_abi_160_size, Z_SP); - z_lgr(Z_ARG2, oop); - load_const(Z_ARG1, (address) msg); - load_const(Z_R1, entry); + // Push frame, but preserve flags + z_lgr(Z_R0, Z_SP); + z_lay(Z_SP, -((int64_t)nbytes_save + frame::z_abi_160_size), Z_SP); + z_stg(Z_R0, _z_abi(callers_sp), Z_SP); + + save_volatile_regs(Z_SP, frame::z_abi_160_size, true, true); + + lgr_if_needed(Z_ARG2, oop); + load_const_optimized(Z_ARG1, (address)msg); + load_const_optimized(Z_R1, entry_addr); z_lg(Z_R1, 0, Z_R1); call_c(Z_R1); - z_lmg(Z_R1, Z_R5, frame::z_abi_160_size, Z_SP); + restore_volatile_regs(Z_SP, frame::z_abi_160_size, true, true); + pop_frame(); + restore_return_pc(); + + BLOCK_COMMENT("} verify_oop "); +} + +void MacroAssembler::verify_oop_addr(Address addr, const char* msg) { + if (!VerifyOops) return; + + BLOCK_COMMENT("verify_oop {"); + unsigned int nbytes_save = (5 + 8) * BytesPerWord; + address entry_addr = StubRoutines::verify_oop_subroutine_entry_address(); + + save_return_pc(); + unsigned int frame_size = push_frame_abi160(nbytes_save); // kills Z_R0 + save_volatile_regs(Z_SP, frame::z_abi_160_size, true, false); + + z_lg(Z_ARG2, addr.plus_disp(frame_size)); + load_const_optimized(Z_ARG1, (address)msg); + load_const_optimized(Z_R1, entry_addr); + z_lg(Z_R1, 0, Z_R1); + call_c(Z_R1); + + restore_volatile_regs(Z_SP, frame::z_abi_160_size, true, false); pop_frame(); restore_return_pc(); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index 8600c78a608..fb20b51ed29 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -973,8 +973,15 @@ class MacroAssembler: public Assembler { // Verify Z_thread contents. void verify_thread(); + // Save and restore functions: Exclude Z_R0. + void save_volatile_regs( Register dst, int offset, bool include_fp, bool include_flags); + void restore_volatile_regs(Register src, int offset, bool include_fp, bool include_flags); + // Only if +VerifyOops. + // Kills Z_R0. void verify_oop(Register reg, const char* s = "broken oop"); + // Kills Z_R0, condition code. + void verify_oop_addr(Address addr, const char* msg = "contains broken oop"); // TODO: verify_method and klass metadata (compare against vptr?). void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {} diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp index bb456117a1c..ca93ef3f136 100644 --- a/src/hotspot/cpu/s390/methodHandles_s390.cpp +++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp @@ -85,7 +85,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm, BLOCK_COMMENT("verify_klass {"); - __ verify_oop(obj_reg); + __ verify_oop(obj_reg, FILE_AND_LINE); __ compareU64_and_branch(obj_reg, (intptr_t)0L, Assembler::bcondEqual, L_bad); __ load_klass(temp_reg, obj_reg); // klass_addr is a klass in allstatic SystemDictionaryHandles. Can't get GCed. @@ -194,22 +194,22 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, BLOCK_COMMENT("jump_to_lambda_form {"); // Load the invoker, as MH -> MH.form -> LF.vmentry - __ verify_oop(recv); + __ verify_oop(recv, FILE_AND_LINE); __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), noreg, noreg, IS_NOT_NULL); - __ verify_oop(method_temp); + __ verify_oop(method_temp, FILE_AND_LINE); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), noreg, noreg, IS_NOT_NULL); - __ verify_oop(method_temp); + __ verify_oop(method_temp, FILE_AND_LINE); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), noreg, noreg, IS_NOT_NULL); - __ verify_oop(method_temp); + __ verify_oop(method_temp, FILE_AND_LINE); __ z_lg(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()))); @@ -385,7 +385,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, Register temp1_recv_klass = temp1; if (iid != vmIntrinsics::_linkToStatic) { - __ verify_oop(receiver_reg); + __ verify_oop(receiver_reg, FILE_AND_LINE); if (iid == vmIntrinsics::_linkToSpecial) { // Don't actually load the klass; just null-check the receiver. __ null_check(receiver_reg); diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index dae5d46a8cc..54beb8263ea 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -892,9 +892,9 @@ static void verify_oop_args(MacroAssembler *masm, if (r->is_stack()) { __ z_lg(Z_R0_scratch, Address(Z_SP, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); - __ verify_oop(Z_R0_scratch); + __ verify_oop(Z_R0_scratch, FILE_AND_LINE); } else { - __ verify_oop(r->as_Register()); + __ verify_oop(r->as_Register(), FILE_AND_LINE); } } } @@ -2686,7 +2686,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm __ z_ltgr(Z_ARG1, Z_ARG1); __ z_bre(ic_miss); } - __ verify_oop(Z_ARG1); + __ verify_oop(Z_ARG1, FILE_AND_LINE); // Check ic: object class <-> cached class // Compress cached class for comparison. That's more efficient. @@ -2955,7 +2955,7 @@ void SharedRuntime::generate_deopt_blob() { #ifdef ASSERT // verify that there is really an exception oop in JavaThread __ z_lg(Z_ARG1, Address(Z_thread, JavaThread::exception_oop_offset())); - __ verify_oop(Z_ARG1); + __ MacroAssembler::verify_oop(Z_ARG1, FILE_AND_LINE); // verify that there is no pending exception __ asm_assert_mem8_is_zero(in_bytes(Thread::pending_exception_offset()), Z_thread, diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 419f6832ad5..4a2e28b9569 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -667,6 +667,17 @@ class StubGenerator: public StubCodeGenerator { return start; } +#if !defined(PRODUCT) + // Wrapper which calls oopDesc::is_oop_or_null() + // Only called by MacroAssembler::verify_oop + static void verify_oop_helper(const char* message, oopDesc* o) { + if (!oopDesc::is_oop_or_null(o)) { + fatal("%s. oop: " PTR_FORMAT, message, p2i(o)); + } + ++ StubRoutines::_verify_oop_count; + } +#endif + // Return address of code to be called from code generated by // MacroAssembler::verify_oop. // @@ -679,6 +690,11 @@ class StubGenerator: public StubCodeGenerator { // StubCodeMark mark(this, "StubRoutines", "verify_oop_stub"); address start = 0; + +#if !defined(PRODUCT) + start = CAST_FROM_FN_PTR(address, verify_oop_helper); +#endif + return start; } From feccf3cdb6a99459a40612bf1b79d0a4a3d8ee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Fri, 10 Jan 2020 16:20:31 +0000 Subject: [PATCH 25/54] 8235669: G1: Stack walking API can expose AS_NO_KEEPALIVE oops Reviewed-by: kbarrett, tschatzl --- src/hotspot/share/code/debugInfo.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/code/debugInfo.cpp b/src/hotspot/share/code/debugInfo.cpp index 245774ee633..ebb5dd6258f 100644 --- a/src/hotspot/share/code/debugInfo.cpp +++ b/src/hotspot/share/code/debugInfo.cpp @@ -51,7 +51,15 @@ void DebugInfoWriteStream::write_metadata(Metadata* h) { } oop DebugInfoReadStream::read_oop() { - oop o = code()->oop_at(read_int()); + nmethod* nm = const_cast(code())->as_nmethod_or_null(); + oop o; + if (nm != NULL) { + // Despite these oops being found inside nmethods that are on-stack, + // they are not kept alive by all GCs (e.g. G1 and Shenandoah). + o = nm->oop_at_phantom(read_int()); + } else { + o = code()->oop_at(read_int()); + } assert(oopDesc::is_oop_or_null(o), "oop only"); return o; } From 78df4d412ebe3dc5b6214143c26b3004df29ab4f Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 10 Jan 2020 09:15:20 -0800 Subject: [PATCH 26/54] 8236877: Add "record" to descriptions in java.lang.{annotation, reflect} Reviewed-by: mchung, lancea, chegar --- .../share/classes/java/lang/Class.java | 19 +++++++++---------- .../java/lang/annotation/ElementType.java | 3 ++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 191e954f069..0a320f657cb 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -89,16 +89,15 @@ import sun.reflect.annotation.*; import sun.reflect.misc.ReflectUtil; /** - * Instances of the class {@code Class} represent classes and interfaces - * in a running Java application. An enum type is a kind of class and an - * annotation type is a kind of interface. Every array also - * belongs to a class that is reflected as a {@code Class} object - * that is shared by all arrays with the same element type and number - * of dimensions. The primitive Java types ({@code boolean}, - * {@code byte}, {@code char}, {@code short}, - * {@code int}, {@code long}, {@code float}, and - * {@code double}), and the keyword {@code void} are also - * represented as {@code Class} objects. + * Instances of the class {@code Class} represent classes and + * interfaces in a running Java application. An enum type and a record + * type are kinds of class; an annotation type is a kind of + * interface. Every array also belongs to a class that is reflected as + * a {@code Class} object that is shared by all arrays with the same + * element type and number of dimensions. The primitive Java types + * ({@code boolean}, {@code byte}, {@code char}, {@code short}, {@code + * int}, {@code long}, {@code float}, and {@code double}), and the + * keyword {@code void} are also represented as {@code Class} objects. * *

    {@code Class} has no public constructor. Instead a {@code Class} * object is constructed automatically by the Java Virtual Machine diff --git a/src/java.base/share/classes/java/lang/annotation/ElementType.java b/src/java.base/share/classes/java/lang/annotation/ElementType.java index 337e0264ece..9ae42e24a06 100644 --- a/src/java.base/share/classes/java/lang/annotation/ElementType.java +++ b/src/java.base/share/classes/java/lang/annotation/ElementType.java @@ -71,7 +71,8 @@ package java.lang.annotation; * @jls 4.1 The Kinds of Types and Values */ public enum ElementType { - /** Class, interface (including annotation type), or enum declaration */ + /** Class, interface (including annotation type), enum, or record + * declaration */ TYPE, /** Field declaration (includes enum constants) */ From b7e74ef62f4797d30a6edc5c7963f309b11b067d Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 10 Jan 2020 11:48:16 -0800 Subject: [PATCH 27/54] 8229396: jdeps ignores multi-release when generate-module-info used on command line Reviewed-by: alanb --- .../com/sun/tools/jdeps/ClassFileReader.java | 9 +- .../com/sun/tools/jdeps/JdepsTask.java | 23 ++-- .../sun/tools/jdeps/ModuleInfoBuilder.java | 35 +++-- .../tools/jdeps/resources/jdeps.properties | 7 +- .../jdeps/missingDeps/MissingDepsTest.java | 130 ++++++++++++++++++ .../tools/jdeps/missingDeps/p/internal/X.java | 32 +++++ .../jdeps/missingDeps/src/m1/module-info.java | 27 ++++ .../tools/jdeps/missingDeps/src/m1/p/Foo.java | 29 ++++ .../jdeps/missingDeps/src/m2/module-info.java | 26 ++++ .../tools/jdeps/missingDeps/src/m2/q/Bar.java | 30 ++++ .../tools/jdeps/missingDeps/src/m2/q/T.java | 27 ++++ 11 files changed, 343 insertions(+), 32 deletions(-) create mode 100644 test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java create mode 100644 test/langtools/tools/jdeps/missingDeps/p/internal/X.java create mode 100644 test/langtools/tools/jdeps/missingDeps/src/m1/module-info.java create mode 100644 test/langtools/tools/jdeps/missingDeps/src/m1/p/Foo.java create mode 100644 test/langtools/tools/jdeps/missingDeps/src/m2/module-info.java create mode 100644 test/langtools/tools/jdeps/missingDeps/src/m2/q/Bar.java create mode 100644 test/langtools/tools/jdeps/missingDeps/src/m2/q/T.java diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java index e29f41979bc..e0a3ec17a06 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,13 +58,6 @@ import java.util.zip.ZipFile; * a .class file, a directory, or a JAR file. */ public class ClassFileReader implements Closeable { - /** - * Returns a ClassFileReader instance of a given path. - */ - public static ClassFileReader newInstance(Path path) throws IOException { - return newInstance(path, null); - } - /** * Returns a ClassFileReader instance of a given path. */ diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java index 0766e5a3d32..2127df6c3fc 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -915,6 +915,11 @@ class JdepsTask { option); return false; } + if (!options.rootModules.isEmpty()) { + reportError("err.invalid.options", "-m or --module", + option); + return false; + } return true; } @@ -922,12 +927,12 @@ class JdepsTask { boolean run(JdepsConfiguration config) throws IOException { // check if any JAR file contains unnamed package for (String arg : inputArgs) { - try (ClassFileReader reader = ClassFileReader.newInstance(Paths.get(arg))) { + try (ClassFileReader reader = ClassFileReader.newInstance(Paths.get(arg), config.getVersion())) { Optional classInUnnamedPackage = reader.entries().stream() - .filter(n -> n.endsWith(".class")) - .filter(cn -> toPackageName(cn).isEmpty()) - .findFirst(); + .filter(n -> n.endsWith(".class")) + .filter(cn -> toPackageName(cn).isEmpty()) + .findFirst(); if (classInUnnamedPackage.isPresent()) { if (classInUnnamedPackage.get().equals("module-info.class")) { @@ -942,10 +947,10 @@ class JdepsTask { ModuleInfoBuilder builder = new ModuleInfoBuilder(config, inputArgs, dir, openModule); - boolean ok = builder.run(); - - if (!ok && !options.nowarning) { + boolean ok = builder.run(options.ignoreMissingDeps, log, options.nowarning); + if (!ok) { reportError("err.missing.dependences"); + log.println(); builder.visitMissingDeps(new SimpleDepVisitor()); } return ok; @@ -1041,7 +1046,7 @@ class JdepsTask { separator); boolean ok = analyzer.run(options.depth(), options.ignoreMissingDeps); if (!ok) { - reportError("err.cant.list.module.deps"); + reportError("err.missing.dependences"); log.println(); analyzer.visitMissingDeps(new SimpleDepVisitor()); } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java index fe05bd8636c..94fba26c5b7 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ public class ModuleInfoBuilder { } } - public boolean run() throws IOException { + public boolean run(boolean ignoreMissingDeps, PrintWriter log, boolean quiet) throws IOException { try { // pass 1: find API dependencies Map> requiresTransitive = computeRequiresTransitive(); @@ -108,52 +108,65 @@ public class ModuleInfoBuilder { analyzer.run(automaticModules(), dependencyFinder.locationToArchive()); - boolean missingDeps = false; for (Module m : automaticModules()) { Set apiDeps = requiresTransitive.containsKey(m) ? requiresTransitive.get(m) : Collections.emptySet(); - Path file = outputdir.resolve(m.name()).resolve("module-info.java"); + // if this is a multi-release JAR, write to versions/$VERSION/module-info.java + Runtime.Version version = configuration.getVersion(); + Path dir = version != null + ? outputdir.resolve(m.name()) + .resolve("versions") + .resolve(String.valueOf(version.feature())) + : outputdir.resolve(m.name()); + Path file = dir.resolve("module-info.java"); // computes requires and requires transitive - Module normalModule = toNormalModule(m, apiDeps); + Module normalModule = toNormalModule(m, apiDeps, ignoreMissingDeps); if (normalModule != null) { automaticToNormalModule.put(m, normalModule); // generate module-info.java - System.out.format("writing to %s%n", file); + if (!quiet) { + if (ignoreMissingDeps && analyzer.requires(m).anyMatch(Analyzer::notFound)) { + log.format("Warning: --ignore-missing-deps specified. Missing dependencies from %s are ignored%n", + m.name()); + } + log.format("writing to %s%n", file); + } writeModuleInfo(file, normalModule.descriptor()); } else { // find missing dependences - System.out.format("Missing dependence: %s not generated%n", file); - missingDeps = true; + return false; } } - return !missingDeps; } finally { dependencyFinder.shutdown(); } + return true; } - private Module toNormalModule(Module module, Set requiresTransitive) + private Module toNormalModule(Module module, Set requiresTransitive, boolean ignoreMissingDeps) throws IOException { // done analysis module.close(); - if (analyzer.requires(module).anyMatch(Analyzer::notFound)) { + if (!ignoreMissingDeps && analyzer.requires(module).anyMatch(Analyzer::notFound)) { // missing dependencies return null; } Map requires = new HashMap<>(); requiresTransitive.stream() + .filter(a -> !(ignoreMissingDeps && Analyzer.notFound(a))) .map(Archive::getModule) .forEach(m -> requires.put(m.name(), Boolean.TRUE)); analyzer.requires(module) + .filter(a -> !(ignoreMissingDeps && Analyzer.notFound(a))) .map(Archive::getModule) .forEach(d -> requires.putIfAbsent(d.name(), Boolean.FALSE)); diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties index 2b55e39aad6..98babe8e7ed 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -229,7 +229,6 @@ main.opt.multi-release=\ err.command.set={0} and {1} options are specified. err.unknown.option=unknown option: {0} err.missing.arg=no value given for {0} -err.missing.dependences=missing dependencies err.invalid.arg.for.option=invalid argument for option: {0} err.option.after.class=option must be specified before classes: {0} err.genmoduleinfo.not.jarfile={0} is a modular JAR file that cannot be specified with the --generate-module-info option @@ -246,8 +245,8 @@ err.multirelease.option.exists={0} is not a multi-release jar file but --multi-r err.multirelease.option.notfound={0} is a multi-release jar file but --multi-release option is not set err.multirelease.version.associated=class {0} already associated with version {1}, trying to add version {2} err.multirelease.jar.malformed=malformed multi-release jar, {0}, bad entry: {1} -err.cant.list.module.deps=\ -Missing dependencies from the module path and classpath.\n\ +err.missing.dependences=\ +Missing dependencies: classes not found from the module path and classpath.\n\ To suppress this error, use --ignore-missing-deps to continue. warn.invalid.arg=Path does not exist: {0} diff --git a/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java b/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java new file mode 100644 index 00000000000..430fe40e458 --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Tests jdeps option on a MR jar with missing dependences + * @library ../lib + * @build CompilerUtils JdepsUtil + * @modules jdk.jdeps/com.sun.tools.jdeps + * @run testng MissingDepsTest + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.spi.ToolProvider; +import java.util.stream.Stream; + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertEquals; + + +public class MissingDepsTest { + private static final String TEST_SRC = System.getProperty("test.src"); + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); + + private static final Path MODS_DIR = Paths.get("mods"); + private static final Path CLASSES_DIR = Paths.get("classes"); + + private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar").orElseThrow(); + private static final String VERSION = "13"; + + private static final Set modules = Set.of("m1", "m2"); + + /** + * Compiles classes used by the test + */ + @BeforeTest + public void compileAll() throws Exception { + CompilerUtils.cleanDir(MODS_DIR); + modules.forEach(mn -> + assertTrue(CompilerUtils.compileModule(SRC_DIR, MODS_DIR, mn))); + + // compile a versioned class file + Path versionedFile = Paths.get(TEST_SRC, "p/internal/X.java"); + assertTrue(CompilerUtils.compile(versionedFile, CLASSES_DIR, "-cp", MODS_DIR.resolve("m2").toString())); + + // create a modular multi-release m1.jar + JAR_TOOL.run(System.out, System.err, "cf", "m1.jar", + "-C", MODS_DIR.resolve("m1").toString(), "."); + JAR_TOOL.run(System.out, System.err, "uf", "m1.jar", + "--release", VERSION, "-C", CLASSES_DIR.toString(), "p/internal/X.class"); + // create a non-modular multi-release mr.jar + JAR_TOOL.run(System.out, System.err, "cf", "mr.jar", + "-C", MODS_DIR.resolve("m1").toString(), "p/Foo.class", + "--release", VERSION, "-C", CLASSES_DIR.toString(), "p/internal/X.class"); + } + + @Test + public void genModuleInfo() { + JdepsTest test = new JdepsTest(); + test.options(List.of("--generate-module-info", ".", "--multi-release", VERSION, "mr.jar")); + test.checkMissingDeps(); + Path file = Paths.get("mr", "versions", VERSION, "module-info.java"); + test.ignoreMissingDeps(file.toString()); + assertTrue(Files.exists(file)); + } + + @Test + public void listModuleDeps() { + JdepsTest test = new JdepsTest(); + test.options(List.of("--list-deps", "--multi-release", VERSION, "mr.jar")); + test.checkMissingDeps(); + test.ignoreMissingDeps("java.management"); + } + + class JdepsTest { + // set DEBUG to true to show the jdeps output + static final boolean DEBUG = false; + List options; + JdepsTest options(List options) { + this.options = options; + return this; + } + + private void checkMissingDeps() { + JdepsRunner jdepsRunner = new JdepsRunner(options.toArray(new String[0])); + int rc = jdepsRunner.run(DEBUG); + assertTrue(rc != 0); + String regex = "\\s+13/p.internal.X\\s+->\\s+q.T\\s+not found"; + assertTrue(Arrays.stream(jdepsRunner.output()).anyMatch(l -> l.matches(regex))); + } + + public void ignoreMissingDeps(String expected) { + JdepsRunner jdepsRunner = new JdepsRunner(Stream.concat(Stream.of("--ignore-missing-deps"), options.stream()) + .toArray(String[]::new)); + int rc = jdepsRunner.run(DEBUG); + assertTrue(rc == 0); + System.out.println("Expected: " + expected); + assertTrue(Arrays.stream(jdepsRunner.output()).anyMatch(l -> l.contains(expected))); + } + } +} diff --git a/test/langtools/tools/jdeps/missingDeps/p/internal/X.java b/test/langtools/tools/jdeps/missingDeps/p/internal/X.java new file mode 100644 index 00000000000..5e1fe26860f --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/p/internal/X.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p.internal; + +import java.lang.management.*; + +class X implements q.T { + public void upTime() { + ManagementFactory.getRuntimeMXBean().getUptime(); + } +} diff --git a/test/langtools/tools/jdeps/missingDeps/src/m1/module-info.java b/test/langtools/tools/jdeps/missingDeps/src/m1/module-info.java new file mode 100644 index 00000000000..ccf7f99dfcc --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/src/m1/module-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module m1 { + requires static m2; + exports p; +} diff --git a/test/langtools/tools/jdeps/missingDeps/src/m1/p/Foo.java b/test/langtools/tools/jdeps/missingDeps/src/m1/p/Foo.java new file mode 100644 index 00000000000..247e0b5f306 --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/src/m1/p/Foo.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p; + +public class Foo implements Runnable { + public void run() { + } +} diff --git a/test/langtools/tools/jdeps/missingDeps/src/m2/module-info.java b/test/langtools/tools/jdeps/missingDeps/src/m2/module-info.java new file mode 100644 index 00000000000..ace57798286 --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/src/m2/module-info.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module m2 { + exports q; +} diff --git a/test/langtools/tools/jdeps/missingDeps/src/m2/q/Bar.java b/test/langtools/tools/jdeps/missingDeps/src/m2/q/Bar.java new file mode 100644 index 00000000000..97b706888e0 --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/src/m2/q/Bar.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package q; + +public interface Bar { + default String name() { + return ""; + } +} diff --git a/test/langtools/tools/jdeps/missingDeps/src/m2/q/T.java b/test/langtools/tools/jdeps/missingDeps/src/m2/q/T.java new file mode 100644 index 00000000000..592c201cae2 --- /dev/null +++ b/test/langtools/tools/jdeps/missingDeps/src/m2/q/T.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package q; + +public interface T { +} From fe8e1aacd16e4a0d3638550f7a28c4a9ff116e04 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 10 Jan 2020 11:50:54 -0800 Subject: [PATCH 28/54] 8225773: jdeps --check produces NPE if there are missing module dependences Reviewed-by: alanb --- .../com/sun/tools/jdeps/JdepsTask.java | 2 +- .../com/sun/tools/jdeps/ModuleAnalyzer.java | 76 +++++++++++++------ .../jdeps/missingDeps/MissingDepsTest.java | 8 ++ .../tools/jdeps/modules/CheckModuleTest.java | 6 +- 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java index 2127df6c3fc..307a488f405 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java @@ -986,7 +986,7 @@ class JdepsTask { throw new UncheckedBadArgs(new BadArgs("err.invalid.options", list, "--check")); } - return new ModuleAnalyzer(config, log, modules).run(); + return new ModuleAnalyzer(config, log, modules).run(options.ignoreMissingDeps); } /* diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java index 233f62b80ba..3bab7be1d92 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,22 +24,16 @@ */ package com.sun.tools.jdeps; -import static com.sun.tools.jdeps.Graph.*; import static com.sun.tools.jdeps.JdepsFilter.DEFAULT_FILTER; import static com.sun.tools.jdeps.Module.*; import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; import static java.util.stream.Collectors.*; import com.sun.tools.classfile.Dependency; -import com.sun.tools.jdeps.JdepsTask.BadArgs; import java.io.IOException; -import java.io.OutputStream; import java.io.PrintWriter; import java.lang.module.ModuleDescriptor; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -80,23 +74,32 @@ public class ModuleAnalyzer { } } - public boolean run() throws IOException { + public boolean run(boolean ignoreMissingDeps) throws IOException { try { - // compute "requires transitive" dependences - modules.values().forEach(ModuleDeps::computeRequiresTransitive); - - modules.values().forEach(md -> { + for (ModuleDeps md: modules.values()) { + // compute "requires transitive" dependences + md.computeRequiresTransitive(ignoreMissingDeps); // compute "requires" dependences - md.computeRequires(); + md.computeRequires(ignoreMissingDeps); + // print module descriptor + md.printModuleDescriptor(); + // apply transitive reduction and reports recommended requires. - md.analyzeDeps(); - }); + boolean ok = md.analyzeDeps(); + if (!ok) return false; + + if (ignoreMissingDeps && md.hasMissingDependencies()) { + log.format("Warning: --ignore-missing-deps specified. Missing dependencies from %s are ignored%n", + md.root.name()); + } + } } finally { dependencyFinder.shutdown(); } return true; } + class ModuleDeps { final Module root; Set requiresTransitive; @@ -110,23 +113,22 @@ public class ModuleAnalyzer { /** * Compute 'requires transitive' dependences by analyzing API dependencies */ - private void computeRequiresTransitive() { + private void computeRequiresTransitive(boolean ignoreMissingDeps) { // record requires transitive - this.requiresTransitive = computeRequires(true) + this.requiresTransitive = computeRequires(true, ignoreMissingDeps) .filter(m -> !m.name().equals(JAVA_BASE)) .collect(toSet()); trace("requires transitive: %s%n", requiresTransitive); } - private void computeRequires() { - this.requires = computeRequires(false).collect(toSet()); + private void computeRequires(boolean ignoreMissingDeps) { + this.requires = computeRequires(false, ignoreMissingDeps).collect(toSet()); trace("requires: %s%n", requires); } - private Stream computeRequires(boolean apionly) { + private Stream computeRequires(boolean apionly, boolean ignoreMissingDeps) { // analyze all classes - if (apionly) { dependencyFinder.parseExportedAPIs(Stream.of(root)); } else { @@ -135,9 +137,14 @@ public class ModuleAnalyzer { // find the modules of all the dependencies found return dependencyFinder.getDependences(root) + .filter(a -> !(ignoreMissingDeps && Analyzer.notFound(a))) .map(Archive::getModule); } + boolean hasMissingDependencies() { + return dependencyFinder.getDependences(root).anyMatch(Analyzer::notFound); + } + ModuleDescriptor descriptor() { return descriptor(requiresTransitive, requires); } @@ -196,12 +203,30 @@ public class ModuleAnalyzer { return descriptor(requiresTransitive, g.adjacentNodes(root)); } + private void showMissingDeps() { + // build the analyzer if there are missing dependences + Analyzer analyzer = new Analyzer(configuration, Analyzer.Type.CLASS, DEFAULT_FILTER); + analyzer.run(Set.of(root), dependencyFinder.locationToArchive()); + log.println("Error: Missing dependencies: classes not found from the module path."); + Analyzer.Visitor visitor = new Analyzer.Visitor() { + @Override + public void visitDependence(String origin, Archive originArchive, String target, Archive targetArchive) { + log.format(" %-50s -> %-50s %s%n", origin, target, targetArchive.getName()); + } + }; + analyzer.visitDependences(root, visitor, Analyzer.Type.VERBOSE, Analyzer::notFound); + log.println(); + } + /** * Apply transitive reduction on the resulting graph and reports * recommended requires. */ - private void analyzeDeps() { - printModuleDescriptor(log, root); + private boolean analyzeDeps() { + if (requires.stream().anyMatch(m -> m == UNNAMED_MODULE)) { + showMissingDeps(); + return false; + } ModuleDescriptor analyzedDescriptor = descriptor(); if (!matches(root.descriptor(), analyzedDescriptor)) { @@ -223,6 +248,7 @@ public class ModuleAnalyzer { checkQualifiedExports(); log.println(); + return true; } private void checkQualifiedExports() { @@ -239,6 +265,10 @@ public class ModuleAnalyzer { .collect(joining(",")))); } + void printModuleDescriptor() { + printModuleDescriptor(log, root); + } + private void printModuleDescriptor(PrintWriter out, Module module) { ModuleDescriptor descriptor = module.descriptor(); out.format("%s (%s)%n", descriptor.name(), module.location()); diff --git a/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java b/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java index 430fe40e458..edd3f3f5787 100644 --- a/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java +++ b/test/langtools/tools/jdeps/missingDeps/MissingDepsTest.java @@ -83,6 +83,14 @@ public class MissingDepsTest { "--release", VERSION, "-C", CLASSES_DIR.toString(), "p/internal/X.class"); } + @Test + public void checkModuleDeps() { + JdepsTest test = new JdepsTest(); + test.options(List.of("--module-path", "m1.jar", "--multi-release", VERSION, "--check", "m1")); + test.checkMissingDeps(); + test.ignoreMissingDeps("requires java.management"); + } + @Test public void genModuleInfo() { JdepsTest test = new JdepsTest(); diff --git a/test/langtools/tools/jdeps/modules/CheckModuleTest.java b/test/langtools/tools/jdeps/modules/CheckModuleTest.java index 128832cb4b1..850b69e9ee5 100644 --- a/test/langtools/tools/jdeps/modules/CheckModuleTest.java +++ b/test/langtools/tools/jdeps/modules/CheckModuleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,7 @@ public class CheckModuleTest { jdeps.appModulePath(MODS_DIR.toString()); ModuleAnalyzer analyzer = jdeps.getModuleAnalyzer(Set.of(name)); - assertTrue(analyzer.run()); + assertTrue(analyzer.run(false)); jdeps.dumpOutput(System.err); ModuleDescriptor[] descriptors = analyzer.descriptors(name); @@ -146,7 +146,7 @@ public class CheckModuleTest { jdeps.appModulePath(MODS_DIR.toString()); ModuleAnalyzer analyzer = jdeps.getModuleAnalyzer(Set.of(name)); - assertTrue(analyzer.run()); + assertTrue(analyzer.run(false)); jdeps.dumpOutput(System.err); // compare the module descriptors and the suggested versions From 0b542e3bae0868ba4736ee41e5940fcf2cf543be Mon Sep 17 00:00:00 2001 From: Christoph Dreis Date: Fri, 10 Jan 2020 12:01:21 -0800 Subject: [PATCH 29/54] 8236945: typo "the the" in Lookup::in javadoc Reviewed-by: mchung --- src/java.base/share/classes/java/lang/invoke/MethodHandles.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 16362f54ccc..d4b4ceb7f72 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -1451,7 +1451,7 @@ public class MethodHandles { *

  • If the new lookup class is in the same module as the old lookup class, * the new previous lookup class is the old previous lookup class. *
  • If the new lookup class is in a different module from the old lookup class, - * the new previous lookup class is the the old lookup class. + * the new previous lookup class is the old lookup class. * *

    * The resulting lookup's capabilities for loading classes From 2c7c8023edaf5e0411685cfbdb0650580d080ed7 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 10 Jan 2020 21:09:53 +0100 Subject: [PATCH 30/54] 8236263: Remove experimental streaming events Reviewed-by: rehn, mseledtsov --- src/hotspot/share/jfr/metadata/metadata.xml | 32 +---------- .../recorder/service/jfrRecorderService.cpp | 55 ++++++------------- src/jdk.jfr/share/conf/jfr/default.jfc | 27 +-------- src/jdk.jfr/share/conf/jfr/profile.jfc | 27 +-------- 4 files changed, 21 insertions(+), 120 deletions(-) diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index cd9705f71c7..f69330dea2e 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -1,7 +1,7 @@