--- old/src/hotspot/share/code/codeBlob.cpp Thu Mar 29 19:50:50 2018 +++ new/src/hotspot/share/code/codeBlob.cpp Thu Mar 29 19:50:50 2018 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -294,7 +294,29 @@ return blob; } +VtableBlob::VtableBlob(const char* name, int size) : + BufferBlob(name, size) { +} +VtableBlob* VtableBlob::create(const char* name, int buffer_size) { + ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock + + VtableBlob* blob = NULL; + unsigned int size = sizeof(VtableBlob); + // align the size to CodeEntryAlignment + size = align_code_offset(size); + size += align_up(buffer_size, oopSize); + assert(name != NULL, "must provide a name"); + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + blob = new (size) VtableBlob(name, size); + } + // Track memory usage statistic after releasing CodeCache_lock + MemoryService::track_code_cache_memory_usage(); + + return blob; +} + //---------------------------------------------------------------------------------------------------- // Implementation of MethodHandlesAdapterBlob --- old/src/hotspot/share/code/codeBlob.hpp Thu Mar 29 19:50:52 2018 +++ new/src/hotspot/share/code/codeBlob.hpp Thu Mar 29 19:50:51 2018 @@ -132,6 +132,7 @@ virtual bool is_exception_stub() const { return false; } virtual bool is_safepoint_stub() const { return false; } virtual bool is_adapter_blob() const { return false; } + virtual bool is_vtable_blob() const { return false; } virtual bool is_method_handles_adapter_blob() const { return false; } virtual bool is_aot() const { return false; } virtual bool is_compiled() const { return false; } @@ -380,6 +381,7 @@ class BufferBlob: public RuntimeBlob { friend class VMStructs; friend class AdapterBlob; + friend class VtableBlob; friend class MethodHandlesAdapterBlob; friend class WhiteBox; @@ -425,7 +427,19 @@ virtual bool is_adapter_blob() const { return true; } }; +//--------------------------------------------------------------------------------------------------- +class VtableBlob: public BufferBlob { +private: + VtableBlob(const char*, int); +public: + // Creation + static VtableBlob* create(const char* name, int buffer_size); + + // Typing + virtual bool is_vtable_blob() const { return true; } +}; + //---------------------------------------------------------------------------------------------------- // MethodHandlesAdapterBlob: used to hold MethodHandles adapters --- old/src/hotspot/share/code/compiledIC.cpp Thu Mar 29 19:50:53 2018 +++ new/src/hotspot/share/code/compiledIC.cpp Thu Mar 29 19:50:53 2018 @@ -235,7 +235,7 @@ assert(k->verify_itable_index(itable_index), "sanity check"); #endif //ASSERT CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(), - call_info->resolved_klass()); + call_info->resolved_klass(), false); holder->claim(); InlineCacheBuffer::create_transition_stub(this, holder, entry); } else { @@ -525,9 +525,11 @@ return true; } // itable stubs also use CompiledICHolder - if (VtableStubs::is_entry_point(entry) && VtableStubs::stub_containing(entry)->is_itable_stub()) { - return true; + if (cb != NULL && cb->is_vtable_blob()) { + VtableStub* s = VtableStubs::entry_point(entry); + return (s != NULL) && s->is_itable_stub(); } + return false; } --- old/src/hotspot/share/code/vtableStubs.cpp Thu Mar 29 19:50:55 2018 +++ new/src/hotspot/share/code/vtableStubs.cpp Thu Mar 29 19:50:54 2018 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -60,7 +60,7 @@ // There is a dependency on the name of the blob in src/share/vm/prims/jvmtiCodeBlobEvents.cpp // If changing the name, update the other file accordingly. - BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); + VtableBlob* blob = VtableBlob::create("vtable chunks", bytes); if (blob == NULL) { return NULL; } @@ -177,6 +177,17 @@ return s == stub; } +VtableStub* VtableStubs::entry_point(address pc) { + MutexLocker ml(VtableStubs_lock); + VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); + uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index()); + VtableStub* s; + for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {} + if (s == stub) { + return s; + } + return NULL; +} bool VtableStubs::contains(address pc) { // simple solution for now - we may want to use --- old/src/hotspot/share/code/vtableStubs.hpp Thu Mar 29 19:50:56 2018 +++ new/src/hotspot/share/code/vtableStubs.hpp Thu Mar 29 19:50:56 2018 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -127,6 +127,7 @@ static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); } static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); } static bool is_entry_point(address pc); // is pc a vtable stub entry point? + static VtableStub* entry_point(address pc); static bool contains(address pc); // is pc within any stub? static VtableStub* stub_containing(address pc); // stub containing pc or NULL static int number_of_vtable_stubs() { return _number_of_vtable_stubs; } --- old/src/hotspot/share/oops/compiledICHolder.cpp Thu Mar 29 19:50:58 2018 +++ new/src/hotspot/share/oops/compiledICHolder.cpp Thu Mar 29 19:50:57 2018 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -24,8 +24,6 @@ #include "precompiled.hpp" #include "oops/compiledICHolder.hpp" -#include "oops/klass.hpp" -#include "oops/method.hpp" #include "runtime/atomic.hpp" volatile int CompiledICHolder::_live_count; @@ -32,8 +30,8 @@ volatile int CompiledICHolder::_live_not_claimed_count; -CompiledICHolder::CompiledICHolder(Metadata* metadata, Klass* klass) - : _holder_metadata(metadata), _holder_klass(klass) { +CompiledICHolder::CompiledICHolder(Metadata* metadata, Klass* klass, bool is_method) + : _holder_metadata(metadata), _holder_klass(klass), is_metadata_method(is_method) { #ifdef ASSERT Atomic::inc(&_live_count); Atomic::inc(&_live_not_claimed_count); @@ -47,22 +45,6 @@ } #endif // ASSERT -bool CompiledICHolder::is_loader_alive(BoolObjectClosure* is_alive) { - if (_holder_metadata->is_method()) { - if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) { - return false; - } - } else if (_holder_metadata->is_klass()) { - if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) { - return false; - } - } - if (!_holder_klass->is_loader_alive(is_alive)) { - return false; - } - return true; -} - // Printing void CompiledICHolder::print_on(outputStream* st) const { --- old/src/hotspot/share/oops/compiledICHolder.hpp Thu Mar 29 19:50:59 2018 +++ new/src/hotspot/share/oops/compiledICHolder.hpp Thu Mar 29 19:50:59 2018 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -27,6 +27,8 @@ #include "oops/oop.hpp" #include "utilities/macros.hpp" +#include "oops/klass.hpp" +#include "oops/method.hpp" // A CompiledICHolder* is a helper object for the inline cache implementation. // It holds: @@ -49,10 +51,11 @@ Metadata* _holder_metadata; Klass* _holder_klass; // to avoid name conflict with oopDesc::_klass CompiledICHolder* _next; + bool is_metadata_method; public: // Constructor - CompiledICHolder(Metadata* metadata, Klass* klass); + CompiledICHolder(Metadata* metadata, Klass* klass, bool is_method = true); ~CompiledICHolder() NOT_DEBUG_RETURN; static int live_count() { return _live_count; } @@ -71,7 +74,21 @@ CompiledICHolder* next() { return _next; } void set_next(CompiledICHolder* n) { _next = n; } - bool is_loader_alive(BoolObjectClosure* is_alive); + inline bool is_loader_alive(BoolObjectClosure* is_alive) { + if (is_metadata_method) { + if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) { + return false; + } + } else { + if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) { + return false; + } + } + if (!_holder_klass->is_loader_alive(is_alive)) { + return false; + } + return true; + } // Verify void verify_on(outputStream* st);