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