Wed, 26 Jun 2013 16:58:37 +0200
8013590: NPG: Add a memory pool MXBean for Metaspace
Reviewed-by: jmasa, mgerdin
jmasa@4196 | 1 | /* |
jmasa@4196 | 2 | * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. |
jmasa@4196 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
jmasa@4196 | 4 | * |
jmasa@4196 | 5 | * This code is free software; you can redistribute it and/or modify it |
jmasa@4196 | 6 | * under the terms of the GNU General Public License version 2 only, as |
jmasa@4196 | 7 | * published by the Free Software Foundation. |
jmasa@4196 | 8 | * |
jmasa@4196 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
jmasa@4196 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
jmasa@4196 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
jmasa@4196 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
jmasa@4196 | 13 | * accompanied this code). |
jmasa@4196 | 14 | * |
jmasa@4196 | 15 | * You should have received a copy of the GNU General Public License version |
jmasa@4196 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
jmasa@4196 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
jmasa@4196 | 18 | * |
jmasa@4196 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
jmasa@4196 | 20 | * or visit www.oracle.com if you need additional information or have any |
jmasa@4196 | 21 | * questions. |
jmasa@4196 | 22 | * |
jmasa@4196 | 23 | */ |
jmasa@4196 | 24 | #ifndef SHARE_VM_MEMORY_METABLOCK_HPP |
jmasa@4196 | 25 | #define SHARE_VM_MEMORY_METABLOCK_HPP |
jmasa@4196 | 26 | |
jmasa@4196 | 27 | // Metablock are the unit of allocation from a Chunk. It is initialized |
jmasa@4196 | 28 | // with the size of the requested allocation. That size is overwritten |
jmasa@4196 | 29 | // once the allocation returns. |
jmasa@4196 | 30 | // |
jmasa@4196 | 31 | // A Metablock may be reused by its SpaceManager but are never moved between |
jmasa@4196 | 32 | // SpaceManagers. There is no explicit link to the Metachunk |
jmasa@4196 | 33 | // from which it was allocated. Metablock may be deallocated and |
jmasa@4196 | 34 | // put on a freelist but the space is never freed, rather |
jmasa@4196 | 35 | // the Metachunk it is a part of will be deallocated when it's |
jmasa@4196 | 36 | // associated class loader is collected. |
jmasa@4196 | 37 | |
jmasa@4196 | 38 | class Metablock VALUE_OBJ_CLASS_SPEC { |
jmasa@4196 | 39 | friend class VMStructs; |
jmasa@4196 | 40 | private: |
jmasa@4196 | 41 | // Used to align the allocation (see below). |
jmasa@4196 | 42 | union block_t { |
jmasa@4196 | 43 | void* _data[3]; |
jmasa@4196 | 44 | struct header_t { |
jmasa@4196 | 45 | size_t _word_size; |
jmasa@4196 | 46 | Metablock* _next; |
jmasa@4196 | 47 | Metablock* _prev; |
jmasa@4196 | 48 | } _header; |
jmasa@4196 | 49 | } _block; |
jmasa@4196 | 50 | static size_t _min_block_byte_size; |
jmasa@4196 | 51 | static size_t _overhead; |
jmasa@4196 | 52 | |
jmasa@4196 | 53 | typedef union block_t Block; |
jmasa@4196 | 54 | typedef struct header_t Header; |
jmasa@4196 | 55 | const Block* block() const { return &_block; } |
jmasa@4196 | 56 | const Block::header_t* header() const { return &(block()->_header); } |
jmasa@4196 | 57 | public: |
jmasa@4196 | 58 | |
jmasa@4196 | 59 | static Metablock* initialize(MetaWord* p, size_t word_size); |
jmasa@4196 | 60 | |
jmasa@4196 | 61 | // This places the body of the block at a 2 word boundary |
jmasa@4196 | 62 | // because every block starts on a 2 word boundary. Work out |
jmasa@4196 | 63 | // how to make the body on a 2 word boundary if the block |
jmasa@4196 | 64 | // starts on a arbitrary boundary. JJJ |
jmasa@4196 | 65 | |
jmasa@4196 | 66 | size_t word_size() const { return header()->_word_size; } |
jmasa@4196 | 67 | void set_word_size(size_t v) { _block._header._word_size = v; } |
jmasa@4196 | 68 | size_t size() const volatile { return _block._header._word_size; } |
jmasa@4196 | 69 | void set_size(size_t v) { _block._header._word_size = v; } |
jmasa@4196 | 70 | Metablock* next() const { return header()->_next; } |
jmasa@4196 | 71 | void set_next(Metablock* v) { _block._header._next = v; } |
jmasa@4196 | 72 | Metablock* prev() const { return header()->_prev; } |
jmasa@4196 | 73 | void set_prev(Metablock* v) { _block._header._prev = v; } |
jmasa@4196 | 74 | |
jmasa@4196 | 75 | static size_t min_block_byte_size() { return _min_block_byte_size; } |
jmasa@4196 | 76 | static size_t overhead() { return _overhead; } |
jmasa@4196 | 77 | |
jmasa@4196 | 78 | bool is_free() { return header()->_word_size != 0; } |
jmasa@4196 | 79 | void clear_next() { set_next(NULL); } |
jmasa@4196 | 80 | void link_prev(Metablock* ptr) { set_prev(ptr); } |
jmasa@4196 | 81 | uintptr_t* end() { return ((uintptr_t*) this) + size(); } |
jmasa@4196 | 82 | bool cantCoalesce() const { return false; } |
jmasa@4196 | 83 | void link_next(Metablock* ptr) { set_next(ptr); } |
jmasa@4196 | 84 | void link_after(Metablock* ptr){ |
jmasa@4196 | 85 | link_next(ptr); |
jmasa@4196 | 86 | if (ptr != NULL) ptr->link_prev(this); |
jmasa@4196 | 87 | } |
jmasa@4196 | 88 | |
jmasa@4196 | 89 | // Should not be needed in a free list of Metablocks |
jmasa@4196 | 90 | void markNotFree() { ShouldNotReachHere(); } |
jmasa@4196 | 91 | |
jmasa@4196 | 92 | // Debug support |
jmasa@4196 | 93 | #ifdef ASSERT |
jmasa@4196 | 94 | void* prev_addr() const { return (void*)&_block._header._prev; } |
jmasa@4196 | 95 | void* next_addr() const { return (void*)&_block._header._next; } |
jmasa@4196 | 96 | void* size_addr() const { return (void*)&_block._header._word_size; } |
jmasa@4196 | 97 | #endif |
jmasa@4196 | 98 | bool verify_chunk_in_free_list(Metablock* tc) const { return true; } |
jmasa@4196 | 99 | bool verify_par_locked() { return true; } |
jmasa@4196 | 100 | |
jmasa@4196 | 101 | void assert_is_mangled() const {/* Don't check "\*/} |
jmasa@4196 | 102 | }; |
jmasa@4196 | 103 | #endif // SHARE_VM_MEMORY_METABLOCK_HPP |