< prev index next >

src/hotspot/share/memory/metaspace/virtualSpaceList.hpp

Print this page
rev 60538 : imported patch jep387-all.patch

*** 1,7 **** /* ! * Copyright (c) 2018, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,8 ---- /* ! * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2018, 2020 SAP SE. 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.
*** 24,168 **** #ifndef SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP #define SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP #include "memory/allocation.hpp" #include "memory/metaspace/virtualSpaceNode.hpp" #include "utilities/globalDefinitions.hpp" namespace metaspace { class Metachunk; ! class ChunkManager; - // List of VirtualSpaces for metadata allocation. - class VirtualSpaceList : public CHeapObj<mtClass> { - friend class VirtualSpaceNode; - - enum VirtualSpaceSizes { - VirtualSpaceSize = 256 * K - }; - - // Head of the list - VirtualSpaceNode* _virtual_space_list; - // virtual space currently being used for allocations - VirtualSpaceNode* _current_virtual_space; ! // Is this VirtualSpaceList used for the compressed class space ! bool _is_class; ! // Sum of reserved and committed memory in the virtual spaces ! size_t _reserved_words; ! size_t _committed_words; ! ! // Number of virtual spaces ! size_t _virtual_space_count; ! // 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; ! bool is_within_envelope(address p) const { ! return p >= _envelope_lo && p < _envelope_hi; ! } ! // Given a node, expand range such that it includes the node. ! void expand_envelope_to_include_node(const VirtualSpaceNode* node); ! ~VirtualSpaceList(); ! VirtualSpaceNode* virtual_space_list() const { return _virtual_space_list; } ! void set_virtual_space_list(VirtualSpaceNode* v) { ! _virtual_space_list = v; ! } ! void set_current_virtual_space(VirtualSpaceNode* v) { ! _current_virtual_space = v; ! } ! void link_vs(VirtualSpaceNode* new_entry); ! // 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); ! // Chunk up the unused committed space in the current ! // virtual space and add the chunks to the free list. ! void retire_current_virtual_space(); ! DEBUG_ONLY(bool contains_node(const VirtualSpaceNode* node) const;) ! public: ! VirtualSpaceList(size_t word_size); ! VirtualSpaceList(ReservedSpace rs); ! size_t free_bytes(); ! Metachunk* get_new_chunk(size_t chunk_word_size, ! size_t suggested_commit_granularity); ! 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; } ! bool initialization_succeeded() { return _virtual_space_list != NULL; } ! 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; } ! 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(); ! VirtualSpaceNode* find_enclosing_space(const void* ptr); ! bool contains(const void* ptr) { return find_enclosing_space(ptr) != NULL; } ! // Unlink empty VirtualSpaceNodes and free it. ! void purge(ChunkManager* chunk_manager); ! 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; ! 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 #endif // SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP --- 25,154 ---- #ifndef SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP #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 FreeChunkListVector; ! // VirtualSpaceList manages a single (if its non-expandable) or ! // a series of (if its expandable) virtual memory regions used ! // for metaspace. ! // ! // Internally it holds a list of nodes (VirtualSpaceNode) each ! // managing a single contiguous memory region. The first node of ! // this list is the current node and used for allocation of new ! // root chunks. ! // ! // Beyond access to those nodes and the ability to grow new nodes ! // (if expandable) it allows for purging: purging this list means ! // removing and unmapping all memory regions which are unused. ! class VirtualSpaceList : public CHeapObj<mtClass> { ! // Name ! const char* const _name; ! // Head of the list. ! VirtualSpaceNode* _first_node; ! // Number of nodes (kept for statistics only). ! IntCounter _nodes_counter; ! // Whether this list can expand by allocating new nodes. ! const bool _can_expand; ! // Whether this list can be purged. ! const bool _can_purge; ! // Used to check limits before committing memory. ! CommitLimiter* const _commit_limiter; ! // Statistics ! // Holds sum of reserved space, in words, over all list nodes. ! SizeCounter _reserved_words_counter; ! // Holds sum of committed space, in words, over all list nodes. ! SizeCounter _committed_words_counter; ! // 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(); ! public: ! // Create a new, empty, expandable list. ! VirtualSpaceList(const char* name, CommitLimiter* commit_limiter); ! // 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); ! virtual ~VirtualSpaceList(); ! // 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. ! // May return NULL if vslist would need to be expanded to hold the new root node but ! // the list cannot be expanded (in practice this means we reached CompressedClassSpaceSize). ! Metachunk* allocate_root_chunk(); ! // Attempts to purge nodes. This will remove and delete nodes which only contain free chunks. ! // The free chunks are removed from the freelists before the nodes are deleted. ! // Return number of purged nodes. ! int purge(FreeChunkListVector* freelists); ! //// Statistics //// ! // Return sum of reserved words in all nodes. ! size_t reserved_words() const { return _reserved_words_counter.get(); } ! // Return sum of committed words in all nodes. ! size_t committed_words() const { return _committed_words_counter.get(); } ! // Return number of nodes in this list. ! int num_nodes() const { return _nodes_counter.get(); } ! //// Debug stuff //// ! DEBUG_ONLY(void verify(bool slow) const;) ! DEBUG_ONLY(void verify_locked(bool slow) const;) ! // Print all nodes in this space list. ! void print_on(outputStream* st) const; ! // Returns true if this pointer is contained in one of our nodes. ! bool contains(const MetaWord* p) const; ! // Returns true if the list is not expandable and no more root chunks ! // can be allocated. ! bool is_full() const; ! // Convenience methods to return the global class-space vslist ! // and non-class vslist, respectively. ! static VirtualSpaceList* vslist_class(); ! static VirtualSpaceList* vslist_nonclass(); ! // These exist purely to print limits of the compressed class space; ! // if we ever change the ccs to not use a degenerated-list-of-one-node this ! // will go away. ! MetaWord* base_of_first_node() const { return _first_node != NULL ? _first_node->base() : NULL; } ! size_t word_size_of_first_node() const { return _first_node != NULL ? _first_node->word_size() : 0; } }; } // namespace metaspace #endif // SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP +
< prev index next >