2128 void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) {
2129 if (chunks == NULL) {
2130 return;
2131 }
2132 ChunkList* list = free_chunks(index);
2133 assert(list->size() == chunks->word_size(), "Mismatch in chunk sizes");
2134 assert_lock_strong(SpaceManager::expand_lock());
2135 Metachunk* cur = chunks;
2136
2137 // This returns chunks one at a time. If a new
2138 // class List can be created that is a base class
2139 // of FreeList then something like FreeList::prepend()
2140 // can be used in place of this loop
2141 while (cur != NULL) {
2142 assert(cur->container() != NULL, "Container should have been set");
2143 cur->container()->dec_container_count();
2144 // Capture the next link before it is changed
2145 // by the call to return_chunk_at_head();
2146 Metachunk* next = cur->next();
2147 DEBUG_ONLY(cur->set_is_tagged_free(true);)
2148 list->return_chunk_at_head(cur);
2149 cur = next;
2150 }
2151 }
2152
2153 SpaceManager::~SpaceManager() {
2154 // This call this->_lock which can't be done while holding expand_lock()
2155 assert(sum_capacity_in_chunks_in_use() == allocated_chunks_words(),
2156 "sum_capacity_in_chunks_in_use() " SIZE_FORMAT
2157 " allocated_chunks_words() " SIZE_FORMAT,
2158 sum_capacity_in_chunks_in_use(), allocated_chunks_words());
2159
2160 MutexLockerEx fcl(SpaceManager::expand_lock(),
2161 Mutex::_no_safepoint_check_flag);
2162
2163 chunk_manager()->slow_locked_verify();
2164
2165 dec_total_from_size_metrics();
2166
2167 LogHandle(gc, metaspace, freelist) log;
2192 set_chunks_in_use(i, NULL);
2193 log.trace("updated freelist count " SSIZE_FORMAT " %s", chunk_manager()->free_chunks(i)->count(), chunk_size_name(i));
2194 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
2195 }
2196
2197 // The medium chunk case may be optimized by passing the head and
2198 // tail of the medium chunk list to add_at_head(). The tail is often
2199 // the current chunk but there are probably exceptions.
2200
2201 // Humongous chunks
2202 log.trace("returned " SIZE_FORMAT " %s humongous chunks to dictionary",
2203 sum_count_in_chunks_in_use(HumongousIndex), chunk_size_name(HumongousIndex));
2204 log.trace("Humongous chunk dictionary: ");
2205 // Humongous chunks are never the current chunk.
2206 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
2207
2208 while (humongous_chunks != NULL) {
2209 #ifdef ASSERT
2210 humongous_chunks->set_is_tagged_free(true);
2211 #endif
2212 log.trace(PTR_FORMAT " (" SIZE_FORMAT ") ", p2i(humongous_chunks), humongous_chunks->word_size());
2213 assert(humongous_chunks->word_size() == (size_t)
2214 align_size_up(humongous_chunks->word_size(),
2215 smallest_chunk_size()),
2216 "Humongous chunk size is wrong: word size " SIZE_FORMAT
2217 " granularity " SIZE_FORMAT,
2218 humongous_chunks->word_size(), smallest_chunk_size());
2219 Metachunk* next_humongous_chunks = humongous_chunks->next();
2220 humongous_chunks->container()->dec_container_count();
2221 chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
2222 humongous_chunks = next_humongous_chunks;
2223 }
2224 log.trace("updated dictionary count " SIZE_FORMAT " %s", chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex));
2225 chunk_manager()->slow_locked_verify();
2226 }
2227
2228 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
2229 switch (index) {
2230 case SpecializedIndex:
2231 return "Specialized";
|
2128 void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) {
2129 if (chunks == NULL) {
2130 return;
2131 }
2132 ChunkList* list = free_chunks(index);
2133 assert(list->size() == chunks->word_size(), "Mismatch in chunk sizes");
2134 assert_lock_strong(SpaceManager::expand_lock());
2135 Metachunk* cur = chunks;
2136
2137 // This returns chunks one at a time. If a new
2138 // class List can be created that is a base class
2139 // of FreeList then something like FreeList::prepend()
2140 // can be used in place of this loop
2141 while (cur != NULL) {
2142 assert(cur->container() != NULL, "Container should have been set");
2143 cur->container()->dec_container_count();
2144 // Capture the next link before it is changed
2145 // by the call to return_chunk_at_head();
2146 Metachunk* next = cur->next();
2147 DEBUG_ONLY(cur->set_is_tagged_free(true);)
2148 NOT_PRODUCT(cur->zap();)
2149 list->return_chunk_at_head(cur);
2150 cur = next;
2151 }
2152 }
2153
2154 SpaceManager::~SpaceManager() {
2155 // This call this->_lock which can't be done while holding expand_lock()
2156 assert(sum_capacity_in_chunks_in_use() == allocated_chunks_words(),
2157 "sum_capacity_in_chunks_in_use() " SIZE_FORMAT
2158 " allocated_chunks_words() " SIZE_FORMAT,
2159 sum_capacity_in_chunks_in_use(), allocated_chunks_words());
2160
2161 MutexLockerEx fcl(SpaceManager::expand_lock(),
2162 Mutex::_no_safepoint_check_flag);
2163
2164 chunk_manager()->slow_locked_verify();
2165
2166 dec_total_from_size_metrics();
2167
2168 LogHandle(gc, metaspace, freelist) log;
2193 set_chunks_in_use(i, NULL);
2194 log.trace("updated freelist count " SSIZE_FORMAT " %s", chunk_manager()->free_chunks(i)->count(), chunk_size_name(i));
2195 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
2196 }
2197
2198 // The medium chunk case may be optimized by passing the head and
2199 // tail of the medium chunk list to add_at_head(). The tail is often
2200 // the current chunk but there are probably exceptions.
2201
2202 // Humongous chunks
2203 log.trace("returned " SIZE_FORMAT " %s humongous chunks to dictionary",
2204 sum_count_in_chunks_in_use(HumongousIndex), chunk_size_name(HumongousIndex));
2205 log.trace("Humongous chunk dictionary: ");
2206 // Humongous chunks are never the current chunk.
2207 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
2208
2209 while (humongous_chunks != NULL) {
2210 #ifdef ASSERT
2211 humongous_chunks->set_is_tagged_free(true);
2212 #endif
2213 NOT_PRODUCT(humongous_chunks->zap();)
2214 log.trace(PTR_FORMAT " (" SIZE_FORMAT ") ", p2i(humongous_chunks), humongous_chunks->word_size());
2215 assert(humongous_chunks->word_size() == (size_t)
2216 align_size_up(humongous_chunks->word_size(),
2217 smallest_chunk_size()),
2218 "Humongous chunk size is wrong: word size " SIZE_FORMAT
2219 " granularity " SIZE_FORMAT,
2220 humongous_chunks->word_size(), smallest_chunk_size());
2221 Metachunk* next_humongous_chunks = humongous_chunks->next();
2222 humongous_chunks->container()->dec_container_count();
2223 chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
2224 humongous_chunks = next_humongous_chunks;
2225 }
2226 log.trace("updated dictionary count " SIZE_FORMAT " %s", chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex));
2227 chunk_manager()->slow_locked_verify();
2228 }
2229
2230 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
2231 switch (index) {
2232 case SpecializedIndex:
2233 return "Specialized";
|