/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 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.
*
* 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_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 MetachunkListCluster;
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(MetachunkListCluster* 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;
private:
static VirtualSpaceList* _vslist_class;
static VirtualSpaceList* _vslist_nonclass;
public:
static VirtualSpaceList* vslist_class() { return _vslist_class; }
static VirtualSpaceList* vslist_nonclass() { return _vslist_nonclass; }
static void set_vslist_class(VirtualSpaceList* vslist_class);
static void set_vslist_nonclass(VirtualSpaceList* vslist_class);
};
} // namespace metaspace
#endif // SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP