diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/code/compiledMethod.cpp --- a/src/hotspot/share/code/compiledMethod.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/code/compiledMethod.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -415,20 +415,22 @@ #ifdef ASSERT // Check class_loader is alive for this bit of metadata. -static void check_class(Metadata* md) { - Klass* klass = NULL; - if (md->is_klass()) { - klass = ((Klass*)md); - } else if (md->is_method()) { - klass = ((Method*)md)->method_holder(); - } else if (md->is_methodData()) { - klass = ((MethodData*)md)->method()->method_holder(); - } else { - md->print(); - ShouldNotReachHere(); - } - assert(klass->is_loader_alive(), "must be alive"); -} +class CheckClass : public MetadataClosure { + void do_metadata(Metadata* md) { + Klass* klass = NULL; + if (md->is_klass()) { + klass = ((Klass*)md); + } else if (md->is_method()) { + klass = ((Method*)md)->method_holder(); + } else if (md->is_methodData()) { + klass = ((MethodData*)md)->method()->method_holder(); + } else { + md->print(); + ShouldNotReachHere(); + } + assert(klass->is_loader_alive(), "must be alive"); + } +}; #endif // ASSERT @@ -550,8 +552,11 @@ // All static stubs need to be cleaned. clean_ic_stubs(); +#ifdef ASSERT // Check that the metadata embedded in the nmethod is alive - DEBUG_ONLY(metadata_do(check_class)); + CheckClass check_class; + metadata_do(&check_class); +#endif return true; } @@ -628,3 +633,35 @@ os::is_readable_pointer(method->constants()) && os::is_readable_pointer(method->signature()); } + +class HasEvolDependency : public MetadataClosure { + bool _has_evol_dependency; + public: + HasEvolDependency() : _has_evol_dependency(false) {} + void do_metadata(Metadata* md) { + if (md->is_method()) { + Method* method = (Method*)md; + if (method->is_old()) { + _has_evol_dependency = true; + } + } + } + bool has_evol_dependency() const { return _has_evol_dependency; } +}; + +bool CompiledMethod::has_evol_metadata() { + // Check the metadata in relocIter and CompiledIC and also deoptimize + // any nmethod that has reference to old methods. + HasEvolDependency check_evol; + metadata_do(&check_evol); + if (check_evol.has_evol_dependency() && log_is_enabled(Debug, redefine, class, nmethod)) { + ResourceMark rm; + log_debug(redefine, class, nmethod) + ("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on in nmethod metadata", + _method->method_holder()->external_name(), + _method->name()->as_C_string(), + _method->signature()->as_C_string(), + compile_id()); + } + return check_evol.has_evol_dependency(); +}