hotspot/src/share/vm/memory/metachunk.hpp
changeset 20729 0a687ee7097d
parent 17101 3a82a58d9aa9
child 20732 39d1710a9a1c
equal deleted inserted replaced
20728:25114f3ae9af 20729:0a687ee7097d
     1 /*
     1 /*
     2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    22  *
    22  *
    23  */
    23  */
    24 #ifndef SHARE_VM_MEMORY_METACHUNK_HPP
    24 #ifndef SHARE_VM_MEMORY_METACHUNK_HPP
    25 #define SHARE_VM_MEMORY_METACHUNK_HPP
    25 #define SHARE_VM_MEMORY_METACHUNK_HPP
    26 
    26 
    27 //  Metachunk - Quantum of allocation from a Virtualspace
    27 #include "memory/allocation.hpp"
    28 //    Metachunks are reused (when freed are put on a global freelist) and
    28 #include "utilities/debug.hpp"
    29 //    have no permanent association to a SpaceManager.
    29 #include "utilities/globalDefinitions.hpp"
    30 
       
    31 //            +--------------+ <- end
       
    32 //            |              |          --+       ---+
       
    33 //            |              |            | free     |
       
    34 //            |              |            |          |
       
    35 //            |              |            |          | capacity
       
    36 //            |              |            |          |
       
    37 //            |              | <- top   --+          |
       
    38 //            |              |           ---+        |
       
    39 //            |              |              | used   |
       
    40 //            |              |              |        |
       
    41 //            |              |              |        |
       
    42 //            +--------------+ <- bottom ---+     ---+
       
    43 
    30 
    44 class VirtualSpaceNode;
    31 class VirtualSpaceNode;
    45 
    32 
    46 class Metachunk VALUE_OBJ_CLASS_SPEC {
    33 // Super class of Metablock and Metachunk to allow them to
    47   // link to support lists of chunks
    34 // be put on the FreeList and in the BinaryTreeDictionary.
    48   Metachunk* _next;
    35 template <class T>
    49   Metachunk* _prev;
    36 class Metabase VALUE_OBJ_CLASS_SPEC {
    50   VirtualSpaceNode* _container;
    37   size_t _word_size;
       
    38   T*     _next;
       
    39   T*     _prev;
    51 
    40 
    52   MetaWord* _bottom;
    41  protected:
    53   MetaWord* _end;
    42   Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {}
    54   MetaWord* _top;
       
    55   size_t _word_size;
       
    56   // Used in a guarantee() so included in the Product builds
       
    57   // even through it is only for debugging.
       
    58   bool _is_free;
       
    59 
       
    60   // Metachunks are allocated out of a MetadataVirtualSpace and
       
    61   // and use some of its space to describe itself (plus alignment
       
    62   // considerations).  Metadata is allocated in the rest of the chunk.
       
    63   // This size is the overhead of maintaining the Metachunk within
       
    64   // the space.
       
    65   static size_t _overhead;
       
    66 
    43 
    67  public:
    44  public:
    68   Metachunk(size_t word_size , VirtualSpaceNode* container);
    45   T* next() const         { return _next; }
       
    46   T* prev() const         { return _prev; }
       
    47   void set_next(T* v)     { _next = v; assert(v != this, "Boom");}
       
    48   void set_prev(T* v)     { _prev = v; assert(v != this, "Boom");}
       
    49   void clear_next()       { set_next(NULL); }
       
    50   void clear_prev()       { set_prev(NULL); }
    69 
    51 
    70   // Used to add a Metachunk to a list of Metachunks
       
    71   void set_next(Metachunk* v) { _next = v; assert(v != this, "Boom");}
       
    72   void set_prev(Metachunk* v) { _prev = v; assert(v != this, "Boom");}
       
    73   void set_container(VirtualSpaceNode* v) { _container = v; }
       
    74 
       
    75   MetaWord* allocate(size_t word_size);
       
    76 
       
    77   // Accessors
       
    78   Metachunk* next() const { return _next; }
       
    79   Metachunk* prev() const { return _prev; }
       
    80   VirtualSpaceNode* container() const { return _container; }
       
    81   MetaWord* bottom() const { return _bottom; }
       
    82   MetaWord* end() const { return _end; }
       
    83   MetaWord* top() const { return _top; }
       
    84   size_t word_size() const { return _word_size; }
       
    85   size_t size() const volatile { return _word_size; }
    52   size_t size() const volatile { return _word_size; }
    86   void set_size(size_t v) { _word_size = v; }
    53   void set_size(size_t v) { _word_size = v; }
    87   bool is_free() { return _is_free; }
    54 
    88   void set_is_free(bool v) { _is_free = v; }
    55   void link_next(T* ptr)  { set_next(ptr); }
    89   static size_t overhead() { return _overhead; }
    56   void link_prev(T* ptr)  { set_prev(ptr); }
    90   void clear_next()              { set_next(NULL); }
    57   void link_after(T* ptr) {
    91   void link_prev(Metachunk* ptr) { set_prev(ptr); }
       
    92   uintptr_t* end()              { return ((uintptr_t*) this) + size(); }
       
    93   bool cantCoalesce() const     { return false; }
       
    94   void link_next(Metachunk* ptr) { set_next(ptr); }
       
    95   void link_after(Metachunk* ptr){
       
    96     link_next(ptr);
    58     link_next(ptr);
    97     if (ptr != NULL) ptr->link_prev(this);
    59     if (ptr != NULL) ptr->link_prev((T*)this);
    98   }
    60   }
    99 
    61 
   100   // Reset top to bottom so chunk can be reused.
    62   uintptr_t* end() const        { return ((uintptr_t*) this) + size(); }
   101   void reset_empty() { _top = (_bottom + _overhead); _next = NULL; _prev = NULL; }
       
   102   bool is_empty() { return _top == (_bottom + _overhead); }
       
   103 
    63 
   104   // used (has been allocated)
    64   bool cantCoalesce() const     { return false; }
   105   // free (available for future allocations)
       
   106   // capacity (total size of chunk)
       
   107   size_t used_word_size() const;
       
   108   size_t free_word_size() const;
       
   109   size_t capacity_word_size()const;
       
   110 
    65 
   111   // Debug support
    66   // Debug support
   112 #ifdef ASSERT
    67 #ifdef ASSERT
   113   void* prev_addr() const { return (void*)&_prev; }
    68   void* prev_addr() const { return (void*)&_prev; }
   114   void* next_addr() const { return (void*)&_next; }
    69   void* next_addr() const { return (void*)&_next; }
   115   void* size_addr() const { return (void*)&_word_size; }
    70   void* size_addr() const { return (void*)&_word_size; }
   116 #endif
    71 #endif
   117   bool verify_chunk_in_free_list(Metachunk* tc) const { return true; }
    72   bool verify_chunk_in_free_list(T* tc) const { return true; }
   118   bool verify_par_locked() { return true; }
    73   bool verify_par_locked() { return true; }
   119 
    74 
   120   void assert_is_mangled() const {/* Don't check "\*/}
    75   void assert_is_mangled() const {/* Don't check "\*/}
   121 
    76 
   122   NOT_PRODUCT(void mangle();)
    77   bool is_free()                 { return true; }
       
    78 };
       
    79 
       
    80 //  Metachunk - Quantum of allocation from a Virtualspace
       
    81 //    Metachunks are reused (when freed are put on a global freelist) and
       
    82 //    have no permanent association to a SpaceManager.
       
    83 
       
    84 //            +--------------+ <- end    --+       --+
       
    85 //            |              |             |         |
       
    86 //            |              |             | free    |
       
    87 //            |              |             |         |
       
    88 //            |              |             |         | size | capacity
       
    89 //            |              |             |         |
       
    90 //            |              | <- top   -- +         |
       
    91 //            |              |             |         |
       
    92 //            |              |             | used    |
       
    93 //            |              |             |         |
       
    94 //            |              |             |         |
       
    95 //            +--------------+ <- bottom --+       --+
       
    96 
       
    97 class Metachunk : public Metabase<Metachunk> {
       
    98   friend class TestMetachunk;
       
    99   // The VirtualSpaceNode containing this chunk.
       
   100   VirtualSpaceNode* _container;
       
   101 
       
   102   // Current allocation top.
       
   103   MetaWord* _top;
       
   104 
       
   105   DEBUG_ONLY(bool _is_tagged_free;)
       
   106 
       
   107   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
       
   108   MetaWord* top() const         { return _top; }
       
   109 
       
   110  public:
       
   111   // Metachunks are allocated out of a MetadataVirtualSpace and
       
   112   // and use some of its space to describe itself (plus alignment
       
   113   // considerations).  Metadata is allocated in the rest of the chunk.
       
   114   // This size is the overhead of maintaining the Metachunk within
       
   115   // the space.
       
   116 
       
   117   // Alignment of each allocation in the chunks.
       
   118   static size_t object_alignment();
       
   119 
       
   120   // Size of the Metachunk header, including alignment.
       
   121   static size_t overhead();
       
   122 
       
   123   Metachunk(size_t word_size , VirtualSpaceNode* container);
       
   124 
       
   125   MetaWord* allocate(size_t word_size);
       
   126 
       
   127   VirtualSpaceNode* container() const { return _container; }
       
   128 
       
   129   MetaWord* bottom() const { return (MetaWord*) this; }
       
   130 
       
   131   // Reset top to bottom so chunk can be reused.
       
   132   void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); }
       
   133   bool is_empty() { return _top == initial_top(); }
       
   134 
       
   135   // used (has been allocated)
       
   136   // free (available for future allocations)
       
   137   size_t word_size() const { return size(); }
       
   138   size_t used_word_size() const;
       
   139   size_t free_word_size() const;
       
   140 
       
   141 #ifdef ASSERT
       
   142   void mangle();
       
   143   bool is_tagged_free() { return _is_tagged_free; }
       
   144   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
       
   145 #endif
   123 
   146 
   124   void print_on(outputStream* st) const;
   147   void print_on(outputStream* st) const;
   125   void verify();
   148   void verify();
   126 };
   149 };
       
   150 
       
   151 // Metablock is the unit of allocation from a Chunk.
       
   152 //
       
   153 // A Metablock may be reused by its SpaceManager but are never moved between
       
   154 // SpaceManagers.  There is no explicit link to the Metachunk
       
   155 // from which it was allocated.  Metablock may be deallocated and
       
   156 // put on a freelist but the space is never freed, rather
       
   157 // the Metachunk it is a part of will be deallocated when it's
       
   158 // associated class loader is collected.
       
   159 
       
   160 class Metablock : public Metabase<Metablock> {
       
   161   friend class VMStructs;
       
   162  public:
       
   163   Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
       
   164 };
       
   165 
   127 #endif  // SHARE_VM_MEMORY_METACHUNK_HPP
   166 #endif  // SHARE_VM_MEMORY_METACHUNK_HPP