src/share/vm/memory/binaryTreeDictionary.hpp

Print this page




  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
  26 #define SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
  27 
  28 #include "memory/freeBlockDictionary.hpp"
  29 #include "memory/freeList.hpp"
  30 
  31 /*
  32  * A binary tree based search structure for free blocks.
  33  * This is currently used in the Concurrent Mark&Sweep implementation, but
  34  * will be used for free block management for metadata.
  35  */
  36 
  37 // A TreeList is a FreeList which can be used to maintain a
  38 // binary tree of free lists.
  39 
  40 template <class Chunk_t, template <class> class FreeList_t> class TreeChunk;
  41 template <class Chunk_t, template <class> class FreeList_t> class BinaryTreeDictionary;
  42 template <class Chunk_t, template <class> class FreeList_t> class AscendTreeCensusClosure;
  43 template <class Chunk_t, template <class> class FreeList_t> class DescendTreeCensusClosure;
  44 template <class Chunk_t, template <class> class FreeList_t> class DescendTreeSearchClosure;
  45 
  46 class FreeChunk;
  47 template <class> class AdaptiveFreeList;
  48 typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList> AFLBinaryTreeDictionary;
  49 
  50 template <class Chunk_t, template <class> class FreeList_t>
  51 class TreeList : public FreeList_t<Chunk_t> {
  52   friend class TreeChunk<Chunk_t, FreeList_t>;
  53   friend class BinaryTreeDictionary<Chunk_t, FreeList_t>;
  54   friend class AscendTreeCensusClosure<Chunk_t, FreeList_t>;
  55   friend class DescendTreeCensusClosure<Chunk_t, FreeList_t>;
  56   friend class DescendTreeSearchClosure<Chunk_t, FreeList_t>;
  57 
  58   TreeList<Chunk_t, FreeList_t>* _parent;
  59   TreeList<Chunk_t, FreeList_t>* _left;
  60   TreeList<Chunk_t, FreeList_t>* _right;
  61 
  62  protected:
  63 
  64   TreeList<Chunk_t, FreeList_t>* parent() const { return _parent; }
  65   TreeList<Chunk_t, FreeList_t>* left()   const { return _left;   }
  66   TreeList<Chunk_t, FreeList_t>* right()  const { return _right;  }
  67 
  68   // Wrapper on call to base class, to get the template to compile.
  69   Chunk_t* head() const { return FreeList_t<Chunk_t>::head(); }
  70   Chunk_t* tail() const { return FreeList_t<Chunk_t>::tail(); }
  71   void set_head(Chunk_t* head) { FreeList_t<Chunk_t>::set_head(head); }
  72   void set_tail(Chunk_t* tail) { FreeList_t<Chunk_t>::set_tail(tail); }
  73 
  74   size_t size() const { return FreeList_t<Chunk_t>::size(); }
  75 
  76   // Accessors for links in tree.
  77 
  78   void set_left(TreeList<Chunk_t, FreeList_t>* tl) {
  79     _left   = tl;
  80     if (tl != NULL)
  81       tl->set_parent(this);
  82   }
  83   void set_right(TreeList<Chunk_t, FreeList_t>* tl) {
  84     _right  = tl;
  85     if (tl != NULL)
  86       tl->set_parent(this);
  87   }
  88   void set_parent(TreeList<Chunk_t, FreeList_t>* tl)  { _parent = tl;   }
  89 
  90   void clear_left()               { _left = NULL;   }
  91   void clear_right()              { _right = NULL;  }
  92   void clear_parent()             { _parent = NULL; }
  93   void initialize()               { clear_left(); clear_right(), clear_parent(); FreeList_t<Chunk_t>::initialize(); }
  94 
  95   // For constructing a TreeList from a Tree chunk or
  96   // address and size.
  97   TreeList();
  98   static TreeList<Chunk_t, FreeList_t>*
  99           as_TreeList(TreeChunk<Chunk_t, FreeList_t>* tc);
 100   static TreeList<Chunk_t, FreeList_t>* as_TreeList(HeapWord* addr, size_t size);
 101 
 102   // Returns the head of the free list as a pointer to a TreeChunk.
 103   TreeChunk<Chunk_t, FreeList_t>* head_as_TreeChunk();
 104 
 105   // Returns the first available chunk in the free list as a pointer
 106   // to a TreeChunk.
 107   TreeChunk<Chunk_t, FreeList_t>* first_available();
 108 
 109   // Returns the block with the largest heap address amongst
 110   // those in the list for this size; potentially slow and expensive,
 111   // use with caution!
 112   TreeChunk<Chunk_t, FreeList_t>* largest_address();
 113 


 122   // node to point to the new node.
 123   TreeList<Chunk_t, FreeList_t>* remove_chunk_replace_if_needed(TreeChunk<Chunk_t, FreeList_t>* tc);
 124   // See FreeList.
 125   void return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* tc);
 126   void return_chunk_at_tail(TreeChunk<Chunk_t, FreeList_t>* tc);
 127 };
 128 
 129 // A TreeChunk is a subclass of a Chunk that additionally
 130 // maintains a pointer to the free list on which it is currently
 131 // linked.
 132 // A TreeChunk is also used as a node in the binary tree.  This
 133 // allows the binary tree to be maintained without any additional
 134 // storage (the free chunks are used).  In a binary tree the first
 135 // chunk in the free list is also the tree node.  Note that the
 136 // TreeChunk has an embedded TreeList for this purpose.  Because
 137 // the first chunk in the list is distinguished in this fashion
 138 // (also is the node in the tree), it is the last chunk to be found
 139 // on the free list for a node in the tree and is only removed if
 140 // it is the last chunk on the free list.
 141 
 142 template <class Chunk_t, template <class> class FreeList_t>
 143 class TreeChunk : public Chunk_t {
 144   friend class TreeList<Chunk_t, FreeList_t>;
 145   TreeList<Chunk_t, FreeList_t>* _list;
 146   TreeList<Chunk_t, FreeList_t> _embedded_list;  // if non-null, this chunk is on _list
 147 
 148   static size_t _min_tree_chunk_size;
 149 
 150  protected:
 151   TreeList<Chunk_t, FreeList_t>* embedded_list() const { return (TreeList<Chunk_t, FreeList_t>*) &_embedded_list; }
 152   void set_embedded_list(TreeList<Chunk_t, FreeList_t>* v) { _embedded_list = *v; }
 153  public:
 154   TreeList<Chunk_t, FreeList_t>* list() { return _list; }
 155   void set_list(TreeList<Chunk_t, FreeList_t>* v) { _list = v; }
 156   static TreeChunk<Chunk_t, FreeList_t>* as_TreeChunk(Chunk_t* fc);
 157   // Initialize fields in a TreeChunk that should be
 158   // initialized when the TreeChunk is being added to
 159   // a free list in the tree.
 160   void initialize() { embedded_list()->initialize(); }
 161 
 162   Chunk_t* next() const { return Chunk_t::next(); }
 163   Chunk_t* prev() const { return Chunk_t::prev(); }
 164   size_t size() const volatile { return Chunk_t::size(); }
 165 
 166   static size_t min_size() {
 167     return _min_tree_chunk_size;
 168   }
 169 
 170   // debugging
 171   void verify_tree_chunk_list() const;
 172   void assert_is_mangled() const;
 173 };
 174 
 175 
 176 template <class Chunk_t, template <class> class FreeList_t>
 177 class BinaryTreeDictionary: public FreeBlockDictionary<Chunk_t> {
 178   friend class VMStructs;
 179   size_t     _total_size;
 180   size_t     _total_free_blocks;
 181   TreeList<Chunk_t, FreeList_t>* _root;
 182 
 183   // private accessors
 184   void set_total_size(size_t v) { _total_size = v; }
 185   virtual void inc_total_size(size_t v);
 186   virtual void dec_total_size(size_t v);
 187   void set_total_free_blocks(size_t v) { _total_free_blocks = v; }
 188   TreeList<Chunk_t, FreeList_t>* root() const { return _root; }
 189   void set_root(TreeList<Chunk_t, FreeList_t>* v) { _root = v; }
 190 
 191   // This field is added and can be set to point to the
 192   // the Mutex used to synchronize access to the
 193   // dictionary so that assertion checking can be done.
 194   // For example it is set to point to _parDictionaryAllocLock.
 195   NOT_PRODUCT(Mutex* _lock;)
 196 




  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
  26 #define SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
  27 
  28 #include "memory/freeBlockDictionary.hpp"
  29 #include "memory/freeList.hpp"
  30 
  31 /*
  32  * A binary tree based search structure for free blocks.
  33  * This is currently used in the Concurrent Mark&Sweep implementation, but
  34  * will be used for free block management for metadata.
  35  */
  36 
  37 // A TreeList is a FreeList which can be used to maintain a
  38 // binary tree of free lists.
  39 
  40 template <class Chunk_t, class FreeList_t> class TreeChunk;
  41 template <class Chunk_t, class FreeList_t> class BinaryTreeDictionary;
  42 template <class Chunk_t, class FreeList_t> class AscendTreeCensusClosure;
  43 template <class Chunk_t, class FreeList_t> class DescendTreeCensusClosure;
  44 template <class Chunk_t, class FreeList_t> class DescendTreeSearchClosure;
  45 
  46 class FreeChunk;
  47 template <class> class AdaptiveFreeList;
  48 typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList<FreeChunk> > AFLBinaryTreeDictionary;
  49 
  50 template <class Chunk_t, class FreeList_t>
  51 class TreeList : public FreeList_t {
  52   friend class TreeChunk<Chunk_t, FreeList_t>;
  53   friend class BinaryTreeDictionary<Chunk_t, FreeList_t>;
  54   friend class AscendTreeCensusClosure<Chunk_t, FreeList_t>;
  55   friend class DescendTreeCensusClosure<Chunk_t, FreeList_t>;
  56   friend class DescendTreeSearchClosure<Chunk_t, FreeList_t>;
  57 
  58   TreeList<Chunk_t, FreeList_t>* _parent;
  59   TreeList<Chunk_t, FreeList_t>* _left;
  60   TreeList<Chunk_t, FreeList_t>* _right;
  61 
  62  protected:
  63 
  64   TreeList<Chunk_t, FreeList_t>* parent() const { return _parent; }
  65   TreeList<Chunk_t, FreeList_t>* left()   const { return _left;   }
  66   TreeList<Chunk_t, FreeList_t>* right()  const { return _right;  }
  67 
  68   // Wrapper on call to base class, to get the template to compile.
  69   Chunk_t* head() const { return FreeList_t::head(); }
  70   Chunk_t* tail() const { return FreeList_t::tail(); }
  71   void set_head(Chunk_t* head) { FreeList_t::set_head(head); }
  72   void set_tail(Chunk_t* tail) { FreeList_t::set_tail(tail); }
  73 
  74   size_t size() const { return FreeList_t::size(); }
  75 
  76   // Accessors for links in tree.
  77 
  78   void set_left(TreeList<Chunk_t, FreeList_t>* tl) {
  79     _left   = tl;
  80     if (tl != NULL)
  81       tl->set_parent(this);
  82   }
  83   void set_right(TreeList<Chunk_t, FreeList_t>* tl) {
  84     _right  = tl;
  85     if (tl != NULL)
  86       tl->set_parent(this);
  87   }
  88   void set_parent(TreeList<Chunk_t, FreeList_t>* tl)  { _parent = tl;   }
  89 
  90   void clear_left()               { _left = NULL;   }
  91   void clear_right()              { _right = NULL;  }
  92   void clear_parent()             { _parent = NULL; }
  93   void initialize()               { clear_left(); clear_right(), clear_parent(); FreeList_t::initialize(); }
  94 
  95   // For constructing a TreeList from a Tree chunk or
  96   // address and size.
  97   TreeList();
  98   static TreeList<Chunk_t, FreeList_t>*
  99           as_TreeList(TreeChunk<Chunk_t, FreeList_t>* tc);
 100   static TreeList<Chunk_t, FreeList_t>* as_TreeList(HeapWord* addr, size_t size);
 101 
 102   // Returns the head of the free list as a pointer to a TreeChunk.
 103   TreeChunk<Chunk_t, FreeList_t>* head_as_TreeChunk();
 104 
 105   // Returns the first available chunk in the free list as a pointer
 106   // to a TreeChunk.
 107   TreeChunk<Chunk_t, FreeList_t>* first_available();
 108 
 109   // Returns the block with the largest heap address amongst
 110   // those in the list for this size; potentially slow and expensive,
 111   // use with caution!
 112   TreeChunk<Chunk_t, FreeList_t>* largest_address();
 113 


 122   // node to point to the new node.
 123   TreeList<Chunk_t, FreeList_t>* remove_chunk_replace_if_needed(TreeChunk<Chunk_t, FreeList_t>* tc);
 124   // See FreeList.
 125   void return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* tc);
 126   void return_chunk_at_tail(TreeChunk<Chunk_t, FreeList_t>* tc);
 127 };
 128 
 129 // A TreeChunk is a subclass of a Chunk that additionally
 130 // maintains a pointer to the free list on which it is currently
 131 // linked.
 132 // A TreeChunk is also used as a node in the binary tree.  This
 133 // allows the binary tree to be maintained without any additional
 134 // storage (the free chunks are used).  In a binary tree the first
 135 // chunk in the free list is also the tree node.  Note that the
 136 // TreeChunk has an embedded TreeList for this purpose.  Because
 137 // the first chunk in the list is distinguished in this fashion
 138 // (also is the node in the tree), it is the last chunk to be found
 139 // on the free list for a node in the tree and is only removed if
 140 // it is the last chunk on the free list.
 141 
 142 template <class Chunk_t, class FreeList_t>
 143 class TreeChunk : public Chunk_t {
 144   friend class TreeList<Chunk_t, FreeList_t>;
 145   TreeList<Chunk_t, FreeList_t>* _list;
 146   TreeList<Chunk_t, FreeList_t> _embedded_list;  // if non-null, this chunk is on _list
 147 
 148   static size_t _min_tree_chunk_size;
 149 
 150  protected:
 151   TreeList<Chunk_t, FreeList_t>* embedded_list() const { return (TreeList<Chunk_t, FreeList_t>*) &_embedded_list; }
 152   void set_embedded_list(TreeList<Chunk_t, FreeList_t>* v) { _embedded_list = *v; }
 153  public:
 154   TreeList<Chunk_t, FreeList_t>* list() { return _list; }
 155   void set_list(TreeList<Chunk_t, FreeList_t>* v) { _list = v; }
 156   static TreeChunk<Chunk_t, FreeList_t>* as_TreeChunk(Chunk_t* fc);
 157   // Initialize fields in a TreeChunk that should be
 158   // initialized when the TreeChunk is being added to
 159   // a free list in the tree.
 160   void initialize() { embedded_list()->initialize(); }
 161 
 162   Chunk_t* next() const { return Chunk_t::next(); }
 163   Chunk_t* prev() const { return Chunk_t::prev(); }
 164   size_t size() const volatile { return Chunk_t::size(); }
 165 
 166   static size_t min_size() {
 167     return _min_tree_chunk_size;
 168   }
 169 
 170   // debugging
 171   void verify_tree_chunk_list() const;
 172   void assert_is_mangled() const;
 173 };
 174 
 175 
 176 template <class Chunk_t, class FreeList_t>
 177 class BinaryTreeDictionary: public FreeBlockDictionary<Chunk_t> {
 178   friend class VMStructs;
 179   size_t     _total_size;
 180   size_t     _total_free_blocks;
 181   TreeList<Chunk_t, FreeList_t>* _root;
 182 
 183   // private accessors
 184   void set_total_size(size_t v) { _total_size = v; }
 185   virtual void inc_total_size(size_t v);
 186   virtual void dec_total_size(size_t v);
 187   void set_total_free_blocks(size_t v) { _total_free_blocks = v; }
 188   TreeList<Chunk_t, FreeList_t>* root() const { return _root; }
 189   void set_root(TreeList<Chunk_t, FreeList_t>* v) { _root = v; }
 190 
 191   // This field is added and can be set to point to the
 192   // the Mutex used to synchronize access to the
 193   // dictionary so that assertion checking can be done.
 194   // For example it is set to point to _parDictionaryAllocLock.
 195   NOT_PRODUCT(Mutex* _lock;)
 196