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 |
169 | |