src/share/vm/memory/metachunk.cpp

Sat, 23 Nov 2013 12:25:13 +0100

author
mgronlun
date
Sat, 23 Nov 2013 12:25:13 +0100
changeset 6131
86e6d691f2e1
parent 5942
ec2e26e26183
child 6680
78bbf4d43a14
permissions
-rw-r--r--

8028128: Add a type safe alternative for working with counter based data
Reviewed-by: dholmes, egahlin

jmasa@4327 1 /*
stefank@5941 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
jmasa@4327 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jmasa@4327 4 *
jmasa@4327 5 * This code is free software; you can redistribute it and/or modify it
jmasa@4327 6 * under the terms of the GNU General Public License version 2 only, as
jmasa@4327 7 * published by the Free Software Foundation.
jmasa@4327 8 *
jmasa@4327 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jmasa@4327 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jmasa@4327 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jmasa@4327 12 * version 2 for more details (a copy is included in the LICENSE file that
jmasa@4327 13 * accompanied this code).
jmasa@4327 14 *
jmasa@4327 15 * You should have received a copy of the GNU General Public License version
jmasa@4327 16 * 2 along with this work; if not, write to the Free Software Foundation,
jmasa@4327 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jmasa@4327 18 *
jmasa@4327 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jmasa@4327 20 * or visit www.oracle.com if you need additional information or have any
jmasa@4327 21 * questions.
jmasa@4327 22 *
jmasa@4327 23 */
jmasa@4327 24
jmasa@4327 25 #include "precompiled.hpp"
jmasa@4327 26 #include "memory/allocation.hpp"
jmasa@4327 27 #include "memory/metachunk.hpp"
jmasa@4327 28 #include "utilities/copy.hpp"
jmasa@4327 29 #include "utilities/debug.hpp"
jmasa@4327 30
jmasa@5007 31 class VirtualSpaceNode;
jmasa@4327 32
jmasa@4327 33 const size_t metadata_chunk_initialize = 0xf7f7f7f7;
jmasa@4327 34
stefank@5941 35 size_t Metachunk::object_alignment() {
stefank@5942 36 // Must align pointers and sizes to 8,
stefank@5942 37 // so that 64 bit types get correctly aligned.
stefank@5942 38 const size_t alignment = 8;
stefank@5942 39
stefank@5942 40 // Make sure that the Klass alignment also agree.
stefank@5942 41 STATIC_ASSERT(alignment == (size_t)KlassAlignmentInBytes);
stefank@5942 42
stefank@5942 43 return alignment;
stefank@5941 44 }
stefank@5941 45
stefank@5941 46 size_t Metachunk::overhead() {
stefank@5941 47 return align_size_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
stefank@5941 48 }
jmasa@4327 49
jmasa@4327 50 // Metachunk methods
jmasa@4327 51
jmasa@5007 52 Metachunk::Metachunk(size_t word_size,
stefank@5941 53 VirtualSpaceNode* container)
stefank@5941 54 : Metabase<Metachunk>(word_size),
jmasa@5007 55 _top(NULL),
jmasa@5007 56 _container(container)
jmasa@5007 57 {
stefank@5941 58 _top = initial_top();
jmasa@4327 59 #ifdef ASSERT
stefank@5941 60 set_is_tagged_free(false);
jmasa@5007 61 size_t data_word_size = pointer_delta(end(),
stefank@5941 62 _top,
jmasa@5007 63 sizeof(MetaWord));
stefank@5941 64 Copy::fill_to_words((HeapWord*)_top,
jmasa@5007 65 data_word_size,
jmasa@5007 66 metadata_chunk_initialize);
jmasa@4327 67 #endif
jmasa@4327 68 }
jmasa@4327 69
jmasa@4327 70 MetaWord* Metachunk::allocate(size_t word_size) {
jmasa@4327 71 MetaWord* result = NULL;
jmasa@4327 72 // If available, bump the pointer to allocate.
jmasa@4327 73 if (free_word_size() >= word_size) {
jmasa@4327 74 result = _top;
jmasa@4327 75 _top = _top + word_size;
jmasa@4327 76 }
jmasa@4327 77 return result;
jmasa@4327 78 }
jmasa@4327 79
jmasa@4327 80 // _bottom points to the start of the chunk including the overhead.
jmasa@4382 81 size_t Metachunk::used_word_size() const {
stefank@5941 82 return pointer_delta(_top, bottom(), sizeof(MetaWord));
jmasa@4327 83 }
jmasa@4327 84
jmasa@4382 85 size_t Metachunk::free_word_size() const {
stefank@5941 86 return pointer_delta(end(), _top, sizeof(MetaWord));
jmasa@4327 87 }
jmasa@4327 88
jmasa@4327 89 void Metachunk::print_on(outputStream* st) const {
jmasa@4327 90 st->print_cr("Metachunk:"
jmasa@4327 91 " bottom " PTR_FORMAT " top " PTR_FORMAT
jmasa@4327 92 " end " PTR_FORMAT " size " SIZE_FORMAT,
stefank@5941 93 bottom(), _top, end(), word_size());
jmasa@4382 94 if (Verbose) {
jmasa@4382 95 st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT,
jmasa@4382 96 used_word_size(), free_word_size());
jmasa@4382 97 }
jmasa@4327 98 }
jmasa@4327 99
jmasa@4327 100 #ifndef PRODUCT
jmasa@4327 101 void Metachunk::mangle() {
jmasa@4327 102 // Mangle the payload of the chunk and not the links that
jmasa@4327 103 // maintain list of chunks.
jmasa@4327 104 HeapWord* start = (HeapWord*)(bottom() + overhead());
stefank@5941 105 size_t size = word_size() - overhead();
stefank@5941 106 Copy::fill_to_words(start, size, metadata_chunk_initialize);
jmasa@4327 107 }
jmasa@4327 108 #endif // PRODUCT
jmasa@4327 109
jmasa@4327 110 void Metachunk::verify() {
jmasa@4327 111 #ifdef ASSERT
jmasa@4327 112 // Cannot walk through the blocks unless the blocks have
jmasa@4327 113 // headers with sizes.
stefank@5941 114 assert(bottom() <= _top &&
stefank@5941 115 _top <= (MetaWord*)end(),
jmasa@4327 116 "Chunk has been smashed");
jmasa@4327 117 #endif
jmasa@4327 118 return;
jmasa@4327 119 }
stefank@5941 120
stefank@5941 121 /////////////// Unit tests ///////////////
stefank@5941 122
stefank@5941 123 #ifndef PRODUCT
stefank@5941 124
stefank@5941 125 class TestMetachunk {
stefank@5941 126 public:
stefank@5941 127 static void test() {
stefank@5941 128 size_t size = 2 * 1024 * 1024;
stefank@5941 129 void* memory = malloc(size);
stefank@5941 130 assert(memory != NULL, "Failed to malloc 2MB");
stefank@5941 131
stefank@5941 132 Metachunk* metachunk = ::new (memory) Metachunk(size / BytesPerWord, NULL);
stefank@5941 133
stefank@5941 134 assert(metachunk->bottom() == (MetaWord*)metachunk, "assert");
stefank@5941 135 assert(metachunk->end() == (uintptr_t*)metachunk + metachunk->size(), "assert");
stefank@5941 136
stefank@5941 137 // Check sizes
stefank@5941 138 assert(metachunk->size() == metachunk->word_size(), "assert");
stefank@5941 139 assert(metachunk->word_size() == pointer_delta(metachunk->end(), metachunk->bottom(),
stefank@5941 140 sizeof(MetaWord*)), "assert");
stefank@5941 141
stefank@5941 142 // Check usage
stefank@5941 143 assert(metachunk->used_word_size() == metachunk->overhead(), "assert");
stefank@5941 144 assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
stefank@5941 145 assert(metachunk->top() == metachunk->initial_top(), "assert");
stefank@5941 146 assert(metachunk->is_empty(), "assert");
stefank@5941 147
stefank@5941 148 // Allocate
stefank@5941 149 size_t alloc_size = 64; // Words
stefank@5941 150 assert(is_size_aligned(alloc_size, Metachunk::object_alignment()), "assert");
stefank@5941 151
stefank@5941 152 MetaWord* mem = metachunk->allocate(alloc_size);
stefank@5941 153
stefank@5941 154 // Check post alloc
stefank@5941 155 assert(mem == metachunk->initial_top(), "assert");
stefank@5941 156 assert(mem + alloc_size == metachunk->top(), "assert");
stefank@5941 157 assert(metachunk->used_word_size() == metachunk->overhead() + alloc_size, "assert");
stefank@5941 158 assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
stefank@5941 159 assert(!metachunk->is_empty(), "assert");
stefank@5941 160
stefank@5941 161 // Clear chunk
stefank@5941 162 metachunk->reset_empty();
stefank@5941 163
stefank@5941 164 // Check post clear
stefank@5941 165 assert(metachunk->used_word_size() == metachunk->overhead(), "assert");
stefank@5941 166 assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
stefank@5941 167 assert(metachunk->top() == metachunk->initial_top(), "assert");
stefank@5941 168 assert(metachunk->is_empty(), "assert");
stefank@5941 169
stefank@5941 170 free(memory);
stefank@5941 171 }
stefank@5941 172 };
stefank@5941 173
stefank@5941 174 void TestMetachunk_test() {
stefank@5941 175 TestMetachunk::test();
stefank@5941 176 }
stefank@5941 177
stefank@5941 178 #endif

mercurial