author | stuefe |
Thu, 17 Oct 2019 16:39:45 +0200 | |
branch | stuefe-new-metaspace-branch |
changeset 58683 | 2d5dd194c65c |
parent 58227 | 0e7d9a23261e |
permissions | -rw-r--r-- |
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
1 |
/* |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
2 |
* Copyright (c) 2019 SAP SE. All rights reserved. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
3 |
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
4 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
5 |
* |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
6 |
* This code is free software; you can redistribute it and/or modify it |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
7 |
* under the terms of the GNU General Public License version 2 only, as |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
8 |
* published by the Free Software Foundation. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
9 |
* |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
10 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
11 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
12 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
13 |
* version 2 for more details (a copy is included in the LICENSE file that |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
14 |
* accompanied this code). |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
15 |
* |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
16 |
* You should have received a copy of the GNU General Public License version |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
17 |
* 2 along with this work; if not, write to the Free Software Foundation, |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
18 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
19 |
* |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
20 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
21 |
* or visit www.oracle.com if you need additional information or have any |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
22 |
* questions. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
23 |
* |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
24 |
*/ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
25 |
#include "precompiled.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
26 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
27 |
#include "logging/log.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
28 |
#include "memory/allocation.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
29 |
#include "memory/metaspace/chunkHeaderPool.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
30 |
#include "memory/metaspace/chunkManager.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
31 |
#include "memory/metaspace/internStat.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
32 |
#include "memory/metaspace/metachunk.hpp" |
58683 | 33 |
#include "memory/metaspace/metaDebug.hpp" |
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
34 |
#include "memory/metaspace/metaspaceCommon.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
35 |
#include "memory/metaspace/rootChunkArea.hpp" |
58227 | 36 |
#include "runtime/mutexLocker.hpp" |
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
37 |
#include "utilities/debug.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
38 |
#include "utilities/globalDefinitions.hpp" |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
39 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
40 |
namespace metaspace { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
41 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
42 |
RootChunkArea::RootChunkArea(const MetaWord* base) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
43 |
: _base(base), _first_chunk(NULL) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
44 |
{} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
45 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
46 |
RootChunkArea::~RootChunkArea() { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
47 |
// This is called when a VirtualSpaceNode is destructed (purged). |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
48 |
// All chunks should be free of course. In fact, there should only |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
49 |
// be one chunk, since all free chunks should have been merged. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
50 |
if (_first_chunk != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
51 |
assert(_first_chunk->is_root_chunk() && _first_chunk->is_free(), |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
52 |
"Cannot delete root chunk area if not all chunks are free."); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
53 |
ChunkHeaderPool::pool().return_chunk_header(_first_chunk); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
54 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
55 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
56 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
57 |
// Initialize: allocate a root node and a root chunk header; return the |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
58 |
// root chunk header. It will be partly initialized. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
59 |
// Note: this just allocates a memory-less header; memory itself is allocated inside VirtualSpaceNode. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
60 |
Metachunk* RootChunkArea::alloc_root_chunk_header(VirtualSpaceNode* node) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
61 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
62 |
assert(_first_chunk == 0, "already have a root"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
63 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
64 |
Metachunk* c = ChunkHeaderPool::pool().allocate_chunk_header(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
65 |
c->initialize(node, const_cast<MetaWord*>(_base), chklvl::ROOT_CHUNK_LEVEL); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
66 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
67 |
_first_chunk = c; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
68 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
69 |
return c; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
70 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
71 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
72 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
73 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
74 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
75 |
// Given a chunk c, split it recursively until you get a chunk of the given target_level. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
76 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
77 |
// The original chunk must not be part of a freelist. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
78 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
79 |
// Returns pointer to the result chunk; the splitted-off chunks are added as |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
80 |
// free chunks to the freelists. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
81 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
82 |
// Returns NULL if chunk cannot be split at least once. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
83 |
Metachunk* RootChunkArea::split(chklvl_t target_level, Metachunk* c, MetachunkListCluster* freelists) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
84 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
85 |
// Splitting a chunk once works like this: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
86 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
87 |
// For a given chunk we want to split: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
88 |
// - increase the chunk level (which halves its size) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
89 |
// - (but leave base address as it is since it will be the leader of the newly |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
90 |
// created chunk pair) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
91 |
// - then create a new chunk header of the same level, set its memory range |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
92 |
// to cover the second halfof the old chunk. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
93 |
// - wire them up (prev_in_vs/next_in_vs) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
94 |
// - return the follower chunk as "splinter chunk" in the splinters array. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
95 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
96 |
// Doing this multiple times will create a new free splinter chunk for every |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
97 |
// level we split: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
98 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
99 |
// A <- original chunk |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
100 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
101 |
// B B <- split into two halves |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
102 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
103 |
// C C B <- first half split again |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
104 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
105 |
// D D C B <- first half split again ... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
106 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
107 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
108 |
// As an optimization, since we usually do not split once but multiple times, |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
109 |
// to not do each split separately, since we would have to wire up prev_in_vs/next_in_vs |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
110 |
// on every level just to tear it open in the next level when we reintroduce a new |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
111 |
// half chunk splinter. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
112 |
// Instead, just split split split and delay building up the double linked list of the |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
113 |
// new chunks at the end of all splits. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
114 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
115 |
DEBUG_ONLY(check_pointer(c->base());) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
116 |
assert(c->is_free(), "Can only split free chunks."); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
117 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
118 |
DEBUG_ONLY(chklvl::check_valid_level(target_level)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
119 |
assert(target_level > c->level(), "Wrong target level"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
120 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
121 |
const chklvl_t starting_level = c->level(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
122 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
123 |
Metachunk* result = c; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
124 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
125 |
log_trace(metaspace)("Splitting chunk @" PTR_FORMAT ", base " PTR_FORMAT ", level " CHKLVL_FORMAT "...", |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
126 |
p2i(c), p2i(c->base()), c->level()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
127 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
128 |
while (result->level() < target_level) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
129 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
130 |
result->inc_level(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
131 |
Metachunk* splinter_chunk = ChunkHeaderPool::pool().allocate_chunk_header(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
132 |
splinter_chunk->initialize(result->vsnode(), result->end(), result->level()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
133 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
134 |
// Fix committed words info: If over the half of the original chunk was |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
135 |
// committed, committed area spills over into the follower chunk. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
136 |
const size_t old_committed_words = result->committed_words(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
137 |
if (old_committed_words > result->word_size()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
138 |
result->set_committed_words(result->word_size()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
139 |
splinter_chunk->set_committed_words(old_committed_words - result->word_size()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
140 |
} else { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
141 |
splinter_chunk->set_committed_words(0); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
142 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
143 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
144 |
// Insert splinter chunk into vs list |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
145 |
if (result->next_in_vs() != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
146 |
result->next_in_vs()->set_prev_in_vs(splinter_chunk); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
147 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
148 |
splinter_chunk->set_next_in_vs(result->next_in_vs()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
149 |
splinter_chunk->set_prev_in_vs(result); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
150 |
result->set_next_in_vs(splinter_chunk); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
151 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
152 |
log_trace(metaspace)("Created splinter chunk @" PTR_FORMAT ", base " PTR_FORMAT ", level " CHKLVL_FORMAT "...", |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
153 |
p2i(splinter_chunk), p2i(splinter_chunk->base()), splinter_chunk->level()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
154 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
155 |
// Add splinter to free lists |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
156 |
freelists->add(splinter_chunk); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
157 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
158 |
DEBUG_ONLY(InternalStats::inc_num_chunks_added_to_freelist_due_to_split();) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
159 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
160 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
161 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
162 |
assert(result->level() == target_level, "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
163 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
164 |
DEBUG_ONLY(verify(true);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
165 |
DEBUG_ONLY(result->verify(true);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
166 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
167 |
DEBUG_ONLY(InternalStats::inc_num_chunk_splits();) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
168 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
169 |
return result; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
170 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
171 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
172 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
173 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
174 |
// Given a chunk, attempt to merge it recursively with its neighboring chunks. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
175 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
176 |
// If successful (merged at least once), returns address of |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
177 |
// the merged chunk; NULL otherwise. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
178 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
179 |
// The merged chunks are removed from the freelists. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
180 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
181 |
// !!! Please note that if this method returns a non-NULL value, the |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
182 |
// original chunk will be invalid and should not be accessed anymore! !!! |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
183 |
Metachunk* RootChunkArea::merge(Metachunk* c, MetachunkListCluster* freelists) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
184 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
185 |
// Note rules: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
186 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
187 |
// - a chunk always has a buddy, unless it is a root chunk. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
188 |
// - In that buddy pair, a chunk is either leader or follower. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
189 |
// - a chunk's base address is always aligned at its size. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
190 |
// - if chunk is leader, its base address is also aligned to the size of the next |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
191 |
// lower level, at least. A follower chunk is not. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
192 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
193 |
// How we merge once: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
194 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
195 |
// For a given chunk c, which has to be free and non-root, we do: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
196 |
// - find out if we are the leader or the follower chunk |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
197 |
// - if we are leader, next_in_vs must be the follower; if we are follower, |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
198 |
// prev_in_vs must be the leader. Now we have the buddy chunk. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
199 |
// - However, if the buddy chunk itself is split (of a level higher than us) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
200 |
// we cannot merge. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
201 |
// - we can only merge if the buddy is of the same level as we are and it is |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
202 |
// free. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
203 |
// - Then we merge by simply removing the follower chunk from the address range |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
204 |
// linked list (returning the now useless header to the pool) and decreasing |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
205 |
// the leader chunk level by one. That makes it double the size. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
206 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
207 |
// Example: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
208 |
// (lower case chunks are free, the * indicates the chunk we want to merge): |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
209 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
210 |
// ........................ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
211 |
// d d*c b A <- we return the second (d*) chunk... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
212 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
213 |
// c* c b A <- we merge it with its predecessor and decrease its level... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
214 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
215 |
// b* b A <- we merge it again, since its new neighbor was free too... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
216 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
217 |
// a* A <- we merge it again, since its new neighbor was free too... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
218 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
219 |
// And we are done, since its new neighbor, (A), is not free. We would also be done |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
220 |
// if the new neighbor itself is splintered. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
221 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
222 |
DEBUG_ONLY(check_pointer(c->base());) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
223 |
assert(!c->is_root_chunk(), "Cannot be merged further."); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
224 |
assert(c->is_free(), "Can only merge free chunks."); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
225 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
226 |
DEBUG_ONLY(c->verify(false);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
227 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
228 |
log_trace(metaspace)("Attempting to merge chunk " METACHUNK_FORMAT ".", METACHUNK_FORMAT_ARGS(c)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
229 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
230 |
const chklvl_t starting_level = c->level(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
231 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
232 |
bool stop = false; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
233 |
Metachunk* result = NULL; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
234 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
235 |
do { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
236 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
237 |
// First find out if this chunk is the leader of its pair |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
238 |
const bool is_leader = c->is_leader(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
239 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
240 |
// Note: this is either our buddy or a splinter of the buddy. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
241 |
Metachunk* const buddy = c->is_leader() ? c->next_in_vs() : c->prev_in_vs(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
242 |
DEBUG_ONLY(buddy->verify(true);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
243 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
244 |
// A buddy chunk must be of the same or higher level (so, same size or smaller) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
245 |
// never be larger. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
246 |
assert(buddy->level() >= c->level(), "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
247 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
248 |
// Is this really my buddy (same level) or a splinter of it (higher level)? |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
249 |
// Also, is it free? |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
250 |
if (buddy->level() != c->level() || buddy->is_free() == false) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
251 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
252 |
log_trace(metaspace)("cannot merge with chunk " METACHUNK_FORMAT ".", METACHUNK_FORMAT_ARGS(buddy)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
253 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
254 |
stop = true; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
255 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
256 |
} else { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
257 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
258 |
log_trace(metaspace)("will merge with chunk " METACHUNK_FORMAT ".", METACHUNK_FORMAT_ARGS(buddy)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
259 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
260 |
// We can merge with the buddy. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
261 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
262 |
// First, remove buddy from the chunk manager. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
263 |
assert(buddy->is_free(), "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
264 |
freelists->remove(buddy); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
265 |
DEBUG_ONLY(InternalStats::inc_num_chunks_removed_from_freelist_due_to_merge();) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
266 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
267 |
// Determine current leader and follower |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
268 |
Metachunk* leader; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
269 |
Metachunk* follower; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
270 |
if (is_leader) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
271 |
leader = c; follower = buddy; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
272 |
} else { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
273 |
leader = buddy; follower = c; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
274 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
275 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
276 |
// Last checkpoint |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
277 |
assert(leader->end() == follower->base() && |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
278 |
leader->level() == follower->level() && |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
279 |
leader->is_free() && follower->is_free(), "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
280 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
281 |
// The new merged chunk is as far committed as possible (if leader |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
282 |
// chunk is fully committed, as far as the follower chunk). |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
283 |
size_t merged_committed_words = leader->committed_words(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
284 |
if (merged_committed_words == leader->word_size()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
285 |
merged_committed_words += follower->committed_words(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
286 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
287 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
288 |
// Leader survives, follower chunk is freed. Remove follower from vslist .. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
289 |
leader->set_next_in_vs(follower->next_in_vs()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
290 |
if (follower->next_in_vs() != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
291 |
follower->next_in_vs()->set_prev_in_vs(leader); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
292 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
293 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
294 |
// .. and return follower chunk header to pool for reuse. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
295 |
ChunkHeaderPool::pool().return_chunk_header(follower); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
296 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
297 |
// Leader level gets decreased (leader chunk doubles in size) but |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
298 |
// base address stays the same. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
299 |
leader->dec_level(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
300 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
301 |
// set commit boundary |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
302 |
leader->set_committed_words(merged_committed_words); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
303 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
304 |
// If the leader is now of root chunk size, stop merging |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
305 |
if (leader->is_root_chunk()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
306 |
stop = true; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
307 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
308 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
309 |
result = c = leader; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
310 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
311 |
DEBUG_ONLY(leader->verify(true);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
312 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
313 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
314 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
315 |
} while (!stop); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
316 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
317 |
#ifdef ASSERT |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
318 |
verify(true); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
319 |
if (result != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
320 |
result->verify(true); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
321 |
if (result->level() < starting_level) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
322 |
DEBUG_ONLY(InternalStats::inc_num_chunk_merges();) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
323 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
324 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
325 |
#endif // ASSERT |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
326 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
327 |
return result; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
328 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
329 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
330 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
331 |
// Given a chunk c, which must be "in use" and must not be a root chunk, attempt to |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
332 |
// enlarge it in place by claiming its trailing buddy. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
333 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
334 |
// This will only work if c is the leader of the buddy pair and the trailing buddy is free. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
335 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
336 |
// If successful, the follower chunk will be removed from the freelists, the leader chunk c will |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
337 |
// double in size (level decreased by one). |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
338 |
// |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
339 |
// On success, true is returned, false otherwise. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
340 |
bool RootChunkArea::attempt_enlarge_chunk(Metachunk* c, MetachunkListCluster* freelists) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
341 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
342 |
DEBUG_ONLY(check_pointer(c->base());) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
343 |
assert(!c->is_root_chunk(), "Cannot be merged further."); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
344 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
345 |
// There is no real reason for this limitation other than it is not |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
346 |
// needed on free chunks since they should be merged already: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
347 |
assert(c->is_in_use(), "Can only enlarge in use chunks."); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
348 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
349 |
DEBUG_ONLY(c->verify(false);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
350 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
351 |
if (!c->is_leader()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
352 |
return false; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
353 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
354 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
355 |
// We are the leader, so the buddy must follow us. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
356 |
Metachunk* const buddy = c->next_in_vs(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
357 |
DEBUG_ONLY(buddy->verify(true);) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
358 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
359 |
// Of course buddy cannot be larger than us. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
360 |
assert(buddy->level() >= c->level(), "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
361 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
362 |
// We cannot merge buddy in if it is not free... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
363 |
if (!buddy->is_free()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
364 |
return false; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
365 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
366 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
367 |
// ... nor if it is splintered. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
368 |
if (buddy->level() != c->level()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
369 |
return false; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
370 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
371 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
372 |
// Okay, lets enlarge c. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
373 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
374 |
log_trace(metaspace)("Enlarging chunk " METACHUNK_FULL_FORMAT " by merging in follower " METACHUNK_FULL_FORMAT ".", |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
375 |
METACHUNK_FULL_FORMAT_ARGS(c), METACHUNK_FULL_FORMAT_ARGS(buddy)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
376 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
377 |
// the enlarged c is as far committed as possible: |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
378 |
size_t merged_committed_words = c->committed_words(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
379 |
if (merged_committed_words == c->word_size()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
380 |
merged_committed_words += buddy->committed_words(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
381 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
382 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
383 |
// Remove buddy from vs list... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
384 |
Metachunk* successor = buddy->next_in_vs(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
385 |
if (successor != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
386 |
successor->set_prev_in_vs(c); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
387 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
388 |
c->set_next_in_vs(successor); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
389 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
390 |
// .. and from freelist ... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
391 |
freelists->remove(buddy); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
392 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
393 |
// .. and return its empty husk to the pool... |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
394 |
ChunkHeaderPool::pool().return_chunk_header(buddy); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
395 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
396 |
// Then decrease level of c. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
397 |
c->dec_level(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
398 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
399 |
// and correct committed words if needed. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
400 |
c->set_committed_words(merged_committed_words); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
401 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
402 |
log_debug(metaspace)("Enlarged chunk " METACHUNK_FULL_FORMAT ".", METACHUNK_FULL_FORMAT_ARGS(c)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
403 |
// log_debug(metaspace)("Enlarged chunk " METACHUNK_FORMAT ".", METACHUNK_FORMAT_ARGS(c)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
404 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
405 |
DEBUG_ONLY(verify(true)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
406 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
407 |
return true; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
408 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
409 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
410 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
411 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
412 |
#ifdef ASSERT |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
413 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
414 |
#define assrt_(cond, ...) \ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
415 |
if (!(cond)) { \ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
416 |
fdStream errst(2); \ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
417 |
this->print_on(&errst); \ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
418 |
vmassert(cond, __VA_ARGS__); \ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
419 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
420 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
421 |
void RootChunkArea::verify(bool slow) const { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
422 |
|
58683 | 423 |
|
58227 | 424 |
assert_lock_strong(MetaspaceExpand_lock); |
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
425 |
assert_is_aligned(_base, chklvl::MAX_CHUNK_BYTE_SIZE); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
426 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
427 |
// Iterate thru all chunks in this area. They must be ordered correctly, |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
428 |
// being adjacent to each other, and cover the complete area |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
429 |
int num_chunk = 0; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
430 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
431 |
if (_first_chunk != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
432 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
433 |
assrt_(_first_chunk->prev_in_vs() == NULL, "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
434 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
435 |
const Metachunk* c = _first_chunk; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
436 |
const MetaWord* expected_next_base = _base; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
437 |
const MetaWord* const area_end = _base + word_size(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
438 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
439 |
while (c != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
440 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
441 |
assrt_(c->base() == expected_next_base, |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
442 |
"Chunk No. %d " METACHUNK_FORMAT " - unexpected base.", |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
443 |
num_chunk, METACHUNK_FORMAT_ARGS(c)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
444 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
445 |
assrt_(c->base() >= base() && c->end() <= end(), |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
446 |
"chunk %d " METACHUNK_FORMAT " oob for this root area [" PTR_FORMAT ".." PTR_FORMAT ").", |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
447 |
num_chunk, METACHUNK_FORMAT_ARGS(c), p2i(base()), p2i(end())); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
448 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
449 |
assrt_(is_aligned(c->base(), c->word_size()), |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
450 |
"misaligned chunk %d " METACHUNK_FORMAT ".", num_chunk, METACHUNK_FORMAT_ARGS(c)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
451 |
|
58227 | 452 |
c->verify_neighborhood(); |
453 |
c->verify(slow); |
|
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
454 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
455 |
expected_next_base = c->end(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
456 |
num_chunk ++; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
457 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
458 |
c = c->next_in_vs(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
459 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
460 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
461 |
assrt_(expected_next_base == _base + word_size(), "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
462 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
463 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
464 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
465 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
466 |
void RootChunkArea::verify_area_is_ideally_merged() const { |
58227 | 467 |
|
58683 | 468 |
SOMETIMES(assert_lock_strong(MetaspaceExpand_lock);) |
58227 | 469 |
|
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
470 |
int num_chunk = 0; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
471 |
for (const Metachunk* c = _first_chunk; c != NULL; c = c->next_in_vs()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
472 |
if (!c->is_root_chunk() && c->is_free()) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
473 |
// If a chunk is free, it must not have a buddy which is also free, because |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
474 |
// those chunks should have been merged. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
475 |
// In other words, a buddy shall be either in-use or splintered |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
476 |
// (which in turn would mean part of it are in use). |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
477 |
Metachunk* const buddy = c->is_leader() ? c->next_in_vs() : c->prev_in_vs(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
478 |
assrt_(buddy->is_in_use() || buddy->level() > c->level(), |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
479 |
"Chunk No. %d " METACHUNK_FORMAT " : missed merge opportunity with neighbor " METACHUNK_FORMAT ".", |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
480 |
num_chunk, METACHUNK_FORMAT_ARGS(c), METACHUNK_FORMAT_ARGS(buddy)); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
481 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
482 |
num_chunk ++; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
483 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
484 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
485 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
486 |
#endif |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
487 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
488 |
void RootChunkArea::print_on(outputStream* st) const { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
489 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
490 |
st->print(PTR_FORMAT ": ", p2i(base())); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
491 |
if (_first_chunk != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
492 |
const Metachunk* c = _first_chunk; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
493 |
// 01234567890123 |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
494 |
const char* letters_for_levels_cap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
495 |
const char* letters_for_levels = "abcdefghijklmnopqrstuvwxyz"; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
496 |
while (c != NULL) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
497 |
const chklvl_t l = c->level(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
498 |
if (l >= 0 && (size_t)l < strlen(letters_for_levels)) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
499 |
// c->print_on(st); st->cr(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
500 |
st->print("%c", c->is_free() ? letters_for_levels[c->level()] : letters_for_levels_cap[c->level()]); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
501 |
} else { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
502 |
// Obviously garbage, but lets not crash. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
503 |
st->print("?"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
504 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
505 |
c = c->next_in_vs(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
506 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
507 |
} else { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
508 |
st->print(" (no chunks)"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
509 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
510 |
st->cr(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
511 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
512 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
513 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
514 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
515 |
// Create an array of ChunkTree objects, all initialized to NULL, covering |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
516 |
// a given memory range. Memory range must be a multiple of root chunk size. |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
517 |
RootChunkAreaLUT::RootChunkAreaLUT(const MetaWord* base, size_t word_size) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
518 |
: _base(base), |
58099 | 519 |
_num((int)(word_size / chklvl::MAX_CHUNK_WORD_SIZE)), |
58063
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
520 |
_arr(NULL) |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
521 |
{ |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
522 |
assert_is_aligned(word_size, chklvl::MAX_CHUNK_WORD_SIZE); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
523 |
_arr = NEW_C_HEAP_ARRAY(RootChunkArea, _num, mtClass); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
524 |
const MetaWord* this_base = _base; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
525 |
for (int i = 0; i < _num; i ++) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
526 |
RootChunkArea* rca = new(_arr + i) RootChunkArea(this_base); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
527 |
assert(rca == _arr + i, "Sanity"); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
528 |
this_base += chklvl::MAX_CHUNK_WORD_SIZE; |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
529 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
530 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
531 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
532 |
RootChunkAreaLUT::~RootChunkAreaLUT() { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
533 |
for (int i = 0; i < _num; i ++) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
534 |
_arr[i].~RootChunkArea(); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
535 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
536 |
FREE_C_HEAP_ARRAY(RootChunkArea, _arr); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
537 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
538 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
539 |
#ifdef ASSERT |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
540 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
541 |
void RootChunkAreaLUT::verify(bool slow) const { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
542 |
for (int i = 0; i < _num; i ++) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
543 |
check_pointer(_arr[i].base()); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
544 |
_arr[i].verify(slow); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
545 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
546 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
547 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
548 |
#endif |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
549 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
550 |
void RootChunkAreaLUT::print_on(outputStream* st) const { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
551 |
for (int i = 0; i < _num; i ++) { |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
552 |
st->print("%2d:", i); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
553 |
_arr[i].print_on(st); |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
554 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
555 |
} |
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
556 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
557 |
|
bdf136b8ae0e
Initial changes for new metaspace. Only tested for Linux x64.
stuefe
parents:
diff
changeset
|
558 |
} // end: namespace metaspace |