blob: 8cefa287c8adefa433c2536eabbcaeb987967b0a [file] [edit]
/*
* Copyright (c) 2021, 2024, 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.
*
*/
#ifndef SHARE_JFR_SUPPORT_JFRSYMBOLTABLE_HPP
#define SHARE_JFR_SUPPORT_JFRSYMBOLTABLE_HPP
#include "jfr/utilities/jfrHashtable.hpp"
#include "jfr/utilities/jfrTypes.hpp"
template <typename T, typename IdType>
class ListEntry : public JfrHashtableEntry<T, IdType> {
public:
ListEntry(uintptr_t hash, const T& data) : JfrHashtableEntry<T, IdType>(hash, data),
_list_next(nullptr), _serialized(false), _unloading(false), _leakp(false) {}
const ListEntry<T, IdType>* list_next() const { return _list_next; }
void reset() const {
_list_next = nullptr; _serialized = false; _unloading = false; _leakp = false;
}
void set_list_next(const ListEntry<T, IdType>* next) const { _list_next = next; }
bool is_serialized() const { return _serialized; }
void set_serialized() const { _serialized = true; }
bool is_unloading() const { return _unloading; }
void set_unloading() const { _unloading = true; }
bool is_leakp() const { return _leakp; }
void set_leakp() const { _leakp = true; }
private:
mutable const ListEntry<T, IdType>* _list_next;
mutable bool _serialized;
mutable bool _unloading;
mutable bool _leakp;
};
/*
* This table maps an oop/Symbol* or a char* to the Jfr type 'Symbol'.
*
* It provides an interface over the corresponding constant pool (TYPE_SYMBOL),
* which is represented in the binary format as a sequence of checkpoint events.
* The returned id can be used as a foreign key, but please note that the id is
* epoch-relative, and is therefore only valid in the current epoch / chunk.
* The table is cleared as part of rotation.
*
* Caller must ensure mutual exclusion by means of the ClassLoaderDataGraph_lock or by safepointing.
*/
class JfrSymbolTable : public JfrCHeapObj {
template <typename, typename, template<typename, typename> class, typename, size_t>
friend class HashTableHost;
typedef HashTableHost<const Symbol*, traceid, ListEntry, JfrSymbolTable> Symbols;
typedef HashTableHost<const char*, traceid, ListEntry, JfrSymbolTable> Strings;
friend class JfrArtifactSet;
public:
typedef Symbols::HashEntry SymbolEntry;
typedef Strings::HashEntry StringEntry;
static traceid add(const Symbol* sym);
static traceid add(const char* str);
private:
Symbols* _symbols;
Strings* _strings;
const SymbolEntry* _symbol_list;
const StringEntry* _string_list;
const Symbol* _symbol_query;
const char* _string_query;
traceid _id_counter;
bool _class_unload;
JfrSymbolTable();
~JfrSymbolTable();
static JfrSymbolTable* create();
static void destroy();
void clear();
void increment_checkpoint_id();
void set_class_unload(bool class_unload);
traceid mark(uintptr_t hash, const Symbol* sym, bool leakp);
traceid mark(const Klass* k, bool leakp);
traceid mark(const Symbol* sym, bool leakp = false);
traceid mark(const char* str, bool leakp = false);
traceid mark(uintptr_t hash, const char* str, bool leakp);
traceid mark_hidden_klass_name(const Klass* k, bool leakp);
traceid bootstrap_name(bool leakp);
bool has_entries() const { return has_symbol_entries() || has_string_entries(); }
bool has_symbol_entries() const { return _symbol_list != nullptr; }
bool has_string_entries() const { return _string_list != nullptr; }
// hashtable(s) callbacks
void on_link(const SymbolEntry* entry);
bool on_equals(uintptr_t hash, const SymbolEntry* entry);
void on_unlink(const SymbolEntry* entry);
void on_link(const StringEntry* entry);
bool on_equals(uintptr_t hash, const StringEntry* entry);
void on_unlink(const StringEntry* entry);
template <typename T>
static traceid add_impl(const T* sym);
template <typename T>
void assign_id(T* entry);
template <typename Functor>
void iterate_symbols(Functor& functor) {
iterate(functor, _symbol_list);
}
template <typename Functor>
void iterate_strings(Functor& functor) {
iterate(functor, _string_list);
}
template <typename Functor, typename T>
void iterate(Functor& functor, const T* list) {
const T* symbol = list;
while (symbol != nullptr) {
const T* next = symbol->list_next();
functor(symbol);
symbol = next;
}
}
};
#endif // SHARE_JFR_SUPPORT_JFRSYMBOLTABLE_HPP