Path: blob/master/src/hotspot/share/memory/metaspace/commitMask.hpp
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#ifndef SHARE_MEMORY_METASPACE_COMMITMASK_HPP26#define SHARE_MEMORY_METASPACE_COMMITMASK_HPP2728#include "utilities/bitMap.hpp"29#include "utilities/debug.hpp"30#include "utilities/globalDefinitions.hpp"3132class outputStream;3334namespace metaspace {3536// The CommitMask is a bitmask used to store the commit state of commit granules.37// It keeps one bit per granule; 1 means committed, 0 means uncommitted.3839class CommitMask : public CHeapBitMap {4041const MetaWord* const _base;42const size_t _word_size;43const size_t _words_per_bit;4445// Given an offset, in words, into the area, return the number of the bit46// covering it.47static idx_t bitno_for_word_offset(size_t offset, size_t words_per_bit) {48return offset / words_per_bit;49}5051idx_t bitno_for_address(const MetaWord* p) const {52// Note: we allow one-beyond since this is a typical need.53assert(p >= _base && p <= _base + _word_size, "Invalid address");54const size_t off = p - _base;55return bitno_for_word_offset(off, _words_per_bit);56}5758static idx_t mask_size(size_t word_size, size_t words_per_bit) {59return bitno_for_word_offset(word_size, words_per_bit);60}6162// Marks a single commit granule as committed (value == true)63// or uncomitted (value == false) and returns64// its prior state.65bool mark_granule(idx_t bitno, bool value) {66bool b = at(bitno);67at_put(bitno, value);68return b;69}7071#ifdef ASSERT7273// Given a pointer, check if it points into the range this bitmap covers.74bool is_pointer_valid(const MetaWord* p) const;7576// Given a pointer, check if it points into the range this bitmap covers.77void check_pointer(const MetaWord* p) const;7879// Given a pointer, check if it points into the range this bitmap covers,80// and if it is aligned to commit granule border.81void check_pointer_aligned(const MetaWord* p) const;8283// Given a range, check if it points into the range this bitmap covers,84// and if its borders are aligned to commit granule border.85void check_range(const MetaWord* start, size_t word_size) const;8687#endif // ASSERT8889public:9091// Create a commit mask covering a range [start, start + word_size).92CommitMask(const MetaWord* start, size_t word_size);9394const MetaWord* base() const { return _base; }95size_t word_size() const { return _word_size; }96const MetaWord* end() const { return _base + word_size(); }9798// Given an address, returns true if the address is committed, false if not.99bool is_committed_address(const MetaWord* p) const {100DEBUG_ONLY(check_pointer(p));101const idx_t bitno = bitno_for_address(p);102return at(bitno);103}104105// Given an address range, return size, in number of words, of committed area within that range.106size_t get_committed_size_in_range(const MetaWord* start, size_t word_size) const {107DEBUG_ONLY(check_range(start, word_size));108assert(word_size > 0, "zero range");109const idx_t b1 = bitno_for_address(start);110const idx_t b2 = bitno_for_address(start + word_size);111const idx_t num_bits = count_one_bits(b1, b2);112return num_bits * _words_per_bit;113}114115// Return total committed size, in number of words.116size_t get_committed_size() const {117return count_one_bits() * _words_per_bit;118}119120// Mark a whole address range [start, end) as committed.121// Return the number of words which had already been committed before this operation.122size_t mark_range_as_committed(const MetaWord* start, size_t word_size) {123DEBUG_ONLY(check_range(start, word_size));124assert(word_size > 0, "zero range");125const idx_t b1 = bitno_for_address(start);126const idx_t b2 = bitno_for_address(start + word_size);127if (b1 == b2) { // Simple case, 1 granule128bool was_committed = mark_granule(b1, true);129return was_committed ? _words_per_bit : 0;130}131const idx_t one_bits_in_range_before = count_one_bits(b1, b2);132set_range(b1, b2);133return one_bits_in_range_before * _words_per_bit;134}135136// Mark a whole address range [start, end) as uncommitted.137// Return the number of words which had already been uncommitted before this operation.138size_t mark_range_as_uncommitted(const MetaWord* start, size_t word_size) {139DEBUG_ONLY(check_range(start, word_size));140assert(word_size > 0, "zero range");141const idx_t b1 = bitno_for_address(start);142const idx_t b2 = bitno_for_address(start + word_size);143if (b1 == b2) { // Simple case, 1 granule144bool was_committed = mark_granule(b1, false);145return was_committed ? 0 : _words_per_bit;146}147const idx_t zero_bits_in_range_before =148(b2 - b1) - count_one_bits(b1, b2);149clear_range(b1, b2);150return zero_bits_in_range_before * _words_per_bit;151}152153//// Debug stuff ////154155// Verify internals.156DEBUG_ONLY(void verify() const;)157158void print_on(outputStream* st) const;159160};161162} // namespace metaspace163164#endif // SHARE_MEMORY_METASPACE_COMMITMASK_HPP165166167