File: | jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp |
Warning: | line 106, column 22 Value stored to 'starting_level' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. |
3 | * Copyright (c) 2020, 2021 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 | #include "precompiled.hpp" |
27 | #include "logging/log.hpp" |
28 | #include "memory/allocation.hpp" |
29 | #include "memory/metaspace/chunkHeaderPool.hpp" |
30 | #include "memory/metaspace/chunkManager.hpp" |
31 | #include "memory/metaspace/freeChunkList.hpp" |
32 | #include "memory/metaspace/metachunk.hpp" |
33 | #include "memory/metaspace/metaspaceCommon.hpp" |
34 | #include "memory/metaspace/rootChunkArea.hpp" |
35 | #include "runtime/mutexLocker.hpp" |
36 | #include "utilities/debug.hpp" |
37 | #include "utilities/globalDefinitions.hpp" |
38 | |
39 | namespace metaspace { |
40 | |
41 | RootChunkArea::RootChunkArea(const MetaWord* base) : |
42 | _base(base), |
43 | _first_chunk(NULL__null) |
44 | {} |
45 | |
46 | RootChunkArea::~RootChunkArea() { |
47 | // This is called when a VirtualSpaceNode is destructed (purged). |
48 | // All chunks should be free of course. In fact, there should only |
49 | // be one chunk, since all free chunks should have been merged. |
50 | if (_first_chunk != NULL__null) { |
51 | assert(_first_chunk->is_root_chunk() && _first_chunk->is_free(),do { if (!(_first_chunk->is_root_chunk() && _first_chunk ->is_free())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 52, "assert(" "_first_chunk->is_root_chunk() && _first_chunk->is_free()" ") failed", "Cannot delete root chunk area if not all chunks are free." ); ::breakpoint(); } } while (0) |
52 | "Cannot delete root chunk area if not all chunks are free.")do { if (!(_first_chunk->is_root_chunk() && _first_chunk ->is_free())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 52, "assert(" "_first_chunk->is_root_chunk() && _first_chunk->is_free()" ") failed", "Cannot delete root chunk area if not all chunks are free." ); ::breakpoint(); } } while (0); |
53 | ChunkHeaderPool::pool()->return_chunk_header(_first_chunk); |
54 | } |
55 | } |
56 | |
57 | // Initialize: allocate a root node and a root chunk header; return the |
58 | // root chunk header. It will be partly initialized. |
59 | // Note: this just allocates a memory-less header; memory itself is allocated inside VirtualSpaceNode. |
60 | Metachunk* RootChunkArea::alloc_root_chunk_header(VirtualSpaceNode* node) { |
61 | assert(_first_chunk == 0, "already have a root")do { if (!(_first_chunk == 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 61, "assert(" "_first_chunk == 0" ") failed", "already have a root" ); ::breakpoint(); } } while (0); |
62 | Metachunk* c = ChunkHeaderPool::pool()->allocate_chunk_header(); |
63 | c->initialize(node, const_cast<MetaWord*>(_base), chunklevel::ROOT_CHUNK_LEVEL); |
64 | _first_chunk = c; |
65 | return c; |
66 | } |
67 | |
68 | // Given a chunk c, split it recursively until you get a chunk of the given target_level. |
69 | // |
70 | // The resulting target chunk resides at the same address as the original chunk. |
71 | // The resulting splinters are added to freelists. |
72 | // |
73 | // Returns pointer to the result chunk; the splitted-off chunks are added as |
74 | // free chunks to the freelists. |
75 | void RootChunkArea::split(chunklevel_t target_level, Metachunk* c, FreeChunkListVector* freelists) { |
76 | // Splitting a chunk once works like this: |
77 | // |
78 | // For a given chunk we want to split: |
79 | // - increase the chunk level (which halves its size) |
80 | // - (but leave base address as it is since it will be the leader of the newly |
81 | // created chunk pair) |
82 | // - then create a new chunk header of the same level, set its memory range |
83 | // to cover the second half of the old chunk. |
84 | // - wire them up (prev_in_vs/next_in_vs) |
85 | // - return the follower chunk as "splinter chunk" in the splinters array. |
86 | |
87 | // Doing this multiple times will create a new free splinter chunk for every |
88 | // level we split: |
89 | // |
90 | // A <- original chunk |
91 | // |
92 | // B B <- split into two halves |
93 | // |
94 | // C C B <- first half split again |
95 | // |
96 | // D D C B <- first half split again ... |
97 | // |
98 | |
99 | DEBUG_ONLY(check_pointer(c->base());)check_pointer(c->base()); |
100 | DEBUG_ONLY(c->verify();)c->verify(); |
101 | assert(c->is_free(), "Can only split free chunks.")do { if (!(c->is_free())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 101, "assert(" "c->is_free()" ") failed", "Can only split free chunks." ); ::breakpoint(); } } while (0); |
102 | |
103 | DEBUG_ONLY(chunklevel::check_valid_level(target_level))chunklevel::check_valid_level(target_level); |
104 | assert(target_level > c->level(), "Wrong target level")do { if (!(target_level > c->level())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 104, "assert(" "target_level > c->level()" ") failed" , "Wrong target level"); ::breakpoint(); } } while (0); |
105 | |
106 | const chunklevel_t starting_level = c->level(); |
Value stored to 'starting_level' during its initialization is never read | |
107 | |
108 | while (c->level() < target_level) { |
109 | |
110 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("Splitting chunk: " METACHUNK_FULL_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " (" "%" "l" "u" "), used: " "%" "l" "u" ", committed: " "%" "l" "u" ", committed-free: " "%" "l" "u" ".", METACHUNK_FULL_FORMAT_ARGS(c)p2i(c), c->get_state_char(), p2i(c->base()), c->level (), c->word_size(), c->used_words(), c->committed_words (), c->free_below_committed_words()); |
111 | |
112 | c->inc_level(); |
113 | Metachunk* splinter_chunk = ChunkHeaderPool::pool()->allocate_chunk_header(); |
114 | splinter_chunk->initialize(c->vsnode(), c->end(), c->level()); |
115 | |
116 | // Fix committed words info: If over the half of the original chunk was |
117 | // committed, committed area spills over into the follower chunk. |
118 | const size_t old_committed_words = c->committed_words(); |
119 | if (old_committed_words > c->word_size()) { |
120 | c->set_committed_words(c->word_size()); |
121 | splinter_chunk->set_committed_words(old_committed_words - c->word_size()); |
122 | } else { |
123 | splinter_chunk->set_committed_words(0); |
124 | } |
125 | |
126 | // Insert splinter chunk into vs list |
127 | if (c->next_in_vs() != NULL__null) { |
128 | c->next_in_vs()->set_prev_in_vs(splinter_chunk); |
129 | } |
130 | splinter_chunk->set_next_in_vs(c->next_in_vs()); |
131 | splinter_chunk->set_prev_in_vs(c); |
132 | c->set_next_in_vs(splinter_chunk); |
133 | |
134 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>(".. Result chunk: " METACHUNK_FULL_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " (" "%" "l" "u" "), used: " "%" "l" "u" ", committed: " "%" "l" "u" ", committed-free: " "%" "l" "u" ".", METACHUNK_FULL_FORMAT_ARGS(c)p2i(c), c->get_state_char(), p2i(c->base()), c->level (), c->word_size(), c->used_words(), c->committed_words (), c->free_below_committed_words()); |
135 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>(".. Splinter chunk: " METACHUNK_FULL_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " (" "%" "l" "u" "), used: " "%" "l" "u" ", committed: " "%" "l" "u" ", committed-free: " "%" "l" "u" ".", METACHUNK_FULL_FORMAT_ARGS(splinter_chunk)p2i(splinter_chunk), splinter_chunk->get_state_char(), p2i (splinter_chunk->base()), splinter_chunk->level(), splinter_chunk ->word_size(), splinter_chunk->used_words(), splinter_chunk ->committed_words(), splinter_chunk->free_below_committed_words ()); |
136 | |
137 | // Add splinter to free lists |
138 | freelists->add(splinter_chunk); |
139 | } |
140 | |
141 | assert(c->level() == target_level, "Sanity")do { if (!(c->level() == target_level)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 141, "assert(" "c->level() == target_level" ") failed", "Sanity" ); ::breakpoint(); } } while (0); |
142 | |
143 | DEBUG_ONLY(verify();)verify(); |
144 | DEBUG_ONLY(c->verify();)c->verify(); |
145 | } |
146 | |
147 | // Given a chunk, attempt to merge it recursively with its neighboring chunks. |
148 | // |
149 | // If successful (merged at least once), returns address of |
150 | // the merged chunk; NULL otherwise. |
151 | // |
152 | // The merged chunks are removed from the freelists. |
153 | // |
154 | // !!! Please note that if this method returns a non-NULL value, the |
155 | // original chunk will be invalid and should not be accessed anymore! !!! |
156 | Metachunk* RootChunkArea::merge(Metachunk* c, FreeChunkListVector* freelists) { |
157 | // Note rules: |
158 | // |
159 | // - a chunk always has a buddy, unless it is a root chunk. |
160 | // - In that buddy pair, a chunk is either leader or follower. |
161 | // - a chunk's base address is always aligned at its size. |
162 | // - if chunk is leader, its base address is also aligned to the size of the next |
163 | // lower level, at least. A follower chunk is not. |
164 | |
165 | // How we merge once: |
166 | // |
167 | // For a given chunk c, which has to be free and non-root, we do: |
168 | // - find out if we are the leader or the follower chunk |
169 | // - if we are leader, next_in_vs must be the follower; if we are follower, |
170 | // prev_in_vs must be the leader. Now we have the buddy chunk. |
171 | // - However, if the buddy chunk itself is split (of a level higher than us) |
172 | // we cannot merge. |
173 | // - we can only merge if the buddy is of the same level as we are and it is |
174 | // free. |
175 | // - Then we merge by simply removing the follower chunk from the address range |
176 | // linked list (returning the now useless header to the pool) and decreasing |
177 | // the leader chunk level by one. That makes it double the size. |
178 | |
179 | // Example: |
180 | // (lower case chunks are free, the * indicates the chunk we want to merge): |
181 | // |
182 | // ........................ |
183 | // d d*c b A <- we return the second (d*) chunk... |
184 | // |
185 | // c* c b A <- we merge it with its predecessor and decrease its level... |
186 | // |
187 | // b* b A <- we merge it again, since its new neighbor was free too... |
188 | // |
189 | // a* A <- we merge it again, since its new neighbor was free too... |
190 | // |
191 | // And we are done, since its new neighbor, (A), is not free. We would also be done |
192 | // if the new neighbor itself is splintered. |
193 | |
194 | DEBUG_ONLY(check_pointer(c->base());)check_pointer(c->base()); |
195 | assert(!c->is_root_chunk(), "Cannot be merged further.")do { if (!(!c->is_root_chunk())) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 195, "assert(" "!c->is_root_chunk()" ") failed", "Cannot be merged further." ); ::breakpoint(); } } while (0); |
196 | assert(c->is_free(), "Can only merge free chunks.")do { if (!(c->is_free())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 196, "assert(" "c->is_free()" ") failed", "Can only merge free chunks." ); ::breakpoint(); } } while (0); |
197 | |
198 | DEBUG_ONLY(c->verify();)c->verify(); |
199 | |
200 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("Attempting to merge chunk " METACHUNK_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", METACHUNK_FORMAT_ARGS(c)p2i(c), c->get_state_char(), p2i(c->base()), c->level ()); |
201 | |
202 | const chunklevel_t starting_level = c->level(); |
203 | |
204 | bool stop = false; |
205 | Metachunk* result = NULL__null; |
206 | |
207 | do { |
208 | |
209 | // First find out if this chunk is the leader of its pair |
210 | const bool is_leader = c->is_leader(); |
211 | |
212 | // Note: this is either our buddy or a splinter of the buddy. |
213 | Metachunk* const buddy = c->is_leader() ? c->next_in_vs() : c->prev_in_vs(); |
214 | DEBUG_ONLY(buddy->verify();)buddy->verify(); |
215 | |
216 | // A buddy chunk must be of the same or higher level (so, same size or smaller) |
217 | // never be larger. |
218 | assert(buddy->level() >= c->level(), "Sanity")do { if (!(buddy->level() >= c->level())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 218, "assert(" "buddy->level() >= c->level()" ") failed" , "Sanity"); ::breakpoint(); } } while (0); |
219 | |
220 | // Is this really my buddy (same level) or a splinter of it (higher level)? |
221 | // Also, is it free? |
222 | if (buddy->level() != c->level() || buddy->is_free() == false) { |
223 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("cannot merge with chunk " METACHUNK_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", METACHUNK_FORMAT_ARGS(buddy)p2i(buddy), buddy->get_state_char(), p2i(buddy->base()) , buddy->level()); |
224 | stop = true; |
225 | } else { |
226 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("will merge with chunk " METACHUNK_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", METACHUNK_FORMAT_ARGS(buddy)p2i(buddy), buddy->get_state_char(), p2i(buddy->base()) , buddy->level()); |
227 | |
228 | // We can merge with the buddy. |
229 | // First, remove buddy from the chunk manager. |
230 | assert(buddy->is_free(), "Sanity")do { if (!(buddy->is_free())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 230, "assert(" "buddy->is_free()" ") failed", "Sanity"); ::breakpoint(); } } while (0); |
231 | freelists->remove(buddy); |
232 | |
233 | // Determine current leader and follower |
234 | Metachunk* leader; |
235 | Metachunk* follower; |
236 | if (is_leader) { |
237 | leader = c; follower = buddy; |
238 | } else { |
239 | leader = buddy; follower = c; |
240 | } |
241 | |
242 | // Last checkpoint |
243 | assert(leader->end() == follower->base() &&do { if (!(leader->end() == follower->base() && leader->level() == follower->level() && leader ->is_free() && follower->is_free())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 245, "assert(" "leader->end() == follower->base() && leader->level() == follower->level() && leader->is_free() && follower->is_free()" ") failed", "Sanity"); ::breakpoint(); } } while (0) |
244 | leader->level() == follower->level() &&do { if (!(leader->end() == follower->base() && leader->level() == follower->level() && leader ->is_free() && follower->is_free())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 245, "assert(" "leader->end() == follower->base() && leader->level() == follower->level() && leader->is_free() && follower->is_free()" ") failed", "Sanity"); ::breakpoint(); } } while (0) |
245 | leader->is_free() && follower->is_free(), "Sanity")do { if (!(leader->end() == follower->base() && leader->level() == follower->level() && leader ->is_free() && follower->is_free())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 245, "assert(" "leader->end() == follower->base() && leader->level() == follower->level() && leader->is_free() && follower->is_free()" ") failed", "Sanity"); ::breakpoint(); } } while (0); |
246 | |
247 | // The new merged chunk is as far committed as possible (if leader |
248 | // chunk is fully committed, as far as the follower chunk). |
249 | size_t merged_committed_words = leader->committed_words(); |
250 | if (merged_committed_words == leader->word_size()) { |
251 | merged_committed_words += follower->committed_words(); |
252 | } |
253 | |
254 | // Leader survives, follower chunk is freed. Remove follower from vslist .. |
255 | leader->set_next_in_vs(follower->next_in_vs()); |
256 | if (follower->next_in_vs() != NULL__null) { |
257 | follower->next_in_vs()->set_prev_in_vs(leader); |
258 | } |
259 | |
260 | // .. and return follower chunk header to pool for reuse. |
261 | ChunkHeaderPool::pool()->return_chunk_header(follower); |
262 | |
263 | // Leader level gets decreased (leader chunk doubles in size) but |
264 | // base address stays the same. |
265 | leader->dec_level(); |
266 | |
267 | // set commit boundary |
268 | leader->set_committed_words(merged_committed_words); |
269 | |
270 | // If the leader is now of root chunk size, stop merging |
271 | if (leader->is_root_chunk()) { |
272 | stop = true; |
273 | } |
274 | |
275 | result = c = leader; |
276 | DEBUG_ONLY(leader->verify();)leader->verify(); |
277 | } |
278 | } while (!stop); |
279 | |
280 | #ifdef ASSERT1 |
281 | verify(); |
282 | if (result != NULL__null) { |
283 | result->verify(); |
284 | } |
285 | #endif // ASSERT |
286 | return result; |
287 | } |
288 | |
289 | // Given a chunk c, which must be "in use" and must not be a root chunk, attempt to |
290 | // enlarge it in place by claiming its trailing buddy. |
291 | // |
292 | // This will only work if c is the leader of the buddy pair and the trailing buddy is free. |
293 | // |
294 | // If successful, the follower chunk will be removed from the freelists, the leader chunk c will |
295 | // double in size (level decreased by one). |
296 | // |
297 | // On success, true is returned, false otherwise. |
298 | bool RootChunkArea::attempt_enlarge_chunk(Metachunk* c, FreeChunkListVector* freelists) { |
299 | DEBUG_ONLY(check_pointer(c->base());)check_pointer(c->base()); |
300 | assert(!c->is_root_chunk(), "Cannot be merged further.")do { if (!(!c->is_root_chunk())) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 300, "assert(" "!c->is_root_chunk()" ") failed", "Cannot be merged further." ); ::breakpoint(); } } while (0); |
301 | |
302 | // There is no real reason for this limitation other than it is not |
303 | // needed on free chunks since they should be merged already: |
304 | assert(c->is_in_use(), "Can only enlarge in use chunks.")do { if (!(c->is_in_use())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 304, "assert(" "c->is_in_use()" ") failed", "Can only enlarge in use chunks." ); ::breakpoint(); } } while (0); |
305 | DEBUG_ONLY(c->verify();)c->verify(); |
306 | |
307 | if (!c->is_leader()) { |
308 | return false; |
309 | } |
310 | |
311 | // We are the leader, so the buddy must follow us. |
312 | Metachunk* const buddy = c->next_in_vs(); |
313 | DEBUG_ONLY(buddy->verify();)buddy->verify(); |
314 | |
315 | // Of course buddy cannot be larger than us. |
316 | assert(buddy->level() >= c->level(), "Sanity")do { if (!(buddy->level() >= c->level())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 316, "assert(" "buddy->level() >= c->level()" ") failed" , "Sanity"); ::breakpoint(); } } while (0); |
317 | |
318 | // We cannot merge buddy in if it is not free... |
319 | if (!buddy->is_free()) { |
320 | return false; |
321 | } |
322 | // ... nor if it is splintered. |
323 | if (buddy->level() != c->level()) { |
324 | return false; |
325 | } |
326 | |
327 | // Okay, lets enlarge c. |
328 | log_trace(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Trace))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Trace>("Enlarging chunk " METACHUNK_FULL_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " (" "%" "l" "u" "), used: " "%" "l" "u" ", committed: " "%" "l" "u" ", committed-free: " "%" "l" "u" " by merging in follower " METACHUNK_FULL_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " (" "%" "l" "u" "), used: " "%" "l" "u" ", committed: " "%" "l" "u" ", committed-free: " "%" "l" "u" ".", |
329 | METACHUNK_FULL_FORMAT_ARGS(c)p2i(c), c->get_state_char(), p2i(c->base()), c->level (), c->word_size(), c->used_words(), c->committed_words (), c->free_below_committed_words(), METACHUNK_FULL_FORMAT_ARGS(buddy)p2i(buddy), buddy->get_state_char(), p2i(buddy->base()) , buddy->level(), buddy->word_size(), buddy->used_words (), buddy->committed_words(), buddy->free_below_committed_words ()); |
330 | |
331 | // the enlarged c is as far committed as possible: |
332 | size_t merged_committed_words = c->committed_words(); |
333 | if (merged_committed_words == c->word_size()) { |
334 | merged_committed_words += buddy->committed_words(); |
335 | } |
336 | |
337 | // Remove buddy from vs list... |
338 | Metachunk* successor = buddy->next_in_vs(); |
339 | if (successor != NULL__null) { |
340 | successor->set_prev_in_vs(c); |
341 | } |
342 | c->set_next_in_vs(successor); |
343 | |
344 | // .. and from freelist ... |
345 | freelists->remove(buddy); |
346 | |
347 | // .. and return its empty husk to the pool... |
348 | ChunkHeaderPool::pool()->return_chunk_header(buddy); |
349 | |
350 | // Then decrease level of c. |
351 | c->dec_level(); |
352 | |
353 | // and correct committed words if needed. |
354 | c->set_committed_words(merged_committed_words); |
355 | |
356 | log_debug(metaspace)(!(LogImpl<(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag ::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag:: __NO_TAG)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl <(LogTag::_metaspace), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::write<LogLevel::Debug>("Enlarged chunk " METACHUNK_FULL_FORMAT"@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " (" "%" "l" "u" "), used: " "%" "l" "u" ", committed: " "%" "l" "u" ", committed-free: " "%" "l" "u" ".", METACHUNK_FULL_FORMAT_ARGS(c)p2i(c), c->get_state_char(), p2i(c->base()), c->level (), c->word_size(), c->used_words(), c->committed_words (), c->free_below_committed_words()); |
357 | |
358 | DEBUG_ONLY(verify())verify(); |
359 | return true; |
360 | } |
361 | |
362 | // Returns true if this root chunk area is completely free: |
363 | // In that case, it should only contain one chunk (maximally merged, so a root chunk) |
364 | // and it should be free. |
365 | bool RootChunkArea::is_free() const { |
366 | return _first_chunk == NULL__null || |
367 | (_first_chunk->is_root_chunk() && _first_chunk->is_free()); |
368 | } |
369 | |
370 | #ifdef ASSERT1 |
371 | |
372 | #define assrt_(cond, ...)if (!(cond)) { fdStream errst(2); this->print_on(&errst ); do { if (!(cond)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 372, "assert(" "cond" ") failed", ...); ::breakpoint(); } } while (0); } \ |
373 | if (!(cond)) { \ |
374 | fdStream errst(2); \ |
375 | this->print_on(&errst); \ |
376 | vmassert(cond, __VA_ARGS__)do { if (!(cond)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 376, "assert(" "cond" ") failed", __VA_ARGS__); ::breakpoint (); } } while (0); \ |
377 | } |
378 | |
379 | void RootChunkArea::verify() const { |
380 | assert_lock_strong(Metaspace_lock); |
381 | assert_is_aligned(_base, chunklevel::MAX_CHUNK_BYTE_SIZE)do { if (!(is_aligned((_base), (chunklevel::MAX_CHUNK_BYTE_SIZE )))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 381, "assert(" "is_aligned((_base), (chunklevel::MAX_CHUNK_BYTE_SIZE))" ") failed", "0x%" "l" "x" " is not aligned to " "0x%" "l" "x" , (size_t)(uintptr_t)_base, (size_t)(chunklevel::MAX_CHUNK_BYTE_SIZE )); ::breakpoint(); } } while (0); |
382 | |
383 | // Iterate thru all chunks in this area. They must be ordered correctly, |
384 | // being adjacent to each other, and cover the complete area |
385 | int num_chunk = 0; |
386 | |
387 | if (_first_chunk != NULL__null) { |
388 | assrt_(_first_chunk->prev_in_vs() == NULL, "Sanity")if (!(_first_chunk->prev_in_vs() == __null)) { fdStream errst (2); this->print_on(&errst); do { if (!(_first_chunk-> prev_in_vs() == __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 388, "assert(" "_first_chunk->prev_in_vs() == __null" ") failed" , "Sanity"); ::breakpoint(); } } while (0); }; |
389 | |
390 | const Metachunk* c = _first_chunk; |
391 | const MetaWord* expected_next_base = _base; |
392 | const MetaWord* const area_end = _base + word_size(); |
393 | |
394 | while (c != NULL__null) { |
395 | assrt_(c->is_free() || c->is_in_use(),if (!(c->is_free() || c->is_in_use())) { fdStream errst (2); this->print_on(&errst); do { if (!(c->is_free( ) || c->is_in_use())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 397, "assert(" "c->is_free() || c->is_in_use()" ") failed" , "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " - invalid state.", num_chunk, p2i (c), c->get_state_char(), p2i(c->base()), c->level() ); ::breakpoint(); } } while (0); } |
396 | "Chunk No. %d " METACHUNK_FORMAT " - invalid state.",if (!(c->is_free() || c->is_in_use())) { fdStream errst (2); this->print_on(&errst); do { if (!(c->is_free( ) || c->is_in_use())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 397, "assert(" "c->is_free() || c->is_in_use()" ") failed" , "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " - invalid state.", num_chunk, p2i (c), c->get_state_char(), p2i(c->base()), c->level() ); ::breakpoint(); } } while (0); } |
397 | num_chunk, METACHUNK_FORMAT_ARGS(c))if (!(c->is_free() || c->is_in_use())) { fdStream errst (2); this->print_on(&errst); do { if (!(c->is_free( ) || c->is_in_use())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 397, "assert(" "c->is_free() || c->is_in_use()" ") failed" , "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " - invalid state.", num_chunk, p2i (c), c->get_state_char(), p2i(c->base()), c->level() ); ::breakpoint(); } } while (0); }; |
398 | assrt_(c->base() == expected_next_base,if (!(c->base() == expected_next_base)) { fdStream errst(2 ); this->print_on(&errst); do { if (!(c->base() == expected_next_base )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 400, "assert(" "c->base() == expected_next_base" ") failed" , "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " - unexpected base.", num_chunk , p2i(c), c->get_state_char(), p2i(c->base()), c->level ()); ::breakpoint(); } } while (0); } |
399 | "Chunk No. %d " METACHUNK_FORMAT " - unexpected base.",if (!(c->base() == expected_next_base)) { fdStream errst(2 ); this->print_on(&errst); do { if (!(c->base() == expected_next_base )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 400, "assert(" "c->base() == expected_next_base" ") failed" , "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " - unexpected base.", num_chunk , p2i(c), c->get_state_char(), p2i(c->base()), c->level ()); ::breakpoint(); } } while (0); } |
400 | num_chunk, METACHUNK_FORMAT_ARGS(c))if (!(c->base() == expected_next_base)) { fdStream errst(2 ); this->print_on(&errst); do { if (!(c->base() == expected_next_base )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 400, "assert(" "c->base() == expected_next_base" ") failed" , "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " - unexpected base.", num_chunk , p2i(c), c->get_state_char(), p2i(c->base()), c->level ()); ::breakpoint(); } } while (0); }; |
401 | assrt_(c->base() >= base() && c->end() <= end(),if (!(c->base() >= base() && c->end() <= end ())) { fdStream errst(2); this->print_on(&errst); do { if (!(c->base() >= base() && c->end() <= end())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 403, "assert(" "c->base() >= base() && c->end() <= end()" ") failed", "chunk %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " oob for this root area [" "0x%016" "l" "x" ".." "0x%016" "l" "x" ").", num_chunk, p2i(c), c-> get_state_char(), p2i(c->base()), c->level(), p2i(base( )), p2i(end())); ::breakpoint(); } } while (0); } |
402 | "chunk %d " METACHUNK_FORMAT " oob for this root area [" PTR_FORMAT ".." PTR_FORMAT ").",if (!(c->base() >= base() && c->end() <= end ())) { fdStream errst(2); this->print_on(&errst); do { if (!(c->base() >= base() && c->end() <= end())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 403, "assert(" "c->base() >= base() && c->end() <= end()" ") failed", "chunk %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " oob for this root area [" "0x%016" "l" "x" ".." "0x%016" "l" "x" ").", num_chunk, p2i(c), c-> get_state_char(), p2i(c->base()), c->level(), p2i(base( )), p2i(end())); ::breakpoint(); } } while (0); } |
403 | num_chunk, METACHUNK_FORMAT_ARGS(c), p2i(base()), p2i(end()))if (!(c->base() >= base() && c->end() <= end ())) { fdStream errst(2); this->print_on(&errst); do { if (!(c->base() >= base() && c->end() <= end())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 403, "assert(" "c->base() >= base() && c->end() <= end()" ") failed", "chunk %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " oob for this root area [" "0x%016" "l" "x" ".." "0x%016" "l" "x" ").", num_chunk, p2i(c), c-> get_state_char(), p2i(c->base()), c->level(), p2i(base( )), p2i(end())); ::breakpoint(); } } while (0); }; |
404 | assrt_(is_aligned(c->base(), c->word_size()),if (!(is_aligned(c->base(), c->word_size()))) { fdStream errst(2); this->print_on(&errst); do { if (!(is_aligned (c->base(), c->word_size()))) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 405, "assert(" "is_aligned(c->base(), c->word_size())" ") failed", "misaligned chunk %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", num_chunk, p2i(c), c->get_state_char(), p2i(c->base()), c->level()); :: breakpoint(); } } while (0); } |
405 | "misaligned chunk %d " METACHUNK_FORMAT ".", num_chunk, METACHUNK_FORMAT_ARGS(c))if (!(is_aligned(c->base(), c->word_size()))) { fdStream errst(2); this->print_on(&errst); do { if (!(is_aligned (c->base(), c->word_size()))) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 405, "assert(" "is_aligned(c->base(), c->word_size())" ") failed", "misaligned chunk %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", num_chunk, p2i(c), c->get_state_char(), p2i(c->base()), c->level()); :: breakpoint(); } } while (0); }; |
406 | |
407 | c->verify_neighborhood(); |
408 | c->verify(); |
409 | expected_next_base = c->end(); |
410 | num_chunk++; |
411 | c = c->next_in_vs(); |
412 | } |
413 | assrt_(expected_next_base == _base + word_size(), "Sanity")if (!(expected_next_base == _base + word_size())) { fdStream errst (2); this->print_on(&errst); do { if (!(expected_next_base == _base + word_size())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 413, "assert(" "expected_next_base == _base + word_size()" ") failed" , "Sanity"); ::breakpoint(); } } while (0); }; |
414 | } |
415 | } |
416 | |
417 | void RootChunkArea::verify_area_is_ideally_merged() const { |
418 | SOMETIMES(assert_lock_strong(Metaspace_lock);){ static int counter_ = 0; if (VerifyMetaspaceInterval > 0 ) { counter_++; if (counter_ >= VerifyMetaspaceInterval) { counter_ = 0; { assert_lock_strong(Metaspace_lock); } } } } |
419 | int num_chunk = 0; |
420 | for (const Metachunk* c = _first_chunk; c != NULL__null; c = c->next_in_vs()) { |
421 | if (!c->is_root_chunk() && c->is_free()) { |
422 | // If a chunk is free, it must not have a buddy which is also free, because |
423 | // those chunks should have been merged. |
424 | // In other words, a buddy shall be either in-use or splintered |
425 | // (which in turn would mean part of it are in use). |
426 | Metachunk* const buddy = c->is_leader() ? c->next_in_vs() : c->prev_in_vs(); |
427 | assrt_(buddy->is_in_use() || buddy->level() > c->level(),if (!(buddy->is_in_use() || buddy->level() > c->level ())) { fdStream errst(2); this->print_on(&errst); do { if (!(buddy->is_in_use() || buddy->level() > c-> level())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 429, "assert(" "buddy->is_in_use() || buddy->level() > c->level()" ") failed", "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " : missed merge opportunity with neighbor " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", num_chunk, p2i(c), c->get_state_char(), p2i (c->base()), c->level(), p2i(buddy), buddy->get_state_char (), p2i(buddy->base()), buddy->level()); ::breakpoint() ; } } while (0); } |
428 | "Chunk No. %d " METACHUNK_FORMAT " : missed merge opportunity with neighbor " METACHUNK_FORMAT ".",if (!(buddy->is_in_use() || buddy->level() > c->level ())) { fdStream errst(2); this->print_on(&errst); do { if (!(buddy->is_in_use() || buddy->level() > c-> level())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 429, "assert(" "buddy->is_in_use() || buddy->level() > c->level()" ") failed", "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " : missed merge opportunity with neighbor " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", num_chunk, p2i(c), c->get_state_char(), p2i (c->base()), c->level(), p2i(buddy), buddy->get_state_char (), p2i(buddy->base()), buddy->level()); ::breakpoint() ; } } while (0); } |
429 | num_chunk, METACHUNK_FORMAT_ARGS(c), METACHUNK_FORMAT_ARGS(buddy))if (!(buddy->is_in_use() || buddy->level() > c->level ())) { fdStream errst(2); this->print_on(&errst); do { if (!(buddy->is_in_use() || buddy->level() > c-> level())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 429, "assert(" "buddy->is_in_use() || buddy->level() > c->level()" ") failed", "Chunk No. %d " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" " : missed merge opportunity with neighbor " "@" "0x%016" "l" "x" ", %c, base " "0x%016" "l" "x" ", level " "lv%.2d" ".", num_chunk, p2i(c), c->get_state_char(), p2i (c->base()), c->level(), p2i(buddy), buddy->get_state_char (), p2i(buddy->base()), buddy->level()); ::breakpoint() ; } } while (0); }; |
430 | } |
431 | num_chunk++; |
432 | } |
433 | } |
434 | |
435 | #endif |
436 | |
437 | void RootChunkArea::print_on(outputStream* st) const { |
438 | st->print(PTR_FORMAT"0x%016" "l" "x" ": ", p2i(base())); |
439 | if (_first_chunk != NULL__null) { |
440 | const Metachunk* c = _first_chunk; |
441 | // 01234567890123 |
442 | const char* letters_for_levels_cap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
443 | const char* letters_for_levels = "abcdefghijklmnopqrstuvwxyz"; |
444 | while (c != NULL__null) { |
445 | const chunklevel_t l = c->level(); |
446 | if (l >= 0 && (size_t)l < strlen(letters_for_levels)) { |
447 | st->print("%c", c->is_free() ? letters_for_levels[c->level()] : letters_for_levels_cap[c->level()]); |
448 | } else { |
449 | // Obviously garbage, but lets not crash. |
450 | st->print("?"); |
451 | } |
452 | c = c->next_in_vs(); |
453 | } |
454 | } else { |
455 | st->print(" (no chunks)"); |
456 | } |
457 | st->cr(); |
458 | } |
459 | |
460 | // Create an array of ChunkTree objects, all initialized to NULL, covering |
461 | // a given memory range. Memory range must be a multiple of root chunk size. |
462 | RootChunkAreaLUT::RootChunkAreaLUT(const MetaWord* base, size_t word_size) : |
463 | _base(base), |
464 | _num((int)(word_size / chunklevel::MAX_CHUNK_WORD_SIZE)), |
465 | _arr(NULL__null) |
466 | { |
467 | assert_is_aligned(word_size, chunklevel::MAX_CHUNK_WORD_SIZE)do { if (!(is_aligned((word_size), (chunklevel::MAX_CHUNK_WORD_SIZE )))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 467, "assert(" "is_aligned((word_size), (chunklevel::MAX_CHUNK_WORD_SIZE))" ") failed", "0x%" "l" "x" " is not aligned to " "0x%" "l" "x" , (size_t)(uintptr_t)word_size, (size_t)(chunklevel::MAX_CHUNK_WORD_SIZE )); ::breakpoint(); } } while (0); |
468 | _arr = NEW_C_HEAP_ARRAY(RootChunkArea, _num, mtClass)(RootChunkArea*) (AllocateHeap((_num) * sizeof(RootChunkArea) , mtClass)); |
469 | const MetaWord* this_base = _base; |
470 | for (int i = 0; i < _num; i++) { |
471 | RootChunkArea* rca = new(_arr + i) RootChunkArea(this_base); |
472 | assert(rca == _arr + i, "Sanity")do { if (!(rca == _arr + i)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/memory/metaspace/rootChunkArea.cpp" , 472, "assert(" "rca == _arr + i" ") failed", "Sanity"); ::breakpoint (); } } while (0); |
473 | this_base += chunklevel::MAX_CHUNK_WORD_SIZE; |
474 | } |
475 | } |
476 | |
477 | RootChunkAreaLUT::~RootChunkAreaLUT() { |
478 | for (int i = 0; i < _num; i++) { |
479 | _arr[i].~RootChunkArea(); |
480 | } |
481 | FREE_C_HEAP_ARRAY(RootChunkArea, _arr)FreeHeap((char*)(_arr)); |
482 | } |
483 | |
484 | #ifdef ASSERT1 |
485 | |
486 | void RootChunkAreaLUT::verify() const { |
487 | for (int i = 0; i < _num; i++) { |
488 | check_pointer(_arr[i].base()); |
489 | _arr[i].verify(); |
490 | } |
491 | } |
492 | |
493 | #endif |
494 | |
495 | void RootChunkAreaLUT::print_on(outputStream* st) const { |
496 | for (int i = 0; i < _num; i++) { |
497 | st->print("%2d:", i); |
498 | _arr[i].print_on(st); |
499 | } |
500 | } |
501 | |
502 | } // end: namespace metaspace |