Type-mem.h

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #if !defined(TYPE_MEM_H_)
00032 #define TYPE_MEM_H_
00033 
00034 #include "symtabAPI/h/Type.h"
00035 #include "boost/static_assert.hpp"
00036 
00037 namespace Dyninst {
00038   namespace SymtabAPI {
00039     extern std::map<void *, size_t> type_memory;
00040   }
00041 }
00042 
00043 using namespace Dyninst;
00044 using namespace SymtabAPI;
00045 
00046 template<class T>
00047 T *upgradePlaceholder(Type *placeholder, T *new_type)
00048 {
00049   void *mem = (void *) placeholder;
00050   assert(type_memory.count(mem));
00051   size_t size = type_memory[mem];
00052 
00053   assert(sizeof(T) < size);
00054   memset(mem, 0, size);
00055 
00056   T *ret = new(mem) T();
00057   assert(mem == (void *) ret);
00058   *ret = *new_type;
00059   return ret;
00060 }
00061 
00062 template<class T>
00063 T* typeCollection::addOrUpdateType(T *type) 
00064 {
00065     //Instanciating this function for 'Type' would be a mistake, which
00066     //the following assert tries to guard against.  If you trigger this,
00067     //then a caller to this function is likely using 'Type'.  Change
00068     //this to a more specific call, e.g. typeFunction instead of Type
00069     BOOST_STATIC_ASSERT(sizeof(T) != sizeof(Type));
00070 
00071     Type *existingType = findTypeLocal(type->getID());
00072     if (!existingType) 
00073     {
00074         if ( type->getName() != "" ) 
00075         {
00076             typesByName[ type->getName() ] = type;
00077         }
00078         typesByID[ type->getID() ] = type;
00079         type->incrRefCount();
00080         return type;
00081     }
00082 
00083     /* Multiple inclusions of the same object file can result
00084        in us parsing the same module types repeatedly. GCC does this
00085        with some of its internal routines */
00086 
00087     T *existingT = dynamic_cast<T*>(existingType);
00088     if (existingT && (*existingT == *type)) 
00089     {
00090         return (T*) existingType;
00091     }
00092 
00093     if (existingType->getDataClass() == dataUnknownType) 
00094     {
00095         upgradePlaceholder(existingType, type);
00096     } 
00097     else 
00098     {
00099         /* Merge the type information. */
00100         existingType->merge(type);
00101     }
00102 
00103     /* The type may have gained a name. */
00104     if ( existingType->getName() != "") 
00105     {
00106         if (typesByName.find(existingType->getName()) != typesByName.end()) 
00107         {
00108             if (typesByName[ existingType->getName() ] != existingType) 
00109             {
00110                 typesByName[ existingType->getName() ]->decrRefCount();
00111                 typesByName[ existingType->getName() ] = existingType;
00112                 existingType->incrRefCount();
00113             }
00114         } 
00115         else 
00116         {
00117             typesByName[ existingType->getName() ] = existingType;
00118             existingType->incrRefCount();
00119         }
00120     }
00121 
00122     /* Tell the parser to update its type pointer. */
00123     return (T*) existingType;
00124 } /* end addOrUpdateType() */
00125 
00126 
00127 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1