< prev index next >
src/share/vm/jfr/leakprofiler/chains/edgeStore.hpp
Print this page
rev 9055 : 8214542: JFR: Old Object Sample event slow on a deep heap in debug builds
Reviewed-by: egahlin, rwestberg
*** 23,119 ****
*/
#ifndef SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP
#define SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP
- #include "jfr/utilities/jfrHashtable.hpp"
#include "jfr/leakprofiler/chains/edge.hpp"
#include "memory/allocation.hpp"
typedef u8 traceid;
! class RoutableEdge : public Edge {
private:
! mutable const RoutableEdge* _skip_edge;
! mutable size_t _skip_length;
! mutable bool _processed;
public:
! RoutableEdge();
! RoutableEdge(const Edge* parent, const oop* reference);
! RoutableEdge(const Edge& edge);
! RoutableEdge(const RoutableEdge& edge);
! void operator=(const RoutableEdge& edge);
!
! const RoutableEdge* skip_edge() const { return _skip_edge; }
! size_t skip_length() const { return _skip_length; }
!
! bool is_skip_edge() const { return _skip_edge != NULL; }
! bool processed() const { return _processed; }
! bool is_sentinel() const {
! return _skip_edge == NULL && _skip_length == 1;
! }
! void set_skip_edge(const RoutableEdge* edge) const {
! assert(!is_skip_edge(), "invariant");
! assert(edge != this, "invariant");
! _skip_edge = edge;
! }
! void set_skip_length(size_t length) const {
! _skip_length = length;
! }
!
! void set_processed() const {
! assert(!_processed, "invariant");
! _processed = true;
! }
! // true navigation according to physical tree representation
! const RoutableEdge* physical_parent() const {
! return static_cast<const RoutableEdge*>(parent());
! }
! // logical navigation taking skip levels into account
! const RoutableEdge* logical_parent() const {
! return is_skip_edge() ? skip_edge() : physical_parent();
}
-
- size_t logical_distance_to_root() const;
};
class EdgeStore : public CHeapObj<mtTracing> {
! typedef HashTableHost<RoutableEdge, traceid, Entry, EdgeStore> EdgeHashTable;
typedef EdgeHashTable::HashEntry EdgeEntry;
template <typename,
typename,
template<typename, typename> class,
typename,
size_t>
friend class HashTableHost;
private:
static traceid _edge_id_counter;
EdgeHashTable* _edges;
// Hash table callbacks
void assign_id(EdgeEntry* entry);
bool equals(const Edge& query, uintptr_t hash, const EdgeEntry* entry);
! const Edge* get_edge(const Edge* edge) const;
! const Edge* put(const Edge* edge);
public:
EdgeStore();
~EdgeStore();
- void add_chain(const Edge* chain, size_t length);
bool is_empty() const;
- size_t number_of_entries() const;
-
traceid get_id(const Edge* edge) const;
! traceid get_root_id(const Edge* edge) const;
!
! template <typename T>
! void iterate_edges(T& functor) const { _edges->iterate_value<T>(functor); }
};
#endif // SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP
--- 23,107 ----
*/
#ifndef SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP
#define SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP
#include "jfr/leakprofiler/chains/edge.hpp"
+ #include "jfr/utilities/jfrHashtable.hpp"
#include "memory/allocation.hpp"
typedef u8 traceid;
! class StoredEdge : public Edge {
private:
! mutable traceid _gc_root_id;
! size_t _skip_length;
public:
! StoredEdge();
! StoredEdge(const Edge* parent, const oop* reference);
! StoredEdge(const Edge& edge);
! StoredEdge(const StoredEdge& edge);
! void operator=(const StoredEdge& edge);
! traceid gc_root_id() const { return _gc_root_id; }
! void set_gc_root_id(traceid root_id) const { _gc_root_id = root_id; }
! bool is_skip_edge() const { return _skip_length != 0; }
! size_t skip_length() const { return _skip_length; }
! void set_skip_length(size_t length) { _skip_length = length; }
! void set_parent(const Edge* edge) { this->_parent = edge; }
! StoredEdge* parent() const {
! return const_cast<StoredEdge*>(static_cast<const StoredEdge*>(Edge::parent()));
}
};
class EdgeStore : public CHeapObj<mtTracing> {
! typedef HashTableHost<StoredEdge, traceid, Entry, EdgeStore> EdgeHashTable;
typedef EdgeHashTable::HashEntry EdgeEntry;
template <typename,
typename,
template<typename, typename> class,
typename,
size_t>
friend class HashTableHost;
+ friend class EventEmitter;
+ friend class ObjectSampleWriter;
+ friend class ObjectSampleCheckpoint;
private:
static traceid _edge_id_counter;
EdgeHashTable* _edges;
// Hash table callbacks
void assign_id(EdgeEntry* entry);
bool equals(const Edge& query, uintptr_t hash, const EdgeEntry* entry);
! StoredEdge* get(const oop* reference) const;
! StoredEdge* put(const oop* reference);
! traceid gc_root_id(const Edge* edge) const;
!
! bool put_edges(StoredEdge** previous, const Edge** current, size_t length);
! bool put_skip_edge(StoredEdge** previous, const Edge** current, size_t distance_to_root);
! void put_chain_epilogue(StoredEdge* leak_context_edge, const Edge* root) const;
!
! StoredEdge* associate_leak_context_with_candidate(const Edge* edge);
! void store_gc_root_id_in_leak_context_edge(StoredEdge* leak_context_edge, const Edge* root) const;
! StoredEdge* link_new_edge(StoredEdge** previous, const Edge** current);
! void link_with_existing_chain(const StoredEdge* current_stored, StoredEdge** previous, size_t previous_length);
!
! template <typename T>
! void iterate(T& functor) const { _edges->iterate_value<T>(functor); }
!
! DEBUG_ONLY(bool contains(const oop* reference) const;)
public:
EdgeStore();
~EdgeStore();
bool is_empty() const;
traceid get_id(const Edge* edge) const;
! void put_chain(const Edge* chain, size_t length);
};
#endif // SHARE_VM_LEAKPROFILER_CHAINS_EDGESTORE_HPP
< prev index next >