1 /*
2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP
26 #define SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP
27
28 #include "memory/allocation.hpp"
29 #include "memory/metaspace/virtualSpaceNode.hpp"
30 #include "utilities/globalDefinitions.hpp"
31
32
33 namespace metaspace {
34
35 class Metachunk;
36 class ChunkManager;
37
38 // List of VirtualSpaces for metadata allocation.
39 class VirtualSpaceList : public CHeapObj<mtClass> {
40 friend class VirtualSpaceNode;
41
42 enum VirtualSpaceSizes {
43 VirtualSpaceSize = 256 * K
44 };
45
46 // Head of the list
47 VirtualSpaceNode* _virtual_space_list;
48 // virtual space currently being used for allocations
49 VirtualSpaceNode* _current_virtual_space;
50
51 // Is this VirtualSpaceList used for the compressed class space
52 bool _is_class;
53
54 // Sum of reserved and committed memory in the virtual spaces
55 size_t _reserved_words;
56 size_t _committed_words;
57
58 // Number of virtual spaces
59 size_t _virtual_space_count;
60
61 // Optimization: we keep an address range to quickly exclude pointers
62 // which are clearly not pointing into metaspace. This is an optimization for
63 // VirtualSpaceList::contains().
64 address _envelope_lo;
65 address _envelope_hi;
66
67 bool is_within_envelope(address p) const {
68 return p >= _envelope_lo && p < _envelope_hi;
69 }
70
71 // Given a node, expand range such that it includes the node.
72 void expand_envelope_to_include_node(const VirtualSpaceNode* node);
73
74 ~VirtualSpaceList();
75
76 VirtualSpaceNode* virtual_space_list() const { return _virtual_space_list; }
77
78 void set_virtual_space_list(VirtualSpaceNode* v) {
79 _virtual_space_list = v;
80 }
81 void set_current_virtual_space(VirtualSpaceNode* v) {
82 _current_virtual_space = v;
83 }
84
85 void link_vs(VirtualSpaceNode* new_entry);
86
87 // Get another virtual space and add it to the list. This
88 // is typically prompted by a failed attempt to allocate a chunk
89 // and is typically followed by the allocation of a chunk.
90 bool create_new_virtual_space(size_t vs_word_size);
91
92 // Chunk up the unused committed space in the current
93 // virtual space and add the chunks to the free list.
94 void retire_current_virtual_space();
95
96 DEBUG_ONLY(bool contains_node(const VirtualSpaceNode* node) const;)
97
98 public:
99 VirtualSpaceList(size_t word_size);
100 VirtualSpaceList(ReservedSpace rs);
101
102 size_t free_bytes();
103
104 Metachunk* get_new_chunk(size_t chunk_word_size,
105 size_t suggested_commit_granularity);
106
107 bool expand_node_by(VirtualSpaceNode* node,
108 size_t min_words,
109 size_t preferred_words);
110
111 bool expand_by(size_t min_words,
112 size_t preferred_words);
113
114 VirtualSpaceNode* current_virtual_space() {
115 return _current_virtual_space;
116 }
117
118 bool is_class() const { return _is_class; }
119
120 bool initialization_succeeded() { return _virtual_space_list != NULL; }
121
122 size_t reserved_words() { return _reserved_words; }
123 size_t reserved_bytes() { return reserved_words() * BytesPerWord; }
124 size_t committed_words() { return _committed_words; }
125 size_t committed_bytes() { return committed_words() * BytesPerWord; }
126
127 void inc_reserved_words(size_t v);
128 void dec_reserved_words(size_t v);
129 void inc_committed_words(size_t v);
130 void dec_committed_words(size_t v);
131 void inc_virtual_space_count();
132 void dec_virtual_space_count();
133
134 VirtualSpaceNode* find_enclosing_space(const void* ptr);
135 bool contains(const void* ptr) { return find_enclosing_space(ptr) != NULL; }
136
137 // Unlink empty VirtualSpaceNodes and free it.
138 void purge(ChunkManager* chunk_manager);
139
140 void print_on(outputStream* st) const { print_on(st, K); }
141 void print_on(outputStream* st, size_t scale) const;
142 void print_map(outputStream* st) const;
143
144 DEBUG_ONLY(void verify(bool slow);)
145
146 class VirtualSpaceListIterator : public StackObj {
147 VirtualSpaceNode* _virtual_spaces;
148 public:
149 VirtualSpaceListIterator(VirtualSpaceNode* virtual_spaces) :
150 _virtual_spaces(virtual_spaces) {}
151
152 bool repeat() {
153 return _virtual_spaces != NULL;
154 }
155
156 VirtualSpaceNode* get_next() {
157 VirtualSpaceNode* result = _virtual_spaces;
158 if (_virtual_spaces != NULL) {
159 _virtual_spaces = _virtual_spaces->next();
160 }
161 return result;
162 }
163 };
164 };
165
166 } // namespace metaspace
167
168 #endif // SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP
|
1 /*
2 * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2018, 2020 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP
27 #define SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP
28
29 #include "memory/allocation.hpp"
30 #include "memory/metaspace/counter.hpp"
31 #include "memory/metaspace/commitLimiter.hpp"
32 #include "memory/metaspace/virtualSpaceNode.hpp"
33 #include "memory/virtualspace.hpp"
34 #include "utilities/globalDefinitions.hpp"
35
36 class outputStream;
37
38 namespace metaspace {
39
40 class Metachunk;
41 class FreeChunkListVector;
42
43
44 // VirtualSpaceList manages a single (if its non-expandable) or
45 // a series of (if its expandable) virtual memory regions used
46 // for metaspace.
47 //
48 // Internally it holds a list of nodes (VirtualSpaceNode) each
49 // managing a single contiguous memory region. The first node of
50 // this list is the current node and used for allocation of new
51 // root chunks.
52 //
53 // Beyond access to those nodes and the ability to grow new nodes
54 // (if expandable) it allows for purging: purging this list means
55 // removing and unmapping all memory regions which are unused.
56
57 class VirtualSpaceList : public CHeapObj<mtClass> {
58
59 // Name
60 const char* const _name;
61
62 // Head of the list.
63 VirtualSpaceNode* _first_node;
64
65 // Number of nodes (kept for statistics only).
66 IntCounter _nodes_counter;
67
68 // Whether this list can expand by allocating new nodes.
69 const bool _can_expand;
70
71 // Whether this list can be purged.
72 const bool _can_purge;
73
74 // Used to check limits before committing memory.
75 CommitLimiter* const _commit_limiter;
76
77 // Statistics
78
79 // Holds sum of reserved space, in words, over all list nodes.
80 SizeCounter _reserved_words_counter;
81
82 // Holds sum of committed space, in words, over all list nodes.
83 SizeCounter _committed_words_counter;
84
85 // Create a new node and append it to the list. After
86 // this function, _current_node shall point to a new empty node.
87 // List must be expandable for this to work.
88 void create_new_node();
89
90 public:
91
92 // Create a new, empty, expandable list.
93 VirtualSpaceList(const char* name, CommitLimiter* commit_limiter);
94
95 // Create a new list. The list will contain one node only, which uses the given ReservedSpace.
96 // It will be not expandable beyond that first node.
97 VirtualSpaceList(const char* name, ReservedSpace rs, CommitLimiter* commit_limiter);
98
99 virtual ~VirtualSpaceList();
100
101 // Allocate a root chunk from this list.
102 // Note: this just returns a chunk whose memory is reserved; no memory is committed yet.
103 // Hence, before using this chunk, it must be committed.
104 // May return NULL if vslist would need to be expanded to hold the new root node but
105 // the list cannot be expanded (in practice this means we reached CompressedClassSpaceSize).
106 Metachunk* allocate_root_chunk();
107
108 // Attempts to purge nodes. This will remove and delete nodes which only contain free chunks.
109 // The free chunks are removed from the freelists before the nodes are deleted.
110 // Return number of purged nodes.
111 int purge(FreeChunkListVector* freelists);
112
113 //// Statistics ////
114
115 // Return sum of reserved words in all nodes.
116 size_t reserved_words() const { return _reserved_words_counter.get(); }
117
118 // Return sum of committed words in all nodes.
119 size_t committed_words() const { return _committed_words_counter.get(); }
120
121 // Return number of nodes in this list.
122 int num_nodes() const { return _nodes_counter.get(); }
123
124 //// Debug stuff ////
125 DEBUG_ONLY(void verify(bool slow) const;)
126 DEBUG_ONLY(void verify_locked(bool slow) const;)
127
128 // Print all nodes in this space list.
129 void print_on(outputStream* st) const;
130
131 // Returns true if this pointer is contained in one of our nodes.
132 bool contains(const MetaWord* p) const;
133
134 // Returns true if the list is not expandable and no more root chunks
135 // can be allocated.
136 bool is_full() const;
137
138 // Convenience methods to return the global class-space vslist
139 // and non-class vslist, respectively.
140 static VirtualSpaceList* vslist_class();
141 static VirtualSpaceList* vslist_nonclass();
142
143 // These exist purely to print limits of the compressed class space;
144 // if we ever change the ccs to not use a degenerated-list-of-one-node this
145 // will go away.
146 MetaWord* base_of_first_node() const { return _first_node != NULL ? _first_node->base() : NULL; }
147 size_t word_size_of_first_node() const { return _first_node != NULL ? _first_node->word_size() : 0; }
148
149 };
150
151 } // namespace metaspace
152
153 #endif // SHARE_MEMORY_METASPACE_VIRTUALSPACELIST_HPP
154
|