TreeAllocator.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- TreeAllocator.h ----------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_TREE_ALLOCATOR_H
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_TREE_ALLOCATOR_H
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <set>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/Support/GCFactory.h"
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/ADT/TreeBase.h"
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class NodeFactory
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief NodeFactory manages the creation and destruction of mcld::Node.
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  NodeFactory guarantees all allocated memory are released finally. When
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  the destructor of NodeFactory is called, all allocated memory are freed.
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  NodeFactory provides delegation of memory. Sometimes, we have to merge two
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  NodeFactories, and NodeFactory::delegate() can move the memory from one
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  NodeFactories to another.
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  @see LinearAllocator
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename DataType>
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass NodeFactory : public GCFactory<Node<DataType>, 64>
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef GCFactory<Node<DataType>, 64> Alloc;
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef Node<DataType>                 NodeType;
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef typename Alloc::iterator       iterator;
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef typename Alloc::const_iterator const_iterator;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// produce - produce a node, add it under control
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  NodeType* produce() {
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    NodeType* result = Alloc::allocate();
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::construct(result);
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// delegate - get the control of chunks owned by the client
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //  after calling delegate(), client will renouce its control
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //  of memory space.
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void delegate(NodeFactory& pClient) {
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (this == &pClient)
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (pClient.empty())
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (Alloc::empty()) {
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      replace(pClient);
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pClient.renounce();
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // neither me nor client is empty
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    concatenate(pClient);
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pClient.renounce();
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// renounce - give up the control of all chunks
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void renounce()
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { Alloc::reset(); }
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// replace - be the agent of client.
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void replace(NodeFactory& pClient) {
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_pRoot = pClient.Alloc::m_pRoot;
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_pCurrent = pClient.Alloc::m_pCurrent;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_AllocatedNum = pClient.Alloc::m_AllocatedNum;
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_NumAllocData = pClient.Alloc::m_NumAllocData;
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// concatenate - conncet two factories
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void concatenate(NodeFactory& pClient) {
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_pCurrent->next = pClient.Alloc::m_pRoot;
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_pCurrent = pClient.Alloc::m_pCurrent;
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_AllocatedNum += pClient.Alloc::m_AllocatedNum;
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::m_NumAllocData += pClient.Alloc::m_NumAllocData;
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
99