# HG changeset patch # User bobv # Date 1541017651 14400 # Node ID e38473506688e0995e701fc7f77d5a91b438ef93 # Parent c42cd17e8e64c0a02e76f3e9a934b27a900028c0# Parent e2478be9c682c9162f4a32bac214f51c57181570 Merge diff -r c42cd17e8e64 -r e38473506688 make/conf/jib-profiles.js --- a/make/conf/jib-profiles.js Wed Oct 31 16:27:01 2018 -0400 +++ b/make/conf/jib-profiles.js Wed Oct 31 16:27:31 2018 -0400 @@ -799,7 +799,7 @@ var getJibProfilesDependencies = function (input, common) { var devkit_platform_revisions = { - linux_x64: "gcc7.3.0-OEL6.4+1.0", + linux_x64: "gcc7.3.0-OEL6.4+1.1", macosx_x64: "Xcode9.4-MacOSX10.13+1.0", solaris_x64: "SS12u4-Solaris11u1+1.0", solaris_sparcv9: "SS12u6-Solaris11u3+1.0", diff -r c42cd17e8e64 -r e38473506688 make/devkit/Makefile --- a/make/devkit/Makefile Wed Oct 31 16:27:01 2018 -0400 +++ b/make/devkit/Makefile Wed Oct 31 16:27:31 2018 -0400 @@ -36,7 +36,7 @@ # By default this Makefile will build a native toolchain for the current # platform if called with something like this: # -# make tars +# make tars BASE_OS=OEL6 # # To build the full set of crosstools for additional platforms, use a command # line looking like this: diff -r c42cd17e8e64 -r e38473506688 make/devkit/Tools.gmk --- a/make/devkit/Tools.gmk Wed Oct 31 16:27:01 2018 -0400 +++ b/make/devkit/Tools.gmk Wed Oct 31 16:27:31 2018 -0400 @@ -110,6 +110,7 @@ libXext libXext-devel \ libXtst libXtst-devel \ libXrender libXrender-devel \ + libXrandr libXrandr-devel \ freetype freetype-devel \ libXt libXt-devel \ libSM libSM-devel \ diff -r c42cd17e8e64 -r e38473506688 src/hotspot/cpu/ppc/assembler_ppc.hpp --- a/src/hotspot/cpu/ppc/assembler_ppc.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -535,6 +535,9 @@ XVMULSP_OPCODE = (60u << OPCODE_SHIFT | 80u << 3), XVMULDP_OPCODE = (60u << OPCODE_SHIFT | 112u << 3), + // Deliver A Random Number (introduced with POWER9) + DARN_OPCODE = (31u << OPCODE_SHIFT | 755u << 1), + // Vector Permute and Formatting VPKPX_OPCODE = (4u << OPCODE_SHIFT | 782u ), VPKSHSS_OPCODE = (4u << OPCODE_SHIFT | 398u ), @@ -1072,6 +1075,7 @@ static int frt( int x) { return opp_u_field(x, 10, 6); } static int fxm( int x) { return opp_u_field(x, 19, 12); } static int l10( int x) { return opp_u_field(x, 10, 10); } + static int l14( int x) { return opp_u_field(x, 15, 14); } static int l15( int x) { return opp_u_field(x, 15, 15); } static int l910( int x) { return opp_u_field(x, 10, 9); } static int e1215( int x) { return opp_u_field(x, 15, 12); } @@ -2220,6 +2224,9 @@ inline void mtfprwa( FloatRegister d, Register a); inline void mffprd( Register a, FloatRegister d); + // Deliver A Random Number (introduced with POWER9) + inline void darn( Register d, int l = 1 /*L=CRN*/); + // AES (introduced with Power 8) inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b); diff -r c42cd17e8e64 -r e38473506688 src/hotspot/cpu/ppc/assembler_ppc.inline.hpp --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2017 SAP SE. All rights reserved. + * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -979,6 +979,9 @@ inline void Assembler::tresume_() { emit_int32( TSR_OPCODE | /*L=1*/ 1u << (31-10) | rc(1)); } inline void Assembler::tcheck(int f) { emit_int32( TCHECK_OPCODE | bf(f)); } +// Deliver A Random Number (introduced with POWER9) +inline void Assembler::darn(Register d, int l /* =1 */) { emit_int32( DARN_OPCODE | rt(d) | l14(l)); } + // ra0 version inline void Assembler::lwzx( Register d, Register s2) { emit_int32( LWZX_OPCODE | rt(d) | rb(s2));} inline void Assembler::lwz( Register d, int si16 ) { emit_int32( LWZ_OPCODE | rt(d) | d1(si16));} diff -r c42cd17e8e64 -r e38473506688 src/hotspot/cpu/ppc/vm_version_ppc.cpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -63,7 +63,9 @@ // If PowerArchitecturePPC64 hasn't been specified explicitly determine from features. if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) { - if (VM_Version::has_lqarx()) { + if (VM_Version::has_darn()) { + FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 9); + } else if (VM_Version::has_lqarx()) { FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 8); } else if (VM_Version::has_popcntw()) { FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 7); @@ -78,6 +80,7 @@ bool PowerArchitecturePPC64_ok = false; switch (PowerArchitecturePPC64) { + case 9: if (!VM_Version::has_darn() ) break; case 8: if (!VM_Version::has_lqarx() ) break; case 7: if (!VM_Version::has_popcntw()) break; case 6: if (!VM_Version::has_cmpb() ) break; @@ -131,12 +134,11 @@ // Create and print feature-string. char buf[(num_features+1) * 16]; // Max 16 chars per feature. jio_snprintf(buf, sizeof(buf), - "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (has_fsqrt() ? " fsqrt" : ""), (has_isel() ? " isel" : ""), (has_lxarxeh() ? " lxarxeh" : ""), (has_cmpb() ? " cmpb" : ""), - //(has_mftgpr()? " mftgpr" : ""), (has_popcntb() ? " popcntb" : ""), (has_popcntw() ? " popcntw" : ""), (has_fcfids() ? " fcfids" : ""), @@ -149,7 +151,8 @@ (has_ldbrx() ? " ldbrx" : ""), (has_stdbrx() ? " stdbrx" : ""), (has_vshasig() ? " sha" : ""), - (has_tm() ? " rtm" : "") + (has_tm() ? " rtm" : ""), + (has_darn() ? " darn" : "") // Make sure number of %s matches num_features! ); _features_string = os::strdup(buf); @@ -663,6 +666,8 @@ a->ldbrx(R7, R3_ARG1, R4_ARG2); // code[14] -> ldbrx a->stdbrx(R7, R3_ARG1, R4_ARG2); // code[15] -> stdbrx a->vshasigmaw(VR0, VR1, 1, 0xF); // code[16] -> vshasig + // rtm is determined by OS + a->darn(R7); // code[17] -> darn a->blr(); // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. @@ -714,6 +719,8 @@ if (code[feature_cntr++]) features |= ldbrx_m; if (code[feature_cntr++]) features |= stdbrx_m; if (code[feature_cntr++]) features |= vshasig_m; + // feature rtm_m is determined by OS + if (code[feature_cntr++]) features |= darn_m; // Print the detection code. if (PrintAssembly) { diff -r c42cd17e8e64 -r e38473506688 src/hotspot/cpu/ppc/vm_version_ppc.hpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2017 SAP SE. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,7 @@ stdbrx, vshasig, rtm, + darn, num_features // last entry to count features }; enum Feature_Flag_Set { @@ -72,6 +73,7 @@ stdbrx_m = (1 << stdbrx ), vshasig_m = (1 << vshasig), rtm_m = (1 << rtm ), + darn_m = (1 << darn ), all_features_m = (unsigned long)-1 }; @@ -108,9 +110,10 @@ static bool has_ldbrx() { return (_features & ldbrx_m) != 0; } static bool has_stdbrx() { return (_features & stdbrx_m) != 0; } static bool has_vshasig() { return (_features & vshasig_m) != 0; } + static bool has_tm() { return (_features & rtm_m) != 0; } + static bool has_darn() { return (_features & darn_m) != 0; } + static bool has_mtfprd() { return has_vpmsumb(); } // alias for P8 - // OS feature support - static bool has_tm() { return (_features & rtm_m) != 0; } // Assembler testing static void allow_all(); diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/ci/ciInstanceKlass.cpp --- a/src/hotspot/share/ci/ciInstanceKlass.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/ci/ciInstanceKlass.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -57,7 +57,7 @@ AccessFlags access_flags = ik->access_flags(); _flags = ciFlags(access_flags); _has_finalizer = access_flags.has_finalizer(); - _has_subklass = flags().is_final() ? subklass_false : subklass_unknown; + _has_subklass = ik->subklass() != NULL; _init_state = ik->init_state(); _nonstatic_field_size = ik->nonstatic_field_size(); _has_nonstatic_fields = ik->has_nonstatic_fields(); @@ -146,10 +146,9 @@ // ciInstanceKlass::compute_shared_has_subklass bool ciInstanceKlass::compute_shared_has_subklass() { GUARDED_VM_ENTRY( - MutexLocker ml(Compile_lock); InstanceKlass* ik = get_instanceKlass(); - _has_subklass = ik->subklass() != NULL ? subklass_true : subklass_false; - return _has_subklass == subklass_true; + _has_subklass = ik->subklass() != NULL; + return _has_subklass; ) } @@ -375,7 +374,6 @@ if (!is_abstract()) return NULL; // Only applies to abstract classes. if (!has_subklass()) return NULL; // Must have at least one subklass. VM_ENTRY_MARK; - MutexLocker ml(Compile_lock); InstanceKlass* ik = get_instanceKlass(); Klass* up = ik->up_cast_abstract(); assert(up->is_instance_klass(), "must be InstanceKlass"); @@ -390,7 +388,6 @@ bool ciInstanceKlass::has_finalizable_subclass() { if (!is_loaded()) return true; VM_ENTRY_MARK; - MutexLocker ml(Compile_lock); return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL; } @@ -580,7 +577,7 @@ if (is_shared()) { return is_final(); // approximately correct } else { - return !has_subklass() && (nof_implementors() == 0); + return !_has_subklass && (nof_implementors() == 0); } } diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/ci/ciInstanceKlass.hpp --- a/src/hotspot/share/ci/ciInstanceKlass.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/ci/ciInstanceKlass.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -44,15 +44,13 @@ friend class ciField; private: - enum SubklassValue { subklass_unknown, subklass_false, subklass_true }; - jobject _loader; jobject _protection_domain; InstanceKlass::ClassState _init_state; // state of class bool _is_shared; bool _has_finalizer; - SubklassValue _has_subklass; + bool _has_subklass; bool _has_nonstatic_fields; bool _has_nonstatic_concrete_methods; bool _is_unsafe_anonymous; @@ -141,15 +139,14 @@ return _has_finalizer; } bool has_subklass() { assert(is_loaded(), "must be loaded"); - if (_has_subklass == subklass_unknown || - (_is_shared && _has_subklass == subklass_false)) { + if (_is_shared && !_has_subklass) { if (flags().is_final()) { return false; } else { return compute_shared_has_subklass(); } } - return _has_subklass == subklass_true; + return _has_subklass; } jint size_helper() { return (Klass::layout_helper_size_in_bytes(layout_helper()) diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp --- a/src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -90,6 +90,7 @@ DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread)); Stack mark_stack; + MutexLocker ml(Compile_lock, thread); mark_stack.push(event_klass->subklass()); while (!mark_stack.is_empty()) { @@ -145,19 +146,16 @@ assert(klass != NULL, "invariant"); assert(JdkJfrEvent::is(klass), "invariant"); + if (klass->subklass() == NULL) { + return empty_java_util_arraylist; + } + ResourceMark rm(THREAD); GrowableArray event_subklasses(THREAD, initial_size_growable_array); - { - MutexLocker cl(Compile_lock); - if (klass->subklass() == NULL) { - return empty_java_util_arraylist; - } + fill_klasses(event_subklasses, klass, THREAD); - fill_klasses(event_subklasses, klass, THREAD); - - if (event_subklasses.is_empty()) { - return empty_java_util_arraylist; - } + if (event_subklasses.is_empty()) { + return empty_java_util_arraylist; } transform_klasses_to_local_jni_handles(event_subklasses, THREAD); diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/jvmci/jvmciCompilerToVM.cpp --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -627,7 +627,6 @@ C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type)) Klass* klass = CompilerToVM::asKlass(jvmci_type); assert(klass != NULL, "method must not be called for primitive types"); - MutexLocker ml(Compile_lock); return Dependencies::find_finalizable_subclass(klass) != NULL; C2V_END diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/memory/universe.cpp --- a/src/hotspot/share/memory/universe.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/memory/universe.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -531,6 +531,10 @@ #undef assert_pll_locked #undef assert_pll_ownership +// initialize_vtable could cause gc if +// 1) we specified true to initialize_vtable and +// 2) this ran after gc was enabled +// In case those ever change we use handles for oops void Universe::reinitialize_vtable_of(Klass* ko, TRAPS) { // init vtable of k and all subclasses ko->vtable().initialize_vtable(false, CHECK); @@ -543,16 +547,6 @@ } } -void Universe::reinitialize_vtables(TRAPS) { - // The vtables are initialized by starting at java.lang.Object and - // initializing through the subclass links, so that the super - // classes are always initialized first. The subclass links - // require the Compile_lock. - MutexLocker cl(Compile_lock); - Klass* ok = SystemDictionary::Object_klass(); - Universe::reinitialize_vtable_of(ok, THREAD); -} - void initialize_itable_for_klass(InstanceKlass* k, TRAPS) { k->itable().initialize_itable(false, CHECK); @@ -970,7 +964,9 @@ { ResourceMark rm; Interpreter::initialize(); // needed for interpreter entry points if (!UseSharedSpaces) { - Universe::reinitialize_vtables(CHECK_false); + HandleMark hm(THREAD); + Klass* ok = SystemDictionary::Object_klass(); + Universe::reinitialize_vtable_of(ok, CHECK_false); Universe::reinitialize_itables(CHECK_false); } } diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/memory/universe.hpp --- a/src/hotspot/share/memory/universe.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/memory/universe.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -219,7 +219,6 @@ static void fixup_mirrors(TRAPS); static void reinitialize_vtable_of(Klass* k, TRAPS); - static void reinitialize_vtables(TRAPS); static void reinitialize_itables(TRAPS); static void compute_base_vtable_size(); // compute vtable size of class Object diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/oops/instanceKlass.cpp --- a/src/hotspot/share/oops/instanceKlass.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/oops/instanceKlass.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -1054,28 +1054,16 @@ } } -Klass* InstanceKlass::implementor(bool log) const { +Klass* InstanceKlass::implementor() const { assert_locked_or_safepoint(Compile_lock); Klass** k = adr_implementor(); if (k == NULL) { return NULL; } else { - Klass* kls = *k; - if (kls != NULL && !kls->is_loader_alive()) { - if (log) { - if (log_is_enabled(Trace, class, unload)) { - ResourceMark rm; - log_trace(class, unload)("unlinking class (implementor): %s", kls->external_name()); - } - } - return NULL; // don't return unloaded class - } else { - return kls; - } + return *k; } } - void InstanceKlass::set_implementor(Klass* k) { assert_lock_strong(Compile_lock); assert(is_interface(), "not interface"); @@ -2151,15 +2139,20 @@ } void InstanceKlass::clean_implementors_list() { - assert_locked_or_safepoint(Compile_lock); assert(is_loader_alive(), "this klass should be live"); if (is_interface()) { - assert (ClassUnloading, "only called for ClassUnloading"); - Klass* impl = implementor(true); - if (impl == NULL) { - // NULL this field, might be an unloaded klass or NULL - Klass** klass = adr_implementor(); - *klass = NULL; + if (ClassUnloading) { + Klass* impl = implementor(); + if (impl != NULL) { + if (!impl->is_loader_alive()) { + // remove this guy + Klass** klass = adr_implementor(); + assert(klass != NULL, "null klass"); + if (klass != NULL) { + *klass = NULL; + } + } + } } } } @@ -3087,29 +3080,28 @@ st->print(BULLET"name: "); name()->print_value_on(st); st->cr(); st->print(BULLET"super: "); Metadata::print_value_on_maybe_null(st, super()); st->cr(); st->print(BULLET"sub: "); - { - MutexLocker ml(Compile_lock); - Klass* sub = subklass(); - int n; - for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) { - if (n < MaxSubklassPrintSize) { - sub->print_value_on(st); - st->print(" "); - } - } - if (n >= MaxSubklassPrintSize) st->print("(" INTX_FORMAT " more klasses...)", n - MaxSubklassPrintSize); - st->cr(); - - if (is_interface()) { - st->print_cr(BULLET"nof implementors: %d", nof_implementors()); - if (nof_implementors() == 1) { - st->print_cr(BULLET"implementor: "); - st->print(" "); - implementor()->print_value_on(st); - st->cr(); - } + Klass* sub = subklass(); + int n; + for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) { + if (n < MaxSubklassPrintSize) { + sub->print_value_on(st); + st->print(" "); } } + if (n >= MaxSubklassPrintSize) st->print("(" INTX_FORMAT " more klasses...)", n - MaxSubklassPrintSize); + st->cr(); + + if (is_interface()) { + MutexLocker ml(Compile_lock); + st->print_cr(BULLET"nof implementors: %d", nof_implementors()); + if (nof_implementors() == 1) { + st->print_cr(BULLET"implementor: "); + st->print(" "); + implementor()->print_value_on(st); + st->cr(); + } + } + st->print(BULLET"arrays: "); Metadata::print_value_on_maybe_null(st, array_klasses()); st->cr(); st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); if (Verbose || WizardMode) { @@ -3491,30 +3483,26 @@ vtable().verify(st); } - // This is called from add_to_hierarchy when the Compile_lock is owned. - { - MutexLockerEx ml(Compile_lock->owned_by_self() ? NULL : Compile_lock); - // Verify first subklass - if (subklass() != NULL) { - guarantee(subklass()->is_klass(), "should be klass"); + // Verify first subklass + if (subklass() != NULL) { + guarantee(subklass()->is_klass(), "should be klass"); + } + + // Verify siblings + Klass* super = this->super(); + Klass* sib = next_sibling(); + if (sib != NULL) { + if (sib == this) { + fatal("subclass points to itself " PTR_FORMAT, p2i(sib)); } - // Verify siblings - Klass* super = this->super(); - Klass* sib = next_sibling(); - if (sib != NULL) { - if (sib == this) { - fatal("subclass points to itself " PTR_FORMAT, p2i(sib)); - } - - guarantee(sib->is_klass(), "should be klass"); - guarantee(sib->super() == super, "siblings should have same superklass"); - } - - // Verify implementor fields requires the Compile_lock, - // but this is sometimes called inside a safepoint, so don't verify. + guarantee(sib->is_klass(), "should be klass"); + guarantee(sib->super() == super, "siblings should have same superklass"); } + // Verify implementor fields requires the Compile_lock, but this is sometimes + // called inside a safepoint, so don't verify. + // Verify local interfaces if (local_interfaces()) { Array* local_interfaces = this->local_interfaces(); diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/oops/instanceKlass.hpp --- a/src/hotspot/share/oops/instanceKlass.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/oops/instanceKlass.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -1007,7 +1007,7 @@ #endif // Access to the implementor of an interface. - Klass* implementor(bool log = false) const; + Klass* implementor() const; void set_implementor(Klass* k); int nof_implementors() const; void add_implementor(Klass* k); // k is a new class that implements this interface diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/oops/klass.cpp --- a/src/hotspot/share/oops/klass.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/oops/klass.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -117,7 +117,7 @@ Klass *r = this; while( r->is_abstract() ) { // Receiver is abstract? Klass *s = r->subklass(); // Check for exactly 1 subklass - if (s == NULL || s->next_sibling() != NULL) // Oops; wrong count; give up + if( !s || s->next_sibling() ) // Oops; wrong count; give up return this; // Return 'this' as a no-progress flag r = s; // Loop till find concrete class } @@ -358,49 +358,11 @@ } -// superklass links InstanceKlass* Klass::superklass() const { assert(super() == NULL || super()->is_instance_klass(), "must be instance klass"); return _super == NULL ? NULL : InstanceKlass::cast(_super); } -// subklass links. Used by the compiler (and vtable initialization) -// May be cleaned concurrently, so must use the Compile_lock. -// The log parameter is for clean_weak_klass_links to report unlinked classes. -Klass* Klass::subklass(bool log) const { - assert_locked_or_safepoint(Compile_lock); - for (Klass* chain = _subklass; chain != NULL; - chain = chain->_next_sibling) { - if (chain->is_loader_alive()) { - return chain; - } else if (log) { - if (log_is_enabled(Trace, class, unload)) { - ResourceMark rm; - log_trace(class, unload)("unlinking class (subclass): %s", chain->external_name()); - } - } - } - return NULL; -} - -Klass* Klass::next_sibling(bool log) const { - assert_locked_or_safepoint(Compile_lock); - for (Klass* chain = _next_sibling; chain != NULL; - chain = chain->_next_sibling) { - // Only return alive klass, there may be stale klass - // in this chain if cleaned concurrently. - if (chain->is_loader_alive()) { - return chain; - } else if (log) { - if (log_is_enabled(Trace, class, unload)) { - ResourceMark rm; - log_trace(class, unload)("unlinking class (sibling): %s", chain->external_name()); - } - } - } - return NULL; -} - void Klass::set_subklass(Klass* s) { assert(s != this, "sanity check"); _subklass = s; @@ -412,7 +374,6 @@ } void Klass::append_to_sibling_list() { - assert_locked_or_safepoint(Compile_lock); debug_only(verify();) // add ourselves to superklass' subklass list InstanceKlass* super = superklass(); @@ -420,7 +381,6 @@ assert((!super->is_interface() // interfaces cannot be supers && (super->superklass() == NULL || !is_interface())), "an interface can only be a subklass of Object"); - Klass* prev_first_subklass = super->subklass(); if (prev_first_subklass != NULL) { // set our sibling to be the superklass' previous first subklass @@ -436,7 +396,6 @@ } void Klass::clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses) { - assert_locked_or_safepoint(Compile_lock); if (!ClassUnloading || !unloading_occurred) { return; } @@ -451,14 +410,30 @@ assert(current->is_loader_alive(), "just checking, this should be live"); // Find and set the first alive subklass - Klass* sub = current->subklass(true); + Klass* sub = current->subklass(); + while (sub != NULL && !sub->is_loader_alive()) { +#ifndef PRODUCT + if (log_is_enabled(Trace, class, unload)) { + ResourceMark rm; + log_trace(class, unload)("unlinking class (subclass): %s", sub->external_name()); + } +#endif + sub = sub->next_sibling(); + } current->set_subklass(sub); if (sub != NULL) { stack.push(sub); } // Find and set the first alive sibling - Klass* sibling = current->next_sibling(true); + Klass* sibling = current->next_sibling(); + while (sibling != NULL && !sibling->is_loader_alive()) { + if (log_is_enabled(Trace, class, unload)) { + ResourceMark rm; + log_trace(class, unload)("[Unlinking class (sibling) %s]", sibling->external_name()); + } + sibling = sibling->next_sibling(); + } current->set_next_sibling(sibling); if (sibling != NULL) { stack.push(sibling); diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/oops/klass.hpp --- a/src/hotspot/share/oops/klass.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/oops/klass.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -284,9 +284,8 @@ // Use InstanceKlass::contains_field_offset to classify field offsets. // sub/superklass links - Klass* subklass(bool log = false) const; - Klass* next_sibling(bool log = false) const; - + Klass* subklass() const { return _subklass; } + Klass* next_sibling() const { return _next_sibling; } InstanceKlass* superklass() const; void append_to_sibling_list(); // add newly created receiver to superklass' subklass list diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/prims/jvmtiExport.hpp --- a/src/hotspot/share/prims/jvmtiExport.hpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/prims/jvmtiExport.hpp Wed Oct 31 16:27:31 2018 -0400 @@ -328,8 +328,8 @@ JVMTI_ONLY(return _should_post_class_file_load_hook); NOT_JVMTI(return false;) } - static bool is_early_phase(); - static bool has_early_class_hook_env(); + static bool is_early_phase() NOT_JVMTI_RETURN_(false); + static bool has_early_class_hook_env() NOT_JVMTI_RETURN_(false); // Return true if the class was modified by the hook. static bool post_class_file_load_hook(Symbol* h_name, Handle class_loader, Handle h_protection_domain, diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/runtime/mutex.cpp --- a/src/hotspot/share/runtime/mutex.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/runtime/mutex.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -876,7 +876,7 @@ #endif // CHECK_UNHANDLED_OOPS debug_only(check_prelock_state(Self, StrictSafepointChecks)); - assert(_owner != Self, "this lock %s is already held by this thread", name()); + assert(_owner != Self, "invariant"); assert(_OnDeck != Self->_MutexEvent, "invariant"); if (TryFast()) { diff -r c42cd17e8e64 -r e38473506688 src/hotspot/share/utilities/vmError.cpp --- a/src/hotspot/share/utilities/vmError.cpp Wed Oct 31 16:27:01 2018 -0400 +++ b/src/hotspot/share/utilities/vmError.cpp Wed Oct 31 16:27:31 2018 -0400 @@ -1467,8 +1467,6 @@ log.set_fd(-1); } - // Error handling generates replay data without the compile lock. - NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true)); static bool skip_replay = ReplayCompiles; // Do not overwrite file during replay if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) { skip_replay = true; diff -r c42cd17e8e64 -r e38473506688 src/java.base/aix/native/libjli/java_md_aix.c --- a/src/java.base/aix/native/libjli/java_md_aix.c Wed Oct 31 16:27:01 2018 -0400 +++ b/src/java.base/aix/native/libjli/java_md_aix.c Wed Oct 31 16:27:31 2018 -0400 @@ -1,10 +1,12 @@ /* - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2016, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * 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 diff -r c42cd17e8e64 -r e38473506688 src/java.base/aix/native/libjli/java_md_aix.h --- a/src/java.base/aix/native/libjli/java_md_aix.h Wed Oct 31 16:27:01 2018 -0400 +++ b/src/java.base/aix/native/libjli/java_md_aix.h Wed Oct 31 16:27:31 2018 -0400 @@ -1,10 +1,12 @@ /* - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2016, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * 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 diff -r c42cd17e8e64 -r e38473506688 src/java.desktop/aix/native/libawt/porting_aix.c --- a/src/java.desktop/aix/native/libawt/porting_aix.c Wed Oct 31 16:27:01 2018 -0400 +++ b/src/java.desktop/aix/native/libawt/porting_aix.c Wed Oct 31 16:27:31 2018 -0400 @@ -1,10 +1,12 @@ /* - * Copyright (c) 2012, 2013 SAP SE. All rights reserved. + * Copyright (c) 2012, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * 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 diff -r c42cd17e8e64 -r e38473506688 src/java.desktop/aix/native/libawt/porting_aix.h --- a/src/java.desktop/aix/native/libawt/porting_aix.h Wed Oct 31 16:27:01 2018 -0400 +++ b/src/java.desktop/aix/native/libawt/porting_aix.h Wed Oct 31 16:27:31 2018 -0400 @@ -1,10 +1,12 @@ /* - * Copyright (c) 2012, 2013 SAP SE. All rights reserved. + * Copyright (c) 2012, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * 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 diff -r c42cd17e8e64 -r e38473506688 test/hotspot/jtreg/runtime/ClassUnload/UnloadInterfaceTest.java --- a/test/hotspot/jtreg/runtime/ClassUnload/UnloadInterfaceTest.java Wed Oct 31 16:27:01 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test UnloadInterfaceTest - * @requires vm.opt.final.ClassUnloading - * @modules java.base/jdk.internal.misc - * @library /runtime/testlibrary /test/lib - * @compile test/Interface.java - * @compile test/ImplementorClass.java - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xlog:class+unload=trace UnloadInterfaceTest - */ -import sun.hotspot.WhiteBox; -import test.Interface; -import java.lang.ClassLoader; - -/** - * Test that verifies that class unloaded removes the implementor from its the interface that it implements - * via logging. - * [1.364s][info][class,unload] unloading class test.ImplementorClass 0x00000008000a2840 - * [1.366s][trace][class,unload] unlinking class (subclass): test.ImplementorClass - * [1.366s][trace][class,unload] unlinking class (implementor): test.ImplementorClass - */ -public class UnloadInterfaceTest { - private static String className = "test.ImplementorClass"; - private static String interfaceName = "test.Interface"; - - static class LoaderToUnload extends ClassLoader { - ClassLoader myParent; - public Class loadClass(String name) throws ClassNotFoundException { - if (name.contains(className)) { - System.out.println("className found " + className); - byte[] data = ClassUnloadCommon.getClassData(name); - return defineClass(name, data, 0, data.length); - } else { - return myParent.loadClass(name); - } - } - public LoaderToUnload(ClassLoader parent) { - super(); - myParent = parent; - } - } - - public static void main(String... args) throws Exception { - run(); - } - - private static void run() throws Exception { - final WhiteBox wb = WhiteBox.getWhiteBox(); - - ClassUnloadCommon.failIf(wb.isClassAlive(className), "is not expected to be alive yet"); - - // Load interface Class with one class loader. - ClassLoader icl = ClassUnloadCommon.newClassLoader(); - Class ic = icl.loadClass(interfaceName); - - ClassLoader cl = new LoaderToUnload(icl); - Class c = cl.loadClass(className); - Object o = c.newInstance(); - - ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here"); - ClassUnloadCommon.failIf(!wb.isClassAlive(interfaceName), "should be live here"); - - cl = null; c = null; o = null; - ClassUnloadCommon.triggerUnloading(); - ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded"); - ClassUnloadCommon.failIf(!wb.isClassAlive(interfaceName), "should be live here"); - System.out.println("We still have Interface referenced" + ic); - } -} - diff -r c42cd17e8e64 -r e38473506688 test/hotspot/jtreg/runtime/ClassUnload/test/ImplementorClass.java --- a/test/hotspot/jtreg/runtime/ClassUnload/test/ImplementorClass.java Wed Oct 31 16:27:01 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package test; - -public class ImplementorClass implements Interface { - public void foo() { System.out.println("foo implemented!"); } -} diff -r c42cd17e8e64 -r e38473506688 test/hotspot/jtreg/runtime/ClassUnload/test/Interface.java --- a/test/hotspot/jtreg/runtime/ClassUnload/test/Interface.java Wed Oct 31 16:27:01 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package test; - -public interface Interface { - public void foo(); -} diff -r c42cd17e8e64 -r e38473506688 test/hotspot/jtreg/runtime/testlibrary/ClassUnloadCommon.java --- a/test/hotspot/jtreg/runtime/testlibrary/ClassUnloadCommon.java Wed Oct 31 16:27:01 2018 -0400 +++ b/test/hotspot/jtreg/runtime/testlibrary/ClassUnloadCommon.java Wed Oct 31 16:27:31 2018 -0400 @@ -27,10 +27,7 @@ * for an example. */ - import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -107,22 +104,4 @@ throw new RuntimeException(e); } } - - // Get data for pre-compiled class file to load. - public static byte[] getClassData(String name) { - try { - String TempName = name.replaceAll("\\.", "/"); - String currentDir = System.getProperty("test.classes"); - String filename = currentDir + File.separator + TempName + ".class"; - System.out.println("filename is " + filename); - FileInputStream fis = new FileInputStream(filename); - byte[] b = new byte[5000]; - int cnt = fis.read(b, 0, 5000); - byte[] c = new byte[cnt]; - for (int i=0; i