# HG changeset patch # User coleenp # Date 1552680018 14400 # Node ID 5529640c5f6700bd49bd5036a1417e53731f7721 # Parent c61f09122d3b9c8d491701647c2e8512c70cd393 8220512: Deoptimize redefinition functions that have dirty ICs Summary: Walk ICs to determine whether nmethods are dependent on redefined classes. Reviewed-by: sspitsyn, eosterlund diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/aot/aotCodeHeap.cpp --- a/src/hotspot/share/aot/aotCodeHeap.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/aot/aotCodeHeap.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -931,13 +931,13 @@ // Scan only klasses_got cells which should have only Klass*, // metadata_got cells are scanned only for alive AOT methods // by AOTCompiledMethod::metadata_do(). -void AOTCodeHeap::got_metadata_do(void f(Metadata*)) { +void AOTCodeHeap::got_metadata_do(MetadataClosure* f) { for (int i = 1; i < _klasses_got_size; i++) { Metadata** p = &_klasses_got[i]; Metadata* md = *p; if (md == NULL) continue; // skip non-oops if (Metaspace::contains(md)) { - f(md); + f->do_metadata(md); } else { intptr_t meta = (intptr_t)md; fatal("Invalid value in _klasses_got[%d] = " INTPTR_FORMAT, i, meta); @@ -969,7 +969,7 @@ } #endif -void AOTCodeHeap::metadata_do(void f(Metadata*)) { +void AOTCodeHeap::metadata_do(MetadataClosure* f) { for (int index = 0; index < _method_count; index++) { if (_code_to_aot[index]._state != in_use) { continue; // Skip uninitialized entries. diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/aot/aotCodeHeap.hpp --- a/src/hotspot/share/aot/aotCodeHeap.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/aot/aotCodeHeap.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -252,8 +252,8 @@ void oops_do(OopClosure* f); - void metadata_do(void f(Metadata*)); - void got_metadata_do(void f(Metadata*)); + void metadata_do(MetadataClosure* f); + void got_metadata_do(MetadataClosure* f); #ifdef ASSERT bool got_contains(Metadata **p) { diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/aot/aotCompiledMethod.cpp --- a/src/hotspot/share/aot/aotCompiledMethod.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/aot/aotCompiledMethod.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -246,7 +246,7 @@ // Iterate over metadata calling this function. Used by RedefineClasses // Copied from nmethod::metadata_do -void AOTCompiledMethod::metadata_do(void f(Metadata*)) { +void AOTCompiledMethod::metadata_do(MetadataClosure* f) { address low_boundary = verified_entry_point(); { // Visit all immediate references that are embedded in the instruction stream. @@ -262,7 +262,7 @@ "metadata must be found in exactly one place"); if (r->metadata_is_immediate() && r->metadata_value() != NULL) { Metadata* md = r->metadata_value(); - if (md != _method) f(md); + if (md != _method) f->do_metadata(md); } } else if (iter.type() == relocInfo::virtual_call_type) { ResourceMark rm; @@ -270,13 +270,13 @@ CompiledIC *ic = CompiledIC_at(&iter); if (ic->is_icholder_call()) { CompiledICHolder* cichk = ic->cached_icholder(); - f(cichk->holder_metadata()); - f(cichk->holder_klass()); + f->do_metadata(cichk->holder_metadata()); + f->do_metadata(cichk->holder_klass()); } else { // Get Klass* or NULL (if value is -1) from GOT cell of virtual call PLT stub. Metadata* ic_oop = ic->cached_metadata(); if (ic_oop != NULL) { - f(ic_oop); + f->do_metadata(ic_oop); } } } else if (iter.type() == relocInfo::static_call_type || @@ -284,7 +284,7 @@ // Check Method* in AOT c2i stub for other calls. Metadata* meta = (Metadata*)nativeLoadGot_at(nativePltCall_at(iter.addr())->plt_c2i_stub())->data(); if (meta != NULL) { - f(meta); + f->do_metadata(meta); } } } @@ -302,11 +302,11 @@ continue; } assert(Metaspace::contains(m), ""); - f(m); + f->do_metadata(m); } // Visit metadata not embedded in the other places. - if (_method != NULL) f(_method); + if (_method != NULL) f->do_metadata(_method); } void AOTCompiledMethod::print() const { diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/aot/aotCompiledMethod.hpp --- a/src/hotspot/share/aot/aotCompiledMethod.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/aot/aotCompiledMethod.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -241,7 +241,7 @@ address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; } - virtual void metadata_do(void f(Metadata*)); + virtual void metadata_do(MetadataClosure* f); bool metadata_got_contains(Metadata **p) { return p >= &_metadata_got[0] && p < &_metadata_got[_metadata_size]; diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/aot/aotLoader.cpp --- a/src/hotspot/share/aot/aotLoader.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/aot/aotLoader.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -78,7 +78,7 @@ } } -void AOTLoader::metadata_do(void f(Metadata*)) { +void AOTLoader::metadata_do(MetadataClosure* f) { if (UseAOT) { FOR_ALL_AOT_HEAPS(heap) { (*heap)->metadata_do(f); diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/aot/aotLoader.hpp --- a/src/hotspot/share/aot/aotLoader.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/aot/aotLoader.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -62,7 +62,7 @@ static void load_for_klass(InstanceKlass* ik, Thread* thread) NOT_AOT_RETURN; static uint64_t get_saved_fingerprint(InstanceKlass* ik) NOT_AOT({ return 0; }); static void oops_do(OopClosure* f) NOT_AOT_RETURN; - static void metadata_do(void f(Metadata*)) NOT_AOT_RETURN; + static void metadata_do(MetadataClosure* f) NOT_AOT_RETURN; static void mark_evol_dependent_methods(InstanceKlass* dependee) NOT_AOT_RETURN; NOT_PRODUCT( static void print_statistics() NOT_AOT_RETURN; ) diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/ci/ciEnv.hpp --- a/src/hotspot/share/ci/ciEnv.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/ci/ciEnv.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -465,7 +465,7 @@ void record_out_of_memory_failure(); // RedefineClasses support - void metadata_do(void f(Metadata*)) { _factory->metadata_do(f); } + void metadata_do(MetadataClosure* f) { _factory->metadata_do(f); } // Dump the compilation replay data for the ciEnv to the stream. void dump_replay_data(int compile_id); diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/ci/ciObjectFactory.cpp --- a/src/hotspot/share/ci/ciObjectFactory.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/ci/ciObjectFactory.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -689,11 +689,11 @@ // ------------------------------------------------------------------ // ciObjectFactory::metadata_do -void ciObjectFactory::metadata_do(void f(Metadata*)) { +void ciObjectFactory::metadata_do(MetadataClosure* f) { if (_ci_metadata == NULL) return; for (int j = 0; j< _ci_metadata->length(); j++) { Metadata* o = _ci_metadata->at(j)->constant_encoding(); - f(o); + f->do_metadata(o); } } diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/ci/ciObjectFactory.hpp --- a/src/hotspot/share/ci/ciObjectFactory.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/ci/ciObjectFactory.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -140,7 +140,7 @@ GrowableArray* get_ci_metadata() const { return _ci_metadata; } // RedefineClasses support - void metadata_do(void f(Metadata*)); + void metadata_do(MetadataClosure* f); void print_contents(); void print(); diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/classfile/metadataOnStackMark.cpp --- a/src/hotspot/share/classfile/metadataOnStackMark.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/classfile/metadataOnStackMark.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -42,6 +42,10 @@ MetadataOnStackBuffer* MetadataOnStackMark::_current_buffer = NULL; NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;) +class MetadataOnStackClosure : public MetadataClosure { + void do_metadata(Metadata* m) { Metadata::mark_on_stack(m); } +}; + // Walk metadata on the stack and mark it so that redefinition doesn't delete // it. Class unloading only deletes in-error class files, methods created by // the relocator and dummy constant pools. None of these appear anywhere except @@ -55,8 +59,9 @@ Threads::metadata_handles_do(Metadata::mark_on_stack); if (redefinition_walk) { - Threads::metadata_do(Metadata::mark_on_stack); - CodeCache::metadata_do(Metadata::mark_on_stack); + MetadataOnStackClosure md_on_stack; + Threads::metadata_do(&md_on_stack); + CodeCache::metadata_do(&md_on_stack); CompileBroker::mark_on_stack(); JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack); ThreadService::metadata_do(Metadata::mark_on_stack); diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/code/codeCache.cpp --- a/src/hotspot/share/code/codeCache.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/code/codeCache.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -667,7 +667,7 @@ } } -void CodeCache::metadata_do(void f(Metadata* m)) { +void CodeCache::metadata_do(MetadataClosure* f) { assert_locked_or_safepoint(CodeCache_lock); NMethodIterator iter(NMethodIterator::only_alive_and_not_unloading); while(iter.next()) { @@ -1061,13 +1061,14 @@ // ...Already marked in the previous pass; count it here. // Also counts AOT compiled methods, already marked. number_of_marked_CodeBlobs++; - } else if (nm->is_evol_dependent()) { + } else if (nm->has_evol_metadata()) { ResourceMark rm; nm->mark_for_deoptimization(); number_of_marked_CodeBlobs++; - } else { - // flush caches in case they refer to a redefined Method* - nm->clear_inline_caches(); + } else { + // Inline caches that refer to an nmethod are deoptimized already, because + // the Method* is walked in the metadata section of the nmethod. + assert(!nm->is_evol_dependent(), "should no longer be necessary"); } } diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/code/codeCache.hpp --- a/src/hotspot/share/code/codeCache.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/code/codeCache.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -147,7 +147,7 @@ static void blobs_do(void f(CodeBlob* cb)); // iterates over all CodeBlobs static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs static void nmethods_do(void f(nmethod* nm)); // iterates over all nmethods - static void metadata_do(void f(Metadata* m)); // iterates over metadata in alive nmethods + static void metadata_do(MetadataClosure* f); // iterates over metadata in alive nmethods // Lookup static CodeBlob* find_blob(void* start); // Returns the CodeBlob containing the given address 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(); +} diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/code/compiledMethod.hpp --- a/src/hotspot/share/code/compiledMethod.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/code/compiledMethod.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -38,6 +38,7 @@ class NativeCallWrapper; class ScopeDesc; class CompiledIC; +class MetadataClosure; // This class is used internally by nmethods, to cache // exception/pc/handler information. @@ -368,6 +369,8 @@ void verify_oop_relocations(); virtual bool is_evol_dependent() = 0; + bool has_evol_metadata(); + // Fast breakpoint support. Tells if this compiled method is // dependent on the given method. Returns true if this nmethod // corresponds to the given method as well. @@ -384,7 +387,7 @@ Method* attached_method(address call_pc); Method* attached_method_before_pc(address pc); - virtual void metadata_do(void f(Metadata*)) = 0; + virtual void metadata_do(MetadataClosure* f) = 0; // GC support protected: diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/code/nmethod.cpp --- a/src/hotspot/share/code/nmethod.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/code/nmethod.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -1499,7 +1499,7 @@ } // Iterate over metadata calling this function. Used by RedefineClasses -void nmethod::metadata_do(void f(Metadata*)) { +void nmethod::metadata_do(MetadataClosure* f) { { // Visit all immediate references that are embedded in the instruction stream. RelocIterator iter(this, oops_reloc_begin()); @@ -1514,7 +1514,7 @@ "metadata must be found in exactly one place"); if (r->metadata_is_immediate() && r->metadata_value() != NULL) { Metadata* md = r->metadata_value(); - if (md != _method) f(md); + if (md != _method) f->do_metadata(md); } } else if (iter.type() == relocInfo::virtual_call_type) { // Check compiledIC holders associated with this nmethod @@ -1522,12 +1522,12 @@ CompiledIC *ic = CompiledIC_at(&iter); if (ic->is_icholder_call()) { CompiledICHolder* cichk = ic->cached_icholder(); - f(cichk->holder_metadata()); - f(cichk->holder_klass()); + f->do_metadata(cichk->holder_metadata()); + f->do_metadata(cichk->holder_klass()); } else { Metadata* ic_oop = ic->cached_metadata(); if (ic_oop != NULL) { - f(ic_oop); + f->do_metadata(ic_oop); } } } @@ -1538,11 +1538,11 @@ for (Metadata** p = metadata_begin(); p < metadata_end(); p++) { if (*p == Universe::non_oop_word() || *p == NULL) continue; // skip non-oops Metadata* md = *p; - f(md); + f->do_metadata(md); } // Visit metadata not embedded in the other places. - if (_method != NULL) f(_method); + if (_method != NULL) f->do_metadata(_method); } // The _is_unloading_state encodes a tuple comprising the unloading cycle diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/code/nmethod.hpp --- a/src/hotspot/share/code/nmethod.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/code/nmethod.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -591,7 +591,7 @@ static int osr_entry_point_offset() { return offset_of(nmethod, _osr_entry_point); } static int state_offset() { return offset_of(nmethod, _state); } - virtual void metadata_do(void f(Metadata*)); + virtual void metadata_do(MetadataClosure* f); NativeCallWrapper* call_wrapper_at(address call) const; NativeCallWrapper* call_wrapper_before(address return_pc) const; diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/compiler/compileTask.cpp --- a/src/hotspot/share/compiler/compileTask.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/compiler/compileTask.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -197,13 +197,13 @@ } // RedefineClasses support -void CompileTask::metadata_do(void f(Metadata*)) { +void CompileTask::metadata_do(MetadataClosure* f) { if (is_unloaded()) { return; } - f(method()); + f->do_metadata(method()); if (hot_method() != NULL && hot_method() != method()) { - f(hot_method()); + f->do_metadata(hot_method()); } } diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/compiler/compileTask.hpp --- a/src/hotspot/share/compiler/compileTask.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/compiler/compileTask.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -177,7 +177,7 @@ bool is_unloaded() const; // RedefineClasses support - void metadata_do(void f(Metadata*)); + void metadata_do(MetadataClosure* f); void mark_on_stack(); private: diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/memory/iterator.hpp --- a/src/hotspot/share/memory/iterator.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/memory/iterator.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -36,6 +36,7 @@ class KlassClosure; class ClassLoaderData; class Symbol; +class Metadata; // The following classes are C++ `closures` for iterating over objects, roots and spaces @@ -124,6 +125,11 @@ virtual void do_cld(ClassLoaderData* cld) = 0; }; +class MetadataClosure : public Closure { + public: + virtual void do_metadata(Metadata* md) = 0; +}; + class CLDToOopClosure : public CLDClosure { OopClosure* _oop_closure; diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/runtime/frame.cpp --- a/src/hotspot/share/runtime/frame.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/runtime/frame.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -1115,13 +1115,13 @@ } -// call f() on the interpreted Method*s in the stack. -// Have to walk the entire code cache for the compiled frames Yuck. -void frame::metadata_do(void f(Metadata*)) { +// Call f closure on the interpreted Method*s in the stack. +void frame::metadata_do(MetadataClosure* f) { + ResourceMark rm; if (is_interpreted_frame()) { Method* m = this->interpreter_frame_method(); assert(m != NULL, "expecting a method in this frame"); - f(m); + f->do_metadata(m); } } diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/runtime/frame.hpp --- a/src/hotspot/share/runtime/frame.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/runtime/frame.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -378,7 +378,7 @@ void nmethods_do(CodeBlobClosure* cf); // RedefineClasses support for finding live interpreted methods on the stack - void metadata_do(void f(Metadata*)); + void metadata_do(MetadataClosure* f); // Verification void verify(const RegisterMap* map); diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/runtime/thread.cpp Fri Mar 15 16:00:18 2019 -0400 @@ -2960,7 +2960,7 @@ } } -void JavaThread::metadata_do(void f(Metadata*)) { +void JavaThread::metadata_do(MetadataClosure* f) { if (has_last_Java_frame()) { // Traverse the execution stack to call f() on the methods in the stack for (StackFrameStream fst(this); !fst.is_done(); fst.next()) { @@ -4574,7 +4574,7 @@ } } -void Threads::metadata_do(void f(Metadata*)) { +void Threads::metadata_do(MetadataClosure* f) { ALL_JAVA_THREADS(p) { p->metadata_do(f); } diff -r c61f09122d3b -r 5529640c5f67 src/hotspot/share/runtime/thread.hpp --- a/src/hotspot/share/runtime/thread.hpp Fri Mar 15 18:59:21 2019 +0100 +++ b/src/hotspot/share/runtime/thread.hpp Fri Mar 15 16:00:18 2019 -0400 @@ -1866,7 +1866,7 @@ virtual void nmethods_do(CodeBlobClosure* cf); // RedefineClasses Support - void metadata_do(void f(Metadata*)); + void metadata_do(MetadataClosure* f); // Misc. operations char* name() const { return (char*)get_thread_name(); } @@ -2281,7 +2281,7 @@ static void nmethods_do(CodeBlobClosure* cf); // RedefineClasses support - static void metadata_do(void f(Metadata*)); + static void metadata_do(MetadataClosure* f); static void metadata_handles_do(void f(Metadata*)); #ifdef ASSERT