Rather resolve range lists lazily. We need them for all functions, but there

are a lot more DIEs that have range lists.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-07-15 12:37:56 +00:00
parent 78888c44da
commit 3c33a74c01
8 changed files with 115 additions and 112 deletions
@@ -37,6 +37,7 @@
#include "StackFrame.h" #include "StackFrame.h"
#include "Statement.h" #include "Statement.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "TargetAddressRangeList.h"
#include "TeamMemory.h" #include "TeamMemory.h"
#include "UnsupportedLanguage.h" #include "UnsupportedLanguage.h"
@@ -230,9 +231,8 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits());
continue; continue;
// get the address ranges // get the address ranges
TargetAddressRangeList* rangeList TargetAddressRangeList* rangeList = fFile->ResolveRangeList(unit,
= subprogramEntry->AddressRanges(); subprogramEntry->AddressRangesOffset());
Reference<TargetAddressRangeList> rangeListReference(rangeList);
if (rangeList == NULL) { if (rangeList == NULL) {
target_addr_t lowPC = subprogramEntry->LowPC(); target_addr_t lowPC = subprogramEntry->LowPC();
target_addr_t highPC = subprogramEntry->HighPC(); target_addr_t highPC = subprogramEntry->HighPC();
@@ -244,8 +244,9 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits());
if (rangeList == NULL) if (rangeList == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
// TODO: Clean up already added functions! // TODO: Clean up already added functions!
rangeListReference.SetTo(rangeList, true);
} }
Reference<TargetAddressRangeList> rangeListReference(rangeList,
true);
// get the source location // get the source location
const char* directoryPath = NULL; const char* directoryPath = NULL;
+2 -10
View File
@@ -6,7 +6,6 @@
#define ATTRIBUTE_VALUE_H #define ATTRIBUTE_VALUE_H
#include "AttributeClasses.h" #include "AttributeClasses.h"
#include "TargetAddressRangeList.h"
#include "Types.h" #include "Types.h"
@@ -22,7 +21,6 @@ struct AttributeValue {
} block; } block;
uint64 constant; uint64 constant;
bool flag; bool flag;
TargetAddressRangeList* rangeList;
off_t pointer; off_t pointer;
DebugInfoEntry* reference; DebugInfoEntry* reference;
const char* string; const char* string;
@@ -94,13 +92,11 @@ struct AttributeValue {
this->pointer = value; this->pointer = value;
} }
void SetToRangeList(TargetAddressRangeList* rangeList) void SetToRangeListPointer(off_t value)
{ {
Unset(); Unset();
attributeClass = ATTRIBUTE_CLASS_RANGELISTPTR; attributeClass = ATTRIBUTE_CLASS_RANGELISTPTR;
this->rangeList = rangeList; this->pointer = value;
if (rangeList != NULL)
rangeList->AddReference();
} }
void SetToReference(DebugInfoEntry* entry) void SetToReference(DebugInfoEntry* entry)
@@ -119,10 +115,6 @@ struct AttributeValue {
void Unset() void Unset()
{ {
if (attributeClass == ATTRIBUTE_CLASS_RANGELISTPTR
&& rangeList != NULL) {
rangeList->RemoveReference();
}
attributeClass = ATTRIBUTE_CLASS_UNKNOWN; attributeClass = ATTRIBUTE_CLASS_UNKNOWN;
} }
@@ -3,10 +3,14 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "CompilationUnit.h" #include "CompilationUnit.h"
#include <new> #include <new>
#include "DebugInfoEntries.h"
#include "TargetAddressRangeList.h"
struct CompilationUnit::File { struct CompilationUnit::File {
BString fileName; BString fileName;
@@ -32,6 +36,7 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset,
fAbbreviationOffset(abbreviationOffset), fAbbreviationOffset(abbreviationOffset),
fAbbreviationTable(NULL), fAbbreviationTable(NULL),
fUnitEntry(NULL), fUnitEntry(NULL),
fAddressRanges(NULL),
fDirectories(10, true), fDirectories(10, true),
fFiles(10, true), fFiles(10, true),
fLineNumberProgram(addressSize), fLineNumberProgram(addressSize),
@@ -43,6 +48,7 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset,
CompilationUnit::~CompilationUnit() CompilationUnit::~CompilationUnit()
{ {
SetAddressRanges(NULL);
} }
@@ -74,6 +80,29 @@ CompilationUnit::SetUnitEntry(DIECompileUnitBase* entry)
} }
void
CompilationUnit::SetAddressRanges(TargetAddressRangeList* ranges)
{
if (fAddressRanges != NULL)
fAddressRanges->ReleaseReference();
fAddressRanges = ranges;
if (fAddressRanges != NULL)
fAddressRanges->AcquireReference();
}
target_addr_t
CompilationUnit::AddressRangeBase() const
{
if (fAddressRanges != NULL)
return fAddressRanges->LowestAddress();
return fUnitEntry != NULL ? fUnitEntry->LowPC() : 0;
}
int int
CompilationUnit::CountEntries() const CompilationUnit::CountEntries() const
{ {
+10
View File
@@ -5,6 +5,7 @@
#ifndef COMPILATION_UNIT_H #ifndef COMPILATION_UNIT_H
#define COMPILATION_UNIT_H #define COMPILATION_UNIT_H
#include <String.h> #include <String.h>
#include <ObjectList.h> #include <ObjectList.h>
@@ -17,6 +18,7 @@
class AbbreviationTable; class AbbreviationTable;
class DebugInfoEntry; class DebugInfoEntry;
class DIECompileUnitBase; class DIECompileUnitBase;
class TargetAddressRangeList;
class CompilationUnit { class CompilationUnit {
@@ -51,6 +53,13 @@ public:
DIECompileUnitBase* UnitEntry() const { return fUnitEntry; } DIECompileUnitBase* UnitEntry() const { return fUnitEntry; }
void SetUnitEntry(DIECompileUnitBase* entry); void SetUnitEntry(DIECompileUnitBase* entry);
TargetAddressRangeList* AddressRanges() const
{ return fAddressRanges; }
void SetAddressRanges(
TargetAddressRangeList* ranges);
target_addr_t AddressRangeBase() const;
LineNumberProgram& GetLineNumberProgram() LineNumberProgram& GetLineNumberProgram()
{ return fLineNumberProgram; } { return fLineNumberProgram; }
@@ -82,6 +91,7 @@ private:
off_t fAbbreviationOffset; off_t fAbbreviationOffset;
AbbreviationTable* fAbbreviationTable; AbbreviationTable* fAbbreviationTable;
DIECompileUnitBase* fUnitEntry; DIECompileUnitBase* fUnitEntry;
TargetAddressRangeList* fAddressRanges;
Array<DebugInfoEntry*> fEntries; Array<DebugInfoEntry*> fEntries;
Array<off_t> fEntryOffsets; Array<off_t> fEntryOffsets;
DirectoryList fDirectories; DirectoryList fDirectories;
+6 -35
View File
@@ -21,10 +21,9 @@ DIECompileUnitBase::DIECompileUnitBase()
fCompilationDir(NULL), fCompilationDir(NULL),
fLowPC(0), fLowPC(0),
fHighPC(0), fHighPC(0),
fStatementListOffset(0), fStatementListOffset(-1),
fMacroInfoOffset(0), fMacroInfoOffset(-1),
// TODO: Is 0 a good invalid offset? fAddressRangesOffset(-1),
fAddressRanges(NULL),
fBaseTypesUnit(NULL), fBaseTypesUnit(NULL),
fLanguage(0), fLanguage(0),
fIdentifierCase(0), fIdentifierCase(0),
@@ -35,8 +34,6 @@ DIECompileUnitBase::DIECompileUnitBase()
DIECompileUnitBase::~DIECompileUnitBase() DIECompileUnitBase::~DIECompileUnitBase()
{ {
if (fAddressRanges != NULL)
fAddressRanges->RemoveReference();
} }
@@ -73,16 +70,6 @@ DIECompileUnitBase::Name() const
} }
target_addr_t
DIECompileUnitBase::AddressRangeBase() const
{
if (fAddressRanges != NULL)
return fAddressRanges->LowestAddress();
return fLowPC;
}
status_t status_t
DIECompileUnitBase::AddChild(DebugInfoEntry* child) DIECompileUnitBase::AddChild(DebugInfoEntry* child)
{ {
@@ -197,14 +184,7 @@ status_t
DIECompileUnitBase::AddAttribute_ranges(uint16 attributeName, DIECompileUnitBase::AddAttribute_ranges(uint16 attributeName,
const AttributeValue& value) const AttributeValue& value)
{ {
if (fAddressRanges != NULL) fAddressRangesOffset = value.pointer;
fAddressRanges->RemoveReference();
fAddressRanges = value.rangeList;
if (fAddressRanges != NULL)
fAddressRanges->AddReference();
return B_OK; return B_OK;
} }
@@ -1547,7 +1527,7 @@ DIESubprogram::DIESubprogram()
: :
fLowPC(0), fLowPC(0),
fHighPC(0), fHighPC(0),
fAddressRanges(NULL), fAddressRangesOffset(-1),
fSpecification(NULL), fSpecification(NULL),
fAbstractOrigin(NULL), fAbstractOrigin(NULL),
fReturnType(NULL), fReturnType(NULL),
@@ -1560,8 +1540,6 @@ DIESubprogram::DIESubprogram()
DIESubprogram::~DIESubprogram() DIESubprogram::~DIESubprogram()
{ {
if (fAddressRanges != NULL)
fAddressRanges->RemoveReference();
} }
@@ -1609,14 +1587,7 @@ status_t
DIESubprogram::AddAttribute_ranges(uint16 attributeName, DIESubprogram::AddAttribute_ranges(uint16 attributeName,
const AttributeValue& value) const AttributeValue& value)
{ {
if (fAddressRanges != NULL) fAddressRangesOffset = value.pointer;
fAddressRanges->RemoveReference();
fAddressRanges = value.rangeList;
if (fAddressRanges != NULL)
fAddressRanges->AddReference();
return B_OK; return B_OK;
} }
+6 -7
View File
@@ -151,12 +151,11 @@ public:
const DebugInfoEntryList& Types() const { return fTypes; } const DebugInfoEntryList& Types() const { return fTypes; }
const DebugInfoEntryList& OtherChildren() const const DebugInfoEntryList& OtherChildren() const
{ return fOtherChildren; } { return fOtherChildren; }
TargetAddressRangeList* AddressRanges() const off_t AddressRangesOffset() const
{ return fAddressRanges; } { return fAddressRangesOffset; }
target_addr_t LowPC() const { return fLowPC; } target_addr_t LowPC() const { return fLowPC; }
target_addr_t HighPC() const { return fHighPC; } target_addr_t HighPC() const { return fHighPC; }
target_addr_t AddressRangeBase() const;
off_t StatementListOffset() const off_t StatementListOffset() const
{ return fStatementListOffset; } { return fStatementListOffset; }
@@ -202,7 +201,7 @@ protected:
target_addr_t fHighPC; target_addr_t fHighPC;
off_t fStatementListOffset; off_t fStatementListOffset;
off_t fMacroInfoOffset; off_t fMacroInfoOffset;
TargetAddressRangeList* fAddressRanges; off_t fAddressRangesOffset;
DIECompileUnitBase* fBaseTypesUnit; DIECompileUnitBase* fBaseTypesUnit;
DebugInfoEntryList fTypes; DebugInfoEntryList fTypes;
DebugInfoEntryList fOtherChildren; DebugInfoEntryList fOtherChildren;
@@ -1025,8 +1024,8 @@ public:
virtual DebugInfoEntry* Specification() const; virtual DebugInfoEntry* Specification() const;
virtual DebugInfoEntry* AbstractOrigin() const; virtual DebugInfoEntry* AbstractOrigin() const;
TargetAddressRangeList* AddressRanges() const off_t AddressRangesOffset() const
{ return fAddressRanges; } { return fAddressRangesOffset; }
target_addr_t LowPC() const { return fLowPC; } target_addr_t LowPC() const { return fLowPC; }
target_addr_t HighPC() const { return fHighPC; } target_addr_t HighPC() const { return fHighPC; }
@@ -1057,7 +1056,7 @@ public:
protected: protected:
target_addr_t fLowPC; target_addr_t fLowPC;
target_addr_t fHighPC; target_addr_t fHighPC;
TargetAddressRangeList* fAddressRanges; off_t fAddressRangesOffset;
DIESubprogram* fSpecification; DIESubprogram* fSpecification;
DIESubprogram* fAbstractOrigin; DIESubprogram* fAbstractOrigin;
DIEType* fReturnType; DIEType* fReturnType;
+54 -56
View File
@@ -223,6 +223,52 @@ DwarfFile::CompilationUnitForDIE(const DebugInfoEntry* entry) const
} }
TargetAddressRangeList*
DwarfFile::ResolveRangeList(CompilationUnit* unit, uint64 offset) const
{
if (unit == NULL || fDebugRangesSection == NULL)
return NULL;
if (offset < 0 || offset >= (uint64)fDebugRangesSection->Size())
return NULL;
TargetAddressRangeList* ranges = new(std::nothrow) TargetAddressRangeList;
if (ranges == NULL) {
fprintf(stderr, "Out of memory.\n");
return NULL;
}
Reference<TargetAddressRangeList> rangesReference(ranges, true);
target_addr_t baseAddress = unit->AddressRangeBase();
target_addr_t maxAddress = unit->MaxAddress();
DataReader dataReader((uint8*)fDebugRangesSection->Data() + offset,
fDebugRangesSection->Size() - offset, unit->AddressSize());
while (true) {
target_addr_t start = dataReader.ReadAddress(0);
target_addr_t end = dataReader.ReadAddress(0);
if (dataReader.HasOverflow())
return NULL;
if (start == 0 && end == 0)
break;
if (start == maxAddress) {
baseAddress = end;
continue;
}
if (start == end)
continue;
if (!ranges->AddRange(baseAddress + start, end - start)) {
fprintf(stderr, "Out of memory.\n");
return NULL;
}
}
return rangesReference.Detach();
}
status_t status_t
DwarfFile::UnwindCallFrame(CompilationUnit* unit, target_addr_t location, DwarfFile::UnwindCallFrame(CompilationUnit* unit, target_addr_t location,
const DwarfTargetInterface* inputInterface, const DwarfTargetInterface* inputInterface,
@@ -581,6 +627,13 @@ printf("entry %p at %lld\n", entry, offset);
} }
} }
// resolve the compilation unit's address range list
if (TargetAddressRangeList* ranges = ResolveRangeList(unit,
unit->UnitEntry()->AddressRangesOffset())) {
unit->SetAddressRanges(ranges);
ranges->ReleaseReference();
}
// add compilation dir to directory list // add compilation dir to directory list
const char* compilationDir = unit->UnitEntry()->CompilationDir(); const char* compilationDir = unit->UnitEntry()->CompilationDir();
if (!unit->AddDirectory(compilationDir != NULL ? compilationDir : ".")) if (!unit->AddDirectory(compilationDir != NULL ? compilationDir : "."))
@@ -743,15 +796,8 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader,
attributeValue.SetToMacroPointer(value); attributeValue.SetToMacroPointer(value);
break; break;
case ATTRIBUTE_CLASS_RANGELISTPTR: case ATTRIBUTE_CLASS_RANGELISTPTR:
{ attributeValue.SetToRangeListPointer(value);
if (entry != NULL) {
TargetAddressRangeList* rangeList
= _ResolveRangeList(value);
Reference<TargetAddressRangeList> reference(rangeList);
attributeValue.SetToRangeList(rangeList);
}
break; break;
}
case ATTRIBUTE_CLASS_REFERENCE: case ATTRIBUTE_CLASS_REFERENCE:
if (entry != NULL) { if (entry != NULL) {
attributeValue.SetToReference(_ResolveReference(value, attributeValue.SetToReference(_ResolveReference(value,
@@ -1334,51 +1380,3 @@ DwarfFile::_ResolveReference(uint64 offset, bool localReference) const
// TODO: Implement program-global references! // TODO: Implement program-global references!
return NULL; return NULL;
} }
TargetAddressRangeList*
DwarfFile::_ResolveRangeList(uint64 offset)
{
if (fDebugRangesSection == NULL)
return NULL;
if (offset >= (uint64)fDebugRangesSection->Size())
return NULL;
TargetAddressRangeList* ranges = new(std::nothrow) TargetAddressRangeList;
if (ranges == NULL) {
fprintf(stderr, "Out of memory.\n");
return NULL;
}
Reference<TargetAddressRangeList> rangesReference(ranges);
target_addr_t baseAddress
= fCurrentCompilationUnit->UnitEntry()->AddressRangeBase();
target_addr_t maxAddress = fCurrentCompilationUnit->MaxAddress();
DataReader dataReader((uint8*)fDebugRangesSection->Data() + offset,
fDebugRangesSection->Size() - offset,
fCurrentCompilationUnit->AddressSize());
while (true) {
target_addr_t start = dataReader.ReadAddress(0);
target_addr_t end = dataReader.ReadAddress(0);
if (dataReader.HasOverflow())
return NULL;
if (start == 0 && end == 0)
break;
if (start == maxAddress) {
baseAddress = end;
continue;
}
if (start == end)
continue;
if (!ranges->AddRange(baseAddress + start, end - start)) {
fprintf(stderr, "Out of memory.\n");
return NULL;
}
}
return rangesReference.Detach();
}
+3
View File
@@ -39,6 +39,9 @@ public:
CompilationUnit* CompilationUnitForDIE( CompilationUnit* CompilationUnitForDIE(
const DebugInfoEntry* entry) const; const DebugInfoEntry* entry) const;
TargetAddressRangeList* ResolveRangeList(CompilationUnit* unit,
uint64 offset) const;
status_t UnwindCallFrame(CompilationUnit* unit, status_t UnwindCallFrame(CompilationUnit* unit,
target_addr_t location, target_addr_t location,
const DwarfTargetInterface* inputInterface, const DwarfTargetInterface* inputInterface,