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 ...]