Path: blob/master/src/hotspot/share/memory/metaspace/freeChunkList.cpp
40957 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2020 SAP SE. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "memory/metaspace/freeChunkList.hpp"27#include "utilities/debug.hpp"28#include "utilities/globalDefinitions.hpp"29#include "utilities/ostream.hpp"3031namespace metaspace {3233// Calculates total number of committed words over all chunks (walks chunks).34size_t FreeChunkList::calc_committed_word_size() const {35size_t s = 0;36for (const Metachunk* c = _first; c != NULL; c = c->next()) {37s += c->committed_words();38}39return s;40}4142void FreeChunkList::print_on(outputStream* st) const {43if (_num_chunks.get() > 0) {44for (const Metachunk* c = _first; c != NULL; c = c->next()) {45st->print(" - <");46c->print_on(st);47st->print(">");48}49st->print(" - total : %d chunks.", _num_chunks.get());50} else {51st->print("empty");52}53}5455#ifdef ASSERT5657bool FreeChunkList::contains(const Metachunk* c) const {58for (Metachunk* c2 = _first; c2 != NULL; c2 = c2->next()) {59if (c2 == c) {60return true;61}62}63return false;64}6566void FreeChunkList::verify() const {67if (_first == NULL) {68assert(_last == NULL, "Sanity");69} else {70assert(_last != NULL, "Sanity");71int num = 0;72bool uncommitted = (_first->committed_words() == 0);73for (Metachunk* c = _first; c != NULL; c = c->next()) {74assert(c->is_free(), "Chunks in freelist should be free");75assert(c->used_words() == 0, "Chunk in freelist should have not used words.");76assert(c->level() == _first->level(), "wrong level");77assert(c->next() == NULL || c->next()->prev() == c, "front link broken");78assert(c->prev() == NULL || c->prev()->next() == c, "back link broken");79assert(c != c->prev() && c != c->next(), "circle");80c->verify();81num++;82}83_num_chunks.check(num);84}85}8687#endif // ASSERT8889// Returns total size in all lists (regardless of commit state of underlying memory)90size_t FreeChunkListVector::word_size() const {91size_t sum = 0;92for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {93sum += list_for_level(l)->num_chunks() * chunklevel::word_size_for_level(l);94}95return sum;96}9798// Calculates total number of committed words over all chunks (walks chunks).99size_t FreeChunkListVector::calc_committed_word_size() const {100size_t sum = 0;101for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {102sum += calc_committed_word_size_at_level(l);103}104return sum;105}106107size_t FreeChunkListVector::calc_committed_word_size_at_level(chunklevel_t lvl) const {108return list_for_level(lvl)->calc_committed_word_size();109}110111// Returns total committed size in all lists112int FreeChunkListVector::num_chunks() const {113int n = 0;114for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {115n += list_for_level(l)->num_chunks();116}117return n;118}119120// Look for a chunk: starting at level, up to and including max_level,121// return the first chunk whose committed words >= min_committed_words.122// Return NULL if no such chunk was found.123Metachunk* FreeChunkListVector::search_chunk_ascending(chunklevel_t level, chunklevel_t max_level, size_t min_committed_words) {124assert(min_committed_words <= chunklevel::word_size_for_level(max_level),125"min chunk size too small to hold min_committed_words");126for (chunklevel_t l = level; l <= max_level; l++) {127FreeChunkList* list = list_for_level(l);128Metachunk* c = list->first_minimally_committed(min_committed_words);129if (c != NULL) {130list->remove(c);131return c;132}133}134return NULL;135}136137// Look for a chunk: starting at level, down to (including) the root chunk level,138// return the first chunk whose committed words >= min_committed_words.139// Return NULL if no such chunk was found.140Metachunk* FreeChunkListVector::search_chunk_descending(chunklevel_t level, size_t min_committed_words) {141for (chunklevel_t l = level; l >= chunklevel::LOWEST_CHUNK_LEVEL; l --) {142FreeChunkList* list = list_for_level(l);143Metachunk* c = list->first_minimally_committed(min_committed_words);144if (c != NULL) {145list->remove(c);146return c;147}148}149return NULL;150}151152void FreeChunkListVector::print_on(outputStream* st) const {153for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {154st->print("-- List[" CHKLVL_FORMAT "]: ", l);155list_for_level(l)->print_on(st);156st->cr();157}158st->print_cr("total chunks: %d, total word size: " SIZE_FORMAT ".",159num_chunks(), word_size());160}161162#ifdef ASSERT163164void FreeChunkListVector::verify() const {165for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {166list_for_level(l)->verify();167}168}169170bool FreeChunkListVector::contains(const Metachunk* c) const {171for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {172if (list_for_level(l)->contains(c)) {173return true;174}175}176return false;177}178179#endif // ASSERT180181} // namespace metaspace182183184185