--- old/src/hotspot/share/memory/metaspace/virtualSpaceList.hpp 2019-08-04 08:11:58.208961525 +0200 +++ new/src/hotspot/share/memory/metaspace/virtualSpaceList.hpp 2019-08-04 08:11:58.008960916 +0200 @@ -26,141 +26,97 @@ #define SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP #include "memory/allocation.hpp" +#include "memory/metaspace/counter.hpp" +#include "memory/metaspace/commitLimiter.hpp" #include "memory/metaspace/virtualSpaceNode.hpp" +#include "memory/virtualspace.hpp" #include "utilities/globalDefinitions.hpp" +class outputStream; namespace metaspace { class Metachunk; -class ChunkManager; -// List of VirtualSpaces for metadata allocation. class VirtualSpaceList : public CHeapObj { - friend class VirtualSpaceNode; - enum VirtualSpaceSizes { - VirtualSpaceSize = 256 * K - }; + // Name + const char* const _name; - // Head of the list - VirtualSpaceNode* _virtual_space_list; - // virtual space currently being used for allocations - VirtualSpaceNode* _current_virtual_space; + // Head of the list. + VirtualSpaceNode* _first_node; - // Is this VirtualSpaceList used for the compressed class space - bool _is_class; + // Node currently being used for allocations. + VirtualSpaceNode* _current_node; - // Sum of reserved and committed memory in the virtual spaces - size_t _reserved_words; - size_t _committed_words; + // Whether this list can expand by allocating new nodes. + const bool _can_expand; - // Number of virtual spaces - size_t _virtual_space_count; + // Used to check limits before committing memory. + CommitLimiter* const _commit_limiter; - // Optimization: we keep an address range to quickly exclude pointers - // which are clearly not pointing into metaspace. This is an optimization for - // VirtualSpaceList::contains(). - address _envelope_lo; - address _envelope_hi; + // Statistics - bool is_within_envelope(address p) const { - return p >= _envelope_lo && p < _envelope_hi; - } + // Holds sum of reserved space, in words, over all list nodes. + SizeCounter _reserved_words_counter; - // Given a node, expand range such that it includes the node. - void expand_envelope_to_include_node(const VirtualSpaceNode* node); + // Holds sum of committed space, in words, over all list nodes. + SizeCounter _committed_words_counter; - ~VirtualSpaceList(); + // Create a new node and append it to the list. After + // this function, _current_node shall point to a new empty node. + // List must be expandable for this to work. + void create_new_node(); - VirtualSpaceNode* virtual_space_list() const { return _virtual_space_list; } +public: - void set_virtual_space_list(VirtualSpaceNode* v) { - _virtual_space_list = v; - } - void set_current_virtual_space(VirtualSpaceNode* v) { - _current_virtual_space = v; - } + // Create a new, empty, expandable list. + VirtualSpaceList(const char* name, CommitLimiter* commit_limiter); - void link_vs(VirtualSpaceNode* new_entry); + // Create a new list. The list will contain one node only, which uses the given ReservedSpace. + // It will be not expandable beyond that first node. + VirtualSpaceList(const char* name, ReservedSpace rs, CommitLimiter* commit_limiter); - // Get another virtual space and add it to the list. This - // is typically prompted by a failed attempt to allocate a chunk - // and is typically followed by the allocation of a chunk. - bool create_new_virtual_space(size_t vs_word_size); + virtual ~VirtualSpaceList(); - // Chunk up the unused committed space in the current - // virtual space and add the chunks to the free list. - void retire_current_virtual_space(); + // Allocate a root chunk from this list. + // Note: this just returns a chunk whose memory is reserved; no memory is committed yet. + // Hence, before using this chunk, it must be committed. + // Also, no limits are checked, since no committing takes place. + Metachunk* allocate_root_chunk(); - DEBUG_ONLY(bool contains_node(const VirtualSpaceNode* node) const;) + //// Statistics //// - public: - VirtualSpaceList(size_t word_size); - VirtualSpaceList(ReservedSpace rs); + // Return sum of reserved words in all nodes. + size_t reserved_words() const { return _reserved_words_counter.get(); } - size_t free_bytes(); + // Return sum of committed words in all nodes. + size_t committed_words() const { return _committed_words_counter.get(); } - Metachunk* get_new_chunk(size_t chunk_word_size, - size_t suggested_commit_granularity); + //// Debug stuff //// + DEBUG_ONLY(void verify(bool slow) const;) - bool expand_node_by(VirtualSpaceNode* node, - size_t min_words, - size_t preferred_words); - - bool expand_by(size_t min_words, - size_t preferred_words); - - VirtualSpaceNode* current_virtual_space() { - return _current_virtual_space; - } - - bool is_class() const { return _is_class; } + // Print all nodes in this space list. + void print_on(outputStream* st) const { print_on(st, K); } + void print_on(outputStream* st, size_t scale) const; - bool initialization_succeeded() { return _virtual_space_list != NULL; } + // Returns true if this pointer is contained in one of our nodes. + bool contains(const MetaWord* p) const; - size_t reserved_words() { return _reserved_words; } - size_t reserved_bytes() { return reserved_words() * BytesPerWord; } - size_t committed_words() { return _committed_words; } - size_t committed_bytes() { return committed_words() * BytesPerWord; } +private: - void inc_reserved_words(size_t v); - void dec_reserved_words(size_t v); - void inc_committed_words(size_t v); - void dec_committed_words(size_t v); - void inc_virtual_space_count(); - void dec_virtual_space_count(); + static VirtualSpaceList* _vslist_class; + static VirtualSpaceList* _vslist_nonclass; - VirtualSpaceNode* find_enclosing_space(const void* ptr); - bool contains(const void* ptr) { return find_enclosing_space(ptr) != NULL; } +public: - // Unlink empty VirtualSpaceNodes and free it. - void purge(ChunkManager* chunk_manager); + static VirtualSpaceList* vslist_class() { return _vslist_class; } + static VirtualSpaceList* vslist_nonclass() { return _vslist_nonclass; } - void print_on(outputStream* st) const { print_on(st, K); } - void print_on(outputStream* st, size_t scale) const; - void print_map(outputStream* st) const; + static void set_vslist_class(VirtualSpaceList* vslist_class); + static void set_vslist_nonclass(VirtualSpaceList* vslist_class); - DEBUG_ONLY(void verify(bool slow);) - class VirtualSpaceListIterator : public StackObj { - VirtualSpaceNode* _virtual_spaces; - public: - VirtualSpaceListIterator(VirtualSpaceNode* virtual_spaces) : - _virtual_spaces(virtual_spaces) {} - - bool repeat() { - return _virtual_spaces != NULL; - } - - VirtualSpaceNode* get_next() { - VirtualSpaceNode* result = _virtual_spaces; - if (_virtual_spaces != NULL) { - _virtual_spaces = _virtual_spaces->next(); - } - return result; - } - }; }; } // namespace metaspace