src/share/vm/memory/metachunk.cpp

changeset 5941
bdfbb1fb19ca
parent 5007
c23dbf0e8ab7
child 5942
ec2e26e26183
     1.1 --- a/src/share/vm/memory/metachunk.cpp	Tue Oct 15 07:10:09 2013 -0700
     1.2 +++ b/src/share/vm/memory/metachunk.cpp	Tue Oct 15 14:28:51 2013 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -29,42 +29,32 @@
    1.11  #include "utilities/debug.hpp"
    1.12  
    1.13  class VirtualSpaceNode;
    1.14 -//
    1.15 -// Future modification
    1.16 -//
    1.17 -// The Metachunk can conceivable be replaced by the Chunk in
    1.18 -// allocation.hpp.  Note that the latter Chunk is the space for
    1.19 -// allocation (allocations from the chunk are out of the space in
    1.20 -// the Chunk after the header for the Chunk) where as Metachunks
    1.21 -// point to space in a VirtualSpace.  To replace Metachunks with
    1.22 -// Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
    1.23  
    1.24  const size_t metadata_chunk_initialize = 0xf7f7f7f7;
    1.25  
    1.26 -size_t Metachunk::_overhead =
    1.27 -  Chunk::aligned_overhead_size(sizeof(Metachunk)) / BytesPerWord;
    1.28 +size_t Metachunk::object_alignment() {
    1.29 +  return ARENA_AMALLOC_ALIGNMENT;
    1.30 +}
    1.31 +
    1.32 +size_t Metachunk::overhead() {
    1.33 +  return align_size_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
    1.34 +}
    1.35  
    1.36  // Metachunk methods
    1.37  
    1.38  Metachunk::Metachunk(size_t word_size,
    1.39 -                     VirtualSpaceNode* container) :
    1.40 -    _word_size(word_size),
    1.41 -    _bottom(NULL),
    1.42 -    _end(NULL),
    1.43 +                     VirtualSpaceNode* container)
    1.44 +    : Metabase<Metachunk>(word_size),
    1.45      _top(NULL),
    1.46 -    _next(NULL),
    1.47 -    _prev(NULL),
    1.48      _container(container)
    1.49  {
    1.50 -  _bottom = (MetaWord*)this;
    1.51 -  _top = (MetaWord*)this + _overhead;
    1.52 -  _end = (MetaWord*)this + word_size;
    1.53 +  _top = initial_top();
    1.54  #ifdef ASSERT
    1.55 -  set_is_free(false);
    1.56 +  set_is_tagged_free(false);
    1.57    size_t data_word_size = pointer_delta(end(),
    1.58 -                                        top(),
    1.59 +                                        _top,
    1.60                                          sizeof(MetaWord));
    1.61 -  Copy::fill_to_words((HeapWord*) top(),
    1.62 +  Copy::fill_to_words((HeapWord*)_top,
    1.63                        data_word_size,
    1.64                        metadata_chunk_initialize);
    1.65  #endif
    1.66 @@ -82,22 +72,18 @@
    1.67  
    1.68  // _bottom points to the start of the chunk including the overhead.
    1.69  size_t Metachunk::used_word_size() const {
    1.70 -  return pointer_delta(_top, _bottom, sizeof(MetaWord));
    1.71 +  return pointer_delta(_top, bottom(), sizeof(MetaWord));
    1.72  }
    1.73  
    1.74  size_t Metachunk::free_word_size() const {
    1.75 -  return pointer_delta(_end, _top, sizeof(MetaWord));
    1.76 -}
    1.77 -
    1.78 -size_t Metachunk::capacity_word_size() const {
    1.79 -  return pointer_delta(_end, _bottom, sizeof(MetaWord));
    1.80 +  return pointer_delta(end(), _top, sizeof(MetaWord));
    1.81  }
    1.82  
    1.83  void Metachunk::print_on(outputStream* st) const {
    1.84    st->print_cr("Metachunk:"
    1.85                 " bottom " PTR_FORMAT " top " PTR_FORMAT
    1.86                 " end " PTR_FORMAT " size " SIZE_FORMAT,
    1.87 -               bottom(), top(), end(), word_size());
    1.88 +               bottom(), _top, end(), word_size());
    1.89    if (Verbose) {
    1.90      st->print_cr("    used " SIZE_FORMAT " free " SIZE_FORMAT,
    1.91                   used_word_size(), free_word_size());
    1.92 @@ -109,8 +95,8 @@
    1.93    // Mangle the payload of the chunk and not the links that
    1.94    // maintain list of chunks.
    1.95    HeapWord* start = (HeapWord*)(bottom() + overhead());
    1.96 -  size_t word_size = capacity_word_size() - overhead();
    1.97 -  Copy::fill_to_words(start, word_size, metadata_chunk_initialize);
    1.98 +  size_t size = word_size() - overhead();
    1.99 +  Copy::fill_to_words(start, size, metadata_chunk_initialize);
   1.100  }
   1.101  #endif // PRODUCT
   1.102  
   1.103 @@ -118,9 +104,68 @@
   1.104  #ifdef ASSERT
   1.105    // Cannot walk through the blocks unless the blocks have
   1.106    // headers with sizes.
   1.107 -  assert(_bottom <= _top &&
   1.108 -         _top <= _end,
   1.109 +  assert(bottom() <= _top &&
   1.110 +         _top <= (MetaWord*)end(),
   1.111           "Chunk has been smashed");
   1.112  #endif
   1.113    return;
   1.114  }
   1.115 +
   1.116 +/////////////// Unit tests ///////////////
   1.117 +
   1.118 +#ifndef PRODUCT
   1.119 +
   1.120 +class TestMetachunk {
   1.121 + public:
   1.122 +  static void test() {
   1.123 +    size_t size = 2 * 1024 * 1024;
   1.124 +    void* memory = malloc(size);
   1.125 +    assert(memory != NULL, "Failed to malloc 2MB");
   1.126 +
   1.127 +    Metachunk* metachunk = ::new (memory) Metachunk(size / BytesPerWord, NULL);
   1.128 +
   1.129 +    assert(metachunk->bottom() == (MetaWord*)metachunk, "assert");
   1.130 +    assert(metachunk->end() == (uintptr_t*)metachunk + metachunk->size(), "assert");
   1.131 +
   1.132 +    // Check sizes
   1.133 +    assert(metachunk->size() == metachunk->word_size(), "assert");
   1.134 +    assert(metachunk->word_size() == pointer_delta(metachunk->end(), metachunk->bottom(),
   1.135 +        sizeof(MetaWord*)), "assert");
   1.136 +
   1.137 +    // Check usage
   1.138 +    assert(metachunk->used_word_size() == metachunk->overhead(), "assert");
   1.139 +    assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
   1.140 +    assert(metachunk->top() == metachunk->initial_top(), "assert");
   1.141 +    assert(metachunk->is_empty(), "assert");
   1.142 +
   1.143 +    // Allocate
   1.144 +    size_t alloc_size = 64; // Words
   1.145 +    assert(is_size_aligned(alloc_size, Metachunk::object_alignment()), "assert");
   1.146 +
   1.147 +    MetaWord* mem = metachunk->allocate(alloc_size);
   1.148 +
   1.149 +    // Check post alloc
   1.150 +    assert(mem == metachunk->initial_top(), "assert");
   1.151 +    assert(mem + alloc_size == metachunk->top(), "assert");
   1.152 +    assert(metachunk->used_word_size() == metachunk->overhead() + alloc_size, "assert");
   1.153 +    assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
   1.154 +    assert(!metachunk->is_empty(), "assert");
   1.155 +
   1.156 +    // Clear chunk
   1.157 +    metachunk->reset_empty();
   1.158 +
   1.159 +    // Check post clear
   1.160 +    assert(metachunk->used_word_size() == metachunk->overhead(), "assert");
   1.161 +    assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
   1.162 +    assert(metachunk->top() == metachunk->initial_top(), "assert");
   1.163 +    assert(metachunk->is_empty(), "assert");
   1.164 +
   1.165 +    free(memory);
   1.166 +  }
   1.167 +};
   1.168 +
   1.169 +void TestMetachunk_test() {
   1.170 +  TestMetachunk::test();
   1.171 +}
   1.172 +
   1.173 +#endif

mercurial