[haiku-commits] r33477 - in haiku/trunk/src/apps/debugger: . debug_info dwarf

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 7 Oct 2009 05:17:22 +0200 (CEST)

Author: bonefish
Date: 2009-10-07 05:17:22 +0200 (Wed, 07 Oct 2009)
New Revision: 33477
Changeset: http://dev.haiku-os.org/changeset/33477/haiku

Added:
   haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.cpp
   haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.h
Modified:
   haiku/trunk/src/apps/debugger/Jamfile
   haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/ImageDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/ImageDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/SpecificImageDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/TeamDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/TeamDebugInfo.h
   haiku/trunk/src/apps/debugger/dwarf/DwarfFile.cpp
Log:
* WIP regarding non comilation unit local types:
  - Introduced GlobalTypeLookup interface and GlobalTypeLookupContext to look
    up types by name and cache them.
  - TeamDebugInfo implementes GlobalTypeLookup iterating through all
    ImageDebugInfos, which in turn iterate through all SpecificImageDebugInfos.
  - DwarfImageDebugInfo iterates through all compilation units, using
    a temporary DwarfStackFrameDebugInfo to create the type.
  - DwarfStackFrameDebugInfo no longer caches the types itself, but uses
    GlobalTypeLookupContext. It uses GlobalTypeLookup to look up types not
    defined in the compilation unit.
  - DwarfFile: Made expression evaluation more robust, so that it also works,
    when no subroutine entry, frame pointer, and instruction pointer are
    available (and not used by the expression).
  Basically works already, although the wrong compilation unit might be used
  when resolving values for global types. It's also horribly slow, when there
  are many types in the stack frame.
* DwarfStackFrameDebugInfo::ResolveArrayElementLocation(): The element location
  piece size was set incorrectly (multiplied by 8, although bytes were
  expected).



Modified: haiku/trunk/src/apps/debugger/Jamfile
===================================================================
--- haiku/trunk/src/apps/debugger/Jamfile       2009-10-07 03:16:43 UTC (rev 
33476)
+++ haiku/trunk/src/apps/debugger/Jamfile       2009-10-07 03:17:22 UTC (rev 
33477)
@@ -65,6 +65,7 @@
        Function.cpp
        FunctionDebugInfo.cpp
        FunctionInstance.cpp
+       GlobalTypeLookup.cpp
        ImageDebugInfo.cpp
        ImageDebugInfoProvider.cpp
        NoOpStackFrameDebugInfo.cpp

Modified: haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp 
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp 
2009-10-07 03:17:22 UTC (rev 33477)
@@ -79,6 +79,14 @@
 
 
 status_t
+DebuggerImageDebugInfo::GetType(GlobalTypeLookupContext* context,
+       const BString& name, Type*& _type)
+{
+       return B_UNSUPPORTED;
+}
+
+
+status_t
 DebuggerImageDebugInfo::CreateFrame(Image* image,
        FunctionInstance* functionInstance, CpuState* cpuState,
        StackFrame*& _previousFrame, CpuState*& _previousCpuState)

Modified: haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h   
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h   
2009-10-07 03:17:22 UTC (rev 33477)
@@ -5,6 +5,7 @@
 #ifndef DEBUGGER_IMAGE_DEBUG_INFO_H
 #define DEBUGGER_IMAGE_DEBUG_INFO_H
 
+
 #include "ImageInfo.h"
 #include "SpecificImageDebugInfo.h"
 
@@ -26,6 +27,8 @@
 
        virtual status_t                        GetFunctions(
                                                                        
BObjectList<FunctionDebugInfo>& functions);
+       virtual status_t                        
GetType(GlobalTypeLookupContext* context,
+                                                                       const 
BString& name, Type*& _type);
        virtual status_t                        CreateFrame(Image* image,
                                                                        
FunctionInstance* functionInstance,
                                                                        
CpuState* cpuState,

Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp    
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp    
2009-10-07 03:17:22 UTC (rev 33477)
@@ -33,6 +33,7 @@
 #include "FileSourceCode.h"
 #include "FunctionID.h"
 #include "FunctionInstance.h"
+#include "GlobalTypeLookup.h"
 #include "LocatableFile.h"
 #include "Register.h"
 #include "RegisterMap.h"
@@ -47,32 +48,26 @@
 #include "Variable.h"
 
 
-// #pragma mark - UnwindTargetInterface
+// #pragma mark - BasicTargetInterface
 
 
-struct DwarfImageDebugInfo::UnwindTargetInterface : DwarfTargetInterface {
-       UnwindTargetInterface(const Register* registers, int32 registerCount,
-               RegisterMap* fromDwarfMap, RegisterMap* toDwarfMap, CpuState* 
cpuState,
-               Architecture* architecture, TeamMemory* teamMemory)
+struct DwarfImageDebugInfo::BasicTargetInterface : DwarfTargetInterface {
+       BasicTargetInterface(const Register* registers, int32 registerCount,
+               RegisterMap* fromDwarfMap, Architecture* architecture,
+               TeamMemory* teamMemory)
                :
                fRegisters(registers),
                fRegisterCount(registerCount),
                fFromDwarfMap(fromDwarfMap),
-               fToDwarfMap(toDwarfMap),
-               fCpuState(cpuState),
                fArchitecture(architecture),
                fTeamMemory(teamMemory)
        {
                fFromDwarfMap->AcquireReference();
-               fToDwarfMap->AcquireReference();
-               fCpuState->AcquireReference();
        }
 
-       ~UnwindTargetInterface()
+       ~BasicTargetInterface()
        {
                fFromDwarfMap->ReleaseReference();
-               fToDwarfMap->ReleaseReference();
-               fCpuState->ReleaseReference();
        }
 
        virtual uint32 CountRegisters() const
@@ -88,18 +83,12 @@
 
        virtual bool GetRegisterValue(uint32 index, BVariant& _value) const
        {
-               const Register* reg = _RegisterAt(index);
-               if (reg == NULL)
-                       return false;
-               return fCpuState->GetRegisterValue(reg, _value);
+               return false;
        }
 
        virtual bool SetRegisterValue(uint32 index, const BVariant& value)
        {
-               const Register* reg = _RegisterAt(index);
-               if (reg == NULL)
-                       return false;
-               return fCpuState->SetRegisterValue(reg, value);
+               return false;
        }
 
        virtual bool IsCalleePreservedRegister(uint32 index) const
@@ -129,24 +118,67 @@
                        valueType, _value) == B_OK;
        }
 
-private:
+protected:
        const Register* _RegisterAt(uint32 dwarfIndex) const
        {
                int32 index = fFromDwarfMap->MapRegisterIndex(dwarfIndex);
                return index >= 0 && index < fRegisterCount ? fRegisters + 
index : NULL;
        }
 
-private:
+protected:
        const Register* fRegisters;
        int32                   fRegisterCount;
        RegisterMap*    fFromDwarfMap;
-       RegisterMap*    fToDwarfMap;
-       CpuState*               fCpuState;
        Architecture*   fArchitecture;
        TeamMemory*             fTeamMemory;
 };
 
 
+// #pragma mark - UnwindTargetInterface
+
+
+struct DwarfImageDebugInfo::UnwindTargetInterface : BasicTargetInterface {
+       UnwindTargetInterface(const Register* registers, int32 registerCount,
+               RegisterMap* fromDwarfMap, RegisterMap* toDwarfMap, CpuState* 
cpuState,
+               Architecture* architecture, TeamMemory* teamMemory)
+               :
+               BasicTargetInterface(registers, registerCount, fromDwarfMap,
+                       architecture, teamMemory),
+               fToDwarfMap(toDwarfMap),
+               fCpuState(cpuState)
+       {
+               fToDwarfMap->AcquireReference();
+               fCpuState->AcquireReference();
+       }
+
+       ~UnwindTargetInterface()
+       {
+               fToDwarfMap->ReleaseReference();
+               fCpuState->ReleaseReference();
+       }
+
+       virtual bool GetRegisterValue(uint32 index, BVariant& _value) const
+       {
+               const Register* reg = _RegisterAt(index);
+               if (reg == NULL)
+                       return false;
+               return fCpuState->GetRegisterValue(reg, _value);
+       }
+
+       virtual bool SetRegisterValue(uint32 index, const BVariant& value)
+       {
+               const Register* reg = _RegisterAt(index);
+               if (reg == NULL)
+                       return false;
+               return fCpuState->SetRegisterValue(reg, value);
+       }
+
+private:
+       RegisterMap*    fToDwarfMap;
+       CpuState*               fCpuState;
+};
+
+
 // #pragma mark - EntryListWrapper
 
 
@@ -169,13 +201,14 @@
 
 DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo,
        Architecture* architecture, TeamMemory* teamMemory,
-       FileManager* fileManager, DwarfFile* file)
+       FileManager* fileManager, GlobalTypeLookup* typeLookup, DwarfFile* file)
        :
        fLock("dwarf image debug info"),
        fImageInfo(imageInfo),
        fArchitecture(architecture),
        fTeamMemory(teamMemory),
        fFileManager(fileManager),
+       fTypeLookup(typeLookup),
        fFile(file),
        fTextSegment(NULL),
        fRelocationDelta(0)
@@ -321,6 +354,72 @@
 
 
 status_t
+DwarfImageDebugInfo::GetType(GlobalTypeLookupContext* context,
+       const BString& name, Type*& _type)
+{
+       int32 registerCount = fArchitecture->CountRegisters();
+       const Register* registers = fArchitecture->Registers();
+
+       // get the DWARF -> architecture register map
+       RegisterMap* fromDwarfMap;
+       status_t error = fArchitecture->GetDwarfRegisterMaps(NULL, 
&fromDwarfMap);
+       if (error != B_OK)
+               return error;
+       Reference<RegisterMap> fromDwarfMapReference(fromDwarfMap, true);
+
+       // create the target interface
+       BasicTargetInterface inputInterface(registers, registerCount, 
fromDwarfMap,
+               fArchitecture, fTeamMemory);
+
+       // iterate through all compilation units
+       for (int32 i = 0; CompilationUnit* unit = fFile->CompilationUnitAt(i);
+               i++) {
+               DwarfStackFrameDebugInfo* stackFrameDebugInfo = NULL;
+               Reference<DwarfStackFrameDebugInfo> 
stackFrameDebugInfoReference;
+
+               // iterate through all types of the compilation unit
+               for (DebugInfoEntryList::ConstIterator it
+                               = unit->UnitEntry()->Types().GetIterator();
+                       DIEType* typeEntry = 
dynamic_cast<DIEType*>(it.Next());) {
+                       if (typeEntry->IsDeclaration())
+                               continue;
+
+                       BString typeEntryName;
+                       DwarfUtils::GetFullyQualifiedDIEName(typeEntry, 
typeEntryName);
+                       if (typeEntryName != name)
+                               continue;
+
+                       // The name matches and the entry is not just a 
declaration --
+                       // create the type. First create the 
StackFrameDebugInfo lazily.
+                       if (stackFrameDebugInfo == NULL) {
+                               stackFrameDebugInfo = new(std::nothrow)
+                                       DwarfStackFrameDebugInfo(fArchitecture, 
fFile, unit, NULL,
+                                       fTypeLookup, context, 0, 0, 
&inputInterface, fromDwarfMap);
+                               if (stackFrameDebugInfo == NULL)
+                                       return B_NO_MEMORY;
+                               
stackFrameDebugInfoReference.SetTo(stackFrameDebugInfo, true);
+
+                               error = stackFrameDebugInfo->Init();
+                               if (error != B_OK)
+                                       return error;
+                       }
+
+                       // create the type
+                       Type* type;
+                       error = stackFrameDebugInfo->CreateType(typeEntry, 
type);
+                       if (error != B_OK)
+                               continue;
+
+                       _type = type;
+                       return B_OK;
+               }
+       }
+
+       return B_ENTRY_NOT_FOUND;
+}
+
+
+status_t
 DwarfImageDebugInfo::CreateFrame(Image* image,
        FunctionInstance* functionInstance, CpuState* cpuState,
        StackFrame*& _previousFrame, CpuState*& _previousCpuState)
@@ -393,12 +492,24 @@
                }
        )
 
+       // create a type lookup context
+       GlobalTypeLookupContext* typeLookupContext
+               = new(std::nothrow) GlobalTypeLookupContext;
+       if (typeLookupContext == NULL)
+               return B_NO_MEMORY;
+       Reference<GlobalTypeLookupContext> typeLookupContextReference(
+               typeLookupContext, true);
+
+       error = typeLookupContext->Init();
+       if (error != B_OK)
+               return error;
+
        // create the stack frame debug info
        DIESubprogram* subprogramEntry = function->SubprogramEntry();
        DwarfStackFrameDebugInfo* stackFrameDebugInfo
                = new(std::nothrow) DwarfStackFrameDebugInfo(fArchitecture, 
fFile, unit,
-                       subprogramEntry, instructionPointer, framePointer, 
inputInterface,
-                       fromDwarfMap);
+                       subprogramEntry, fTypeLookup, typeLookupContext, 
instructionPointer,
+                       framePointer, inputInterface, fromDwarfMap);
        if (stackFrameDebugInfo == NULL)
                return B_NO_MEMORY;
        Reference<DwarfStackFrameDebugInfo> stackFrameDebugInfoReference(

Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.h      
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DwarfImageDebugInfo.h      
2009-10-07 03:17:22 UTC (rev 33477)
@@ -23,6 +23,7 @@
 class FileManager;
 class FileSourceCode;
 class FunctionID;
+class GlobalTypeLookup;
 class LocatableFile;
 class SourceCode;
 class TeamMemory;
@@ -33,7 +34,9 @@
                                                                
DwarfImageDebugInfo(const ImageInfo& imageInfo,
                                                                        
Architecture* architecture,
                                                                        
TeamMemory* teamMemory,
-                                                                       
FileManager* fileManager, DwarfFile* file);
+                                                                       
FileManager* fileManager,
+                                                                       
GlobalTypeLookup* typeLookup,
+                                                                       
DwarfFile* file);
        virtual                                         ~DwarfImageDebugInfo();
 
                        status_t                        Init();
@@ -43,6 +46,8 @@
 
        virtual status_t                        GetFunctions(
                                                                        
BObjectList<FunctionDebugInfo>& functions);
+       virtual status_t                        
GetType(GlobalTypeLookupContext* context,
+                                                                       const 
BString& name, Type*& _type);
        virtual status_t                        CreateFrame(Image* image,
                                                                        
FunctionInstance* functionInstance,
                                                                        
CpuState* cpuState,
@@ -66,6 +71,7 @@
                                                                        
FileSourceCode* sourceCode);
 
 private:
+                       struct BasicTargetInterface;
                        struct UnwindTargetInterface;
                        struct EntryListWrapper;
 
@@ -90,6 +96,7 @@
                        Architecture*           fArchitecture;
                        TeamMemory*                     fTeamMemory;
                        FileManager*            fFileManager;
+                       GlobalTypeLookup*       fTypeLookup;
                        DwarfFile*                      fFile;
                        ElfSegment*                     fTextSegment;
                        target_addr_t           fRelocationDelta;

Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp       
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.cpp       
2009-10-07 03:17:22 UTC (rev 33477)
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <new>
 
+#include <AutoLocker.h>
 #include <Variant.h>
 
 #include "ArrayIndexPath.h"
@@ -20,6 +21,7 @@
 #include "DwarfUtils.h"
 #include "FunctionID.h"
 #include "FunctionParameterID.h"
+#include "GlobalTypeLookup.h"
 #include "LocalVariableID.h"
 #include "Register.h"
 #include "RegisterMap.h"
@@ -304,9 +306,6 @@
 private:
        BString                 fName;
        target_size_t   fByteSize;
-
-public:
-       DwarfType*              fNext;
 };
 
 
@@ -1127,80 +1126,41 @@
 };
 
 
-// #pragma mark - DwarfTypeHashDefinition
-
-
-struct DwarfStackFrameDebugInfo::DwarfTypeHashDefinition {
-       typedef const DIEType*  KeyType;
-       typedef DwarfType               ValueType;
-
-       size_t HashKey(const DIEType* key) const
-       {
-               return (addr_t)key;
-       }
-
-       size_t Hash(const DwarfType* value) const
-       {
-               return HashKey(value->GetDIEType());
-       }
-
-       bool Compare(const DIEType* key, const DwarfType* value) const
-       {
-               return key == value->GetDIEType();
-       }
-
-       DwarfType*& GetLink(DwarfType* value) const
-       {
-               return value->fNext;
-       }
-};
-
-
 // #pragma mark - DwarfStackFrameDebugInfo
 
 
 DwarfStackFrameDebugInfo::DwarfStackFrameDebugInfo(Architecture* architecture,
        DwarfFile* file, CompilationUnit* compilationUnit,
-       DIESubprogram* subprogramEntry, target_addr_t instructionPointer,
-       target_addr_t framePointer, DwarfTargetInterface* targetInterface,
-       RegisterMap* fromDwarfRegisterMap)
+       DIESubprogram* subprogramEntry, GlobalTypeLookup* typeLookup,
+       GlobalTypeLookupContext* typeLookupContext,
+       target_addr_t instructionPointer, target_addr_t framePointer,
+       DwarfTargetInterface* targetInterface, RegisterMap* 
fromDwarfRegisterMap)
        :
        StackFrameDebugInfo(architecture),
        fFile(file),
        fCompilationUnit(compilationUnit),
        fSubprogramEntry(subprogramEntry),
+       fTypeLookup(typeLookup),
+       fTypeLookupContext(typeLookupContext),
        fInstructionPointer(instructionPointer),
        fFramePointer(framePointer),
        fTargetInterface(targetInterface),
-       fFromDwarfRegisterMap(fromDwarfRegisterMap),
-       fTypes(NULL)
+       fFromDwarfRegisterMap(fromDwarfRegisterMap)
 {
+       fTypeLookupContext->AcquireReference();
 }
 
 
 DwarfStackFrameDebugInfo::~DwarfStackFrameDebugInfo()
 {
-       if (fTypes != NULL) {
-               DwarfType* type = fTypes->Clear(true);
-               while (type != NULL) {
-                       DwarfType* next = type->fNext;
-                       type->ReleaseReference();
-                       type = next;
-               }
-
-               delete fTypes;
-       }
+       fTypeLookupContext->ReleaseReference();
 }
 
 
 status_t
 DwarfStackFrameDebugInfo::Init()
 {
-       fTypes = new(std::nothrow) TypeTable;
-       if (fTypes == NULL)
-               return B_NO_MEMORY;
-
-       return fTypes->Init();
+       return B_OK;
 }
 
 
@@ -1468,7 +1428,7 @@
                        int64 byteOffset = elementOffset >= 0
                                ? elementOffset / 8 : (elementOffset - 7) / 8;
                        piece.SetToMemory(piece.address + byteOffset);
-                       piece.SetSize(type->BaseType()->ByteSize() * 8);
+                       piece.SetSize(type->BaseType()->ByteSize());
                        // TODO: Support bit offsets correctly!
                        // TODO: Support bit fields (primitive types) correctly!
 
@@ -1647,39 +1607,73 @@
 status_t
 DwarfStackFrameDebugInfo::_CreateType(DIEType* typeEntry, DwarfType*& _type)
 {
-       // Try the type cache first. If we don't know the type yet, create it.
-       DwarfType* type = fTypes->Lookup(typeEntry);
+       // try the type cache first
+       BString name;
+       DwarfUtils::GetFullyQualifiedDIEName(typeEntry, name);
+// TODO: The DIE may not have a name (e.g. pointer and reference types don't).
 
-       if (type == NULL) {
-               status_t error = _CreateTypeInternal(typeEntry, type);
-               if (error != B_OK)
-                       return error;
+       AutoLocker<GlobalTypeLookupContext> contextLocker(fTypeLookupContext);
+       Type* globalType = name.Length() > 0
+               ? fTypeLookupContext->CachedType(name) : NULL;
+       if (globalType != NULL) {
+               DwarfType* globalDwarfType = 
dynamic_cast<DwarfType*>(globalType);
+               if (globalDwarfType != NULL) {
+                       globalDwarfType->AcquireReference();
+                       _type = globalDwarfType;
+                       return B_OK;
+               }
+       }
 
-               // Insert the type into the hash table. Recheck, as the type 
may already
-               // have been inserted (e.g. in the compound type case).
-               if (fTypes->Lookup(typeEntry) == NULL)
-                       fTypes->Insert(type);
+       contextLocker.Unlock();
 
-               // try to get the type's size
-               uint64 size;
-               if (_ResolveTypeByteSize(typeEntry, size) == B_OK)
-                       type->SetByteSize(size);
+       // If the type entry indicates a declaration only, we try to look the
+       // type up globally first.
+       if (typeEntry->IsDeclaration() && name.Length() > 0
+               && fTypeLookup->GetType(fTypeLookupContext, name, globalType)
+                       == B_OK) {
+               DwarfType* globalDwarfType
+                       = dynamic_cast<DwarfType*>(globalType);
+               if (globalDwarfType != NULL) {
+                       _type = globalDwarfType;
+                       return B_OK;
+               }
+
+               globalType->ReleaseReference();
        }
 
-       type->AcquireReference();
-       _type = type;
+       // No luck yet -- create the type.
+       DwarfType* type;
+       status_t error = _CreateTypeInternal(name, typeEntry, type);
+       if (error != B_OK)
+               return error;
+       Reference<DwarfType> typeReference(type, true);
+
+       // Insert the type into the cache. Re-check, as the type may already
+       // have been inserted (e.g. in the compound type case).
+       if (name.Length() > 0) {
+               contextLocker.Lock();
+               if (fTypeLookupContext->CachedType(name) == NULL) {
+                       error = fTypeLookupContext->AddCachedType(name, type);
+                       if (error != B_OK)
+                               return error;
+               }
+               contextLocker.Unlock();
+       }
+
+       // try to get the type's size
+       uint64 size;
+       if (_ResolveTypeByteSize(typeEntry, size) == B_OK)
+               type->SetByteSize(size);
+
+       _type = typeReference.Detach();
        return B_OK;
 }
 
 
 status_t
-DwarfStackFrameDebugInfo::_CreateTypeInternal(DIEType* typeEntry,
-       DwarfType*& _type)
+DwarfStackFrameDebugInfo::_CreateTypeInternal(const BString& name,
+       DIEType* typeEntry, DwarfType*& _type)
 {
-       BString name;
-       DwarfUtils::GetFullyQualifiedDIEName(typeEntry, name);
-// TODO: The DIE may not have a name (e.g. pointer and reference types don't).
-
        switch (typeEntry->Tag()) {
                case DW_TAG_class_type:
                case DW_TAG_structure_type:
@@ -1775,10 +1769,17 @@
                return B_NO_MEMORY;
        Reference<DwarfCompoundType> typeReference(type, true);
 
-       // Already add the type at this pointer to the hash table, since 
otherwise
+       // Already add the type at this pointer to the cache, since otherwise
        // we could run into an infinite recursion when trying to create the 
types
        // for the data members.
-       fTypes->Insert(type);
+// TODO: Since access to the type lookup context is multi-threaded, the
+// incomplete type could become visible to other threads. Hence we keep the
+// context locked, but that essentially kills multi-threading for this context.
+       AutoLocker<GlobalTypeLookupContext> contextLocker(fTypeLookupContext);
+       status_t error = fTypeLookupContext->AddCachedType(name, type);
+       if (error != B_OK)
+               return error;
+//     contextLocker.Unlock();
 
        // find the abstract origin or specification that defines the data 
members
        DIECompoundType* memberOwnerEntry = 
DwarfUtils::GetDIEByPredicate(typeEntry,
@@ -1808,7 +1809,8 @@
                                memberEntry, memberName, memberType);
                        Reference<DwarfDataMember> memberReference(member, 
true);
                        if (member == NULL || !type->AddDataMember(member)) {
-                               fTypes->Remove(type);
+                               contextLocker.Lock();
+                               fTypeLookupContext->RemoveCachedType(name);
                                return B_NO_MEMORY;
                        }
                }
@@ -1842,7 +1844,8 @@
                                Reference<DwarfInheritance> 
inheritanceReference(inheritance,
                                        true);
                                if (inheritance == NULL || 
!type->AddInheritance(inheritance)) {
-                                       fTypes->Remove(type);
+                                       contextLocker.Lock();
+                                       
fTypeLookupContext->RemoveCachedType(name);
                                        return B_NO_MEMORY;
                                }
                        }

Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h 
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DwarfStackFrameDebugInfo.h 
2009-10-07 03:17:22 UTC (rev 33477)
@@ -8,8 +8,6 @@
 
 #include <String.h>
 
-#include <util/OpenHashTable.h>
-
 #include "StackFrameDebugInfo.h"
 #include "Type.h"
 
@@ -33,6 +31,8 @@
 class DwarfFile;
 class DwarfTargetInterface;
 class FunctionID;
+class GlobalTypeLookup;
+class GlobalTypeLookupContext;
 class LocationDescription;
 class MemberLocation;
 class ObjectID;
@@ -46,6 +46,8 @@
                                                                        
Architecture* architecture, DwarfFile* file,
                                                                        
CompilationUnit* compilationUnit,
                                                                        
DIESubprogram* subprogramEntry,
+                                                                       
GlobalTypeLookup* typeLookup,
+                                                                       
GlobalTypeLookupContext* typeLookupContext,
                                                                        
target_addr_t instructionPointer,
                                                                        
target_addr_t framePointer,
                                                                        
DwarfTargetInterface* targetInterface,
@@ -105,10 +107,7 @@
                        struct DwarfUnspecifiedType;
                        struct DwarfFunctionType;
                        struct DwarfPointerToMemberType;
-                       struct DwarfTypeHashDefinition;
 
-                       typedef BOpenHashTable<DwarfTypeHashDefinition> 
TypeTable;
-
 private:
                        status_t                        
_ResolveDataMemberLocation(
                                                                        
StackFrame* stackFrame,
@@ -121,8 +120,8 @@
 
                        status_t                        _CreateType(DIEType* 
typeEntry,
                                                                        
DwarfType*& _type);
-                       status_t                        
_CreateTypeInternal(DIEType* typeEntry,
-                                                                       
DwarfType*& _type);
+                       status_t                        
_CreateTypeInternal(const BString& name,
+                                                                       
DIEType* typeEntry, DwarfType*& _type);
 
                        status_t                        
_CreateCompoundType(const BString& name,
                                                                        
DIECompoundType* typeEntry,
@@ -180,11 +179,12 @@
                        DwarfFile*                      fFile;
                        CompilationUnit*        fCompilationUnit;
                        DIESubprogram*          fSubprogramEntry;
+                       GlobalTypeLookup*       fTypeLookup;
+                       GlobalTypeLookupContext* fTypeLookupContext;
                        target_addr_t           fInstructionPointer;
                        target_addr_t           fFramePointer;
                        DwarfTargetInterface* fTargetInterface;
                        RegisterMap*            fFromDwarfRegisterMap;
-                       TypeTable*                      fTypes;
 };
 
 

Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp     
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp     
2009-10-07 03:17:22 UTC (rev 33477)
@@ -15,12 +15,14 @@
 
 
 DwarfTeamDebugInfo::DwarfTeamDebugInfo(Architecture* architecture,
-       TeamMemory* teamMemory, FileManager* fileManager)
+       TeamMemory* teamMemory, FileManager* fileManager,
+       GlobalTypeLookup* typeLookup)
        :
        fArchitecture(architecture),
        fTeamMemory(teamMemory),
        fFileManager(fileManager),
-       fManager(NULL)
+       fManager(NULL),
+       fTypeLookup(typeLookup)
 {
 }
 
@@ -64,17 +66,17 @@
                return error;
 
        // create the image debug info
-       DwarfImageDebugInfo* debuggerInfo = new(std::nothrow) 
DwarfImageDebugInfo(
-               imageInfo, fArchitecture, fTeamMemory, fFileManager, file);
-       if (debuggerInfo == NULL)
+       DwarfImageDebugInfo* debugInfo = new(std::nothrow) DwarfImageDebugInfo(
+               imageInfo, fArchitecture, fTeamMemory, fFileManager, 
fTypeLookup, file);
+       if (debugInfo == NULL)
                return B_NO_MEMORY;
 
-       error = debuggerInfo->Init();
+       error = debugInfo->Init();
        if (error != B_OK) {
-               delete debuggerInfo;
+               delete debugInfo;
                return error;
        }
 
-       _imageDebugInfo = debuggerInfo;
+       _imageDebugInfo = debugInfo;
        return B_OK;
 }

Modified: haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h       
2009-10-07 03:16:43 UTC (rev 33476)
+++ haiku/trunk/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h       
2009-10-07 03:17:22 UTC (rev 33477)
@@ -12,6 +12,7 @@
 class DwarfManager;
 class FileManager;
 class ImageInfo;
+class GlobalTypeLookup;
 class TeamMemory;
 
 
@@ -19,7 +20,8 @@
 public:
                                                                
DwarfTeamDebugInfo(Architecture* architecture,
                                                                        
TeamMemory* teamMemory,
-                                                                       
FileManager* fileManager);
+                                                                       
FileManager* fileManager,
+                                                                       
GlobalTypeLookup* typeLookup);
        virtual                                         ~DwarfTeamDebugInfo();
 
                        status_t                        Init();
@@ -33,6 +35,7 @@
                        TeamMemory*                     fTeamMemory;
                        FileManager*            fFileManager;
                        DwarfManager*           fManager;
+                       GlobalTypeLookup*       fTypeLookup;
 };
 
 

Added: haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.cpp               
                (rev 0)
+++ haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.cpp       
2009-10-07 03:17:22 UTC (rev 33477)
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "GlobalTypeLookup.h"
+
+#include <new>
+
+#include <String.h>
+
+#include "StringUtils.h"
+#include "Type.h"
+
+
+struct GlobalTypeLookupContext::TypeEntry {
+       BString         name;
+       Type*           type;
+       TypeEntry*      fNext;
+
+       TypeEntry(const BString& name, Type* type)
+               :
+               name(name),
+               type(type)
+       {
+               type->AcquireReference();
+       }
+
+       ~TypeEntry()
+       {
+               type->ReleaseReference();
+       }
+};
+
+
+struct GlobalTypeLookupContext::TypeEntryHashDefinition {
+       typedef const BString   KeyType;
+       typedef TypeEntry               ValueType;
+
+       size_t HashKey(const BString& key) const
+       {
+               return StringUtils::HashValue(key);
+       }
+
+       size_t Hash(const TypeEntry* value) const
+       {
+               return HashKey(value->name);
+       }
+
+       bool Compare(const BString& key, const TypeEntry* value) const
+       {
+               return key == value->name;
+       }
+
+       TypeEntry*& GetLink(TypeEntry* value) const
+       {
+               return value->fNext;
+       }
+};
+
+
+// #pragma mark - GlobalTypeLookupContext
+
+
+GlobalTypeLookupContext::GlobalTypeLookupContext()
+       :
+       fLock("global type lookup"),
+       fCachedTypes(NULL)
+{
+}
+
+
+GlobalTypeLookupContext::~GlobalTypeLookupContext()
+{
+       // release all cached type references
+       if (fCachedTypes != NULL) {
+               TypeEntry* entry = fCachedTypes->Clear(true);
+               while (entry != NULL) {
+                       TypeEntry* nextEntry = entry->fNext;
+                       delete entry;
+                       entry = nextEntry;
+               }
+       }
+}
+
+
+status_t
+GlobalTypeLookupContext::Init()
+{
+       status_t error = fLock.InitCheck();
+       if (error != B_OK)
+               return error;
+
+       fCachedTypes = new(std::nothrow) TypeTable;
+       if (fCachedTypes == NULL)
+               return B_NO_MEMORY;
+
+       return fCachedTypes->Init();
+}
+
+
+Type*
+GlobalTypeLookupContext::CachedType(const BString& name) const
+{
+       TypeEntry* typeEntry = fCachedTypes->Lookup(name);
+       return typeEntry != NULL ? typeEntry->type : NULL;
+}
+
+
+status_t
+GlobalTypeLookupContext::AddCachedType(const BString& name, Type* type)
+{
+       TypeEntry* typeEntry = fCachedTypes->Lookup(name);
+       if (typeEntry != NULL)
+               return B_BAD_VALUE;
+
+       typeEntry = new(std::nothrow) TypeEntry(name, type);
+       if (typeEntry == NULL)
+               return B_NO_MEMORY;
+
+       fCachedTypes->Insert(typeEntry);
+       return B_OK;
+}
+
+
+void
+GlobalTypeLookupContext::RemoveCachedType(const BString& name)
+{
+       if (TypeEntry* typeEntry = fCachedTypes->Lookup(name)) {
+               fCachedTypes->Remove(typeEntry);
+               delete typeEntry;
+       }
+}
+
+
+// #pragma mark - GlobalTypeLookup
+
+
+GlobalTypeLookup::~GlobalTypeLookup()
+{
+}

Added: haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.h
===================================================================
--- haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.h                 
        (rev 0)
+++ haiku/trunk/src/apps/debugger/debug_info/GlobalTypeLookup.h 2009-10-07 
03:17:22 UTC (rev 33477)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef GLOBAL_TYPE_LOOKUP_H
+#define GLOBAL_TYPE_LOOKUP_H
+
+
+#include <Locker.h>
+
+#include <Referenceable.h>
+#include <util/OpenHashTable.h>
+
+
+class BString;
+class Type;
+
+
+class GlobalTypeLookupContext : public Referenceable {
+public:
+                                                               
GlobalTypeLookupContext();
+                                                               
~GlobalTypeLookupContext();
+
+                       status_t                        Init();
+
+       inline  bool                            Lock();
+       inline  void                            Unlock();
+
+                       // context must be locked
+                       Type*                           CachedType(const 
BString& name) const;
+                       status_t                        AddCachedType(const 
BString& name, Type* type);
+                       void                            RemoveCachedType(const 
BString& name);
+
+private:
+                       struct TypeEntry;
+                       struct TypeEntryHashDefinition;
+
+                       typedef BOpenHashTable<TypeEntryHashDefinition> 
TypeTable;
+
+private:
+                       BLocker                         fLock;
+                       TypeTable*                      fCachedTypes;
+};
+
+
+class GlobalTypeLookup {
+public:
+                                                               
~GlobalTypeLookup();
+
+       virtual status_t                        
GetType(GlobalTypeLookupContext* context,
+                                                                       const 
BString& name, Type*& _type) = 0;
+                                                                       // 
returns a reference
+};
+
+
+bool
+GlobalTypeLookupContext::Lock()
+{
+       return fLock.Lock();
+}
+
+
+void
+GlobalTypeLookupContext::Unlock()
+{
+       fLock.Unlock();
+}
+
+
+#endif // GLOBAL_TYPE_LOOKUP_H

[... truncated: 251 lines follow ...]

Other related posts:

  • » [haiku-commits] r33477 - in haiku/trunk/src/apps/debugger: . debug_info dwarf - ingo_weinhold