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 "Statement.h"
#include "StringUtils.h"
#include "TargetAddressRangeList.h"
#include "TeamMemory.h"
#include "UnsupportedLanguage.h"
@@ -230,9 +231,8 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits());
continue;
// get the address ranges
TargetAddressRangeList* rangeList
= subprogramEntry->AddressRanges();
Reference<TargetAddressRangeList> rangeListReference(rangeList);
TargetAddressRangeList* rangeList = fFile->ResolveRangeList(unit,
subprogramEntry->AddressRangesOffset());
if (rangeList == NULL) {
target_addr_t lowPC = subprogramEntry->LowPC();
target_addr_t highPC = subprogramEntry->HighPC();
@@ -244,8 +244,9 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits());
if (rangeList == NULL)
return B_NO_MEMORY;
// TODO: Clean up already added functions!
rangeListReference.SetTo(rangeList, true);
}
Reference<TargetAddressRangeList> rangeListReference(rangeList,
true);
// get the source location
const char* directoryPath = NULL;
+2 -10
View File
@@ -6,7 +6,6 @@
#define ATTRIBUTE_VALUE_H
#include "AttributeClasses.h"
#include "TargetAddressRangeList.h"
#include "Types.h"
@@ -22,7 +21,6 @@ struct AttributeValue {
} block;
uint64 constant;
bool flag;
TargetAddressRangeList* rangeList;
off_t pointer;
DebugInfoEntry* reference;
const char* string;
@@ -94,13 +92,11 @@ struct AttributeValue {
this->pointer = value;
}
void SetToRangeList(TargetAddressRangeList* rangeList)
void SetToRangeListPointer(off_t value)
{
Unset();
attributeClass = ATTRIBUTE_CLASS_RANGELISTPTR;
this->rangeList = rangeList;
if (rangeList != NULL)
rangeList->AddReference();
this->pointer = value;
}
void SetToReference(DebugInfoEntry* entry)
@@ -119,10 +115,6 @@ struct AttributeValue {
void Unset()
{
if (attributeClass == ATTRIBUTE_CLASS_RANGELISTPTR
&& rangeList != NULL) {
rangeList->RemoveReference();
}
attributeClass = ATTRIBUTE_CLASS_UNKNOWN;
}
@@ -3,10 +3,14 @@
* Distributed under the terms of the MIT License.
*/
#include "CompilationUnit.h"
#include <new>
#include "DebugInfoEntries.h"
#include "TargetAddressRangeList.h"
struct CompilationUnit::File {
BString fileName;
@@ -32,6 +36,7 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset,
fAbbreviationOffset(abbreviationOffset),
fAbbreviationTable(NULL),
fUnitEntry(NULL),
fAddressRanges(NULL),
fDirectories(10, true),
fFiles(10, true),
fLineNumberProgram(addressSize),
@@ -43,6 +48,7 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset,
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
CompilationUnit::CountEntries() const
{
+10
View File
@@ -5,6 +5,7 @@
#ifndef COMPILATION_UNIT_H
#define COMPILATION_UNIT_H
#include <String.h>
#include <ObjectList.h>
@@ -17,6 +18,7 @@
class AbbreviationTable;
class DebugInfoEntry;
class DIECompileUnitBase;
class TargetAddressRangeList;
class CompilationUnit {
@@ -51,6 +53,13 @@ public:
DIECompileUnitBase* UnitEntry() const { return fUnitEntry; }
void SetUnitEntry(DIECompileUnitBase* entry);
TargetAddressRangeList* AddressRanges() const
{ return fAddressRanges; }
void SetAddressRanges(
TargetAddressRangeList* ranges);
target_addr_t AddressRangeBase() const;
LineNumberProgram& GetLineNumberProgram()
{ return fLineNumberProgram; }
@@ -82,6 +91,7 @@ private:
off_t fAbbreviationOffset;
AbbreviationTable* fAbbreviationTable;
DIECompileUnitBase* fUnitEntry;
TargetAddressRangeList* fAddressRanges;
Array<DebugInfoEntry*> fEntries;
Array<off_t> fEntryOffsets;
DirectoryList fDirectories;
+6 -35
View File
@@ -21,10 +21,9 @@ DIECompileUnitBase::DIECompileUnitBase()
fCompilationDir(NULL),
fLowPC(0),
fHighPC(0),
fStatementListOffset(0),
fMacroInfoOffset(0),
// TODO: Is 0 a good invalid offset?
fAddressRanges(NULL),
fStatementListOffset(-1),
fMacroInfoOffset(-1),
fAddressRangesOffset(-1),
fBaseTypesUnit(NULL),
fLanguage(0),
fIdentifierCase(0),
@@ -35,8 +34,6 @@ 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
DIECompileUnitBase::AddChild(DebugInfoEntry* child)
{
@@ -197,14 +184,7 @@ status_t
DIECompileUnitBase::AddAttribute_ranges(uint16 attributeName,
const AttributeValue& value)
{
if (fAddressRanges != NULL)
fAddressRanges->RemoveReference();
fAddressRanges = value.rangeList;
if (fAddressRanges != NULL)
fAddressRanges->AddReference();
fAddressRangesOffset = value.pointer;
return B_OK;
}
@@ -1547,7 +1527,7 @@ DIESubprogram::DIESubprogram()
:
fLowPC(0),
fHighPC(0),
fAddressRanges(NULL),
fAddressRangesOffset(-1),
fSpecification(NULL),
fAbstractOrigin(NULL),
fReturnType(NULL),
@@ -1560,8 +1540,6 @@ DIESubprogram::DIESubprogram()
DIESubprogram::~DIESubprogram()
{
if (fAddressRanges != NULL)
fAddressRanges->RemoveReference();
}
@@ -1609,14 +1587,7 @@ status_t
DIESubprogram::AddAttribute_ranges(uint16 attributeName,
const AttributeValue& value)
{
if (fAddressRanges != NULL)
fAddressRanges->RemoveReference();
fAddressRanges = value.rangeList;
if (fAddressRanges != NULL)
fAddressRanges->AddReference();
fAddressRangesOffset = value.pointer;
return B_OK;
}
+6 -7
View File
@@ -151,12 +151,11 @@ public:
const DebugInfoEntryList& Types() const { return fTypes; }
const DebugInfoEntryList& OtherChildren() const
{ return fOtherChildren; }
TargetAddressRangeList* AddressRanges() const
{ return fAddressRanges; }
off_t AddressRangesOffset() const
{ return fAddressRangesOffset; }
target_addr_t LowPC() const { return fLowPC; }
target_addr_t HighPC() const { return fHighPC; }
target_addr_t AddressRangeBase() const;
off_t StatementListOffset() const
{ return fStatementListOffset; }
@@ -202,7 +201,7 @@ protected:
target_addr_t fHighPC;
off_t fStatementListOffset;
off_t fMacroInfoOffset;
TargetAddressRangeList* fAddressRanges;
off_t fAddressRangesOffset;
DIECompileUnitBase* fBaseTypesUnit;
DebugInfoEntryList fTypes;
DebugInfoEntryList fOtherChildren;
@@ -1025,8 +1024,8 @@ public:
virtual DebugInfoEntry* Specification() const;
virtual DebugInfoEntry* AbstractOrigin() const;
TargetAddressRangeList* AddressRanges() const
{ return fAddressRanges; }
off_t AddressRangesOffset() const
{ return fAddressRangesOffset; }
target_addr_t LowPC() const { return fLowPC; }
target_addr_t HighPC() const { return fHighPC; }
@@ -1057,7 +1056,7 @@ public:
protected:
target_addr_t fLowPC;
target_addr_t fHighPC;
TargetAddressRangeList* fAddressRanges;
off_t fAddressRangesOffset;
DIESubprogram* fSpecification;
DIESubprogram* fAbstractOrigin;
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
DwarfFile::UnwindCallFrame(CompilationUnit* unit, target_addr_t location,
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
const char* compilationDir = unit->UnitEntry()->CompilationDir();
if (!unit->AddDirectory(compilationDir != NULL ? compilationDir : "."))
@@ -743,15 +796,8 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader,
attributeValue.SetToMacroPointer(value);
break;
case ATTRIBUTE_CLASS_RANGELISTPTR:
{
if (entry != NULL) {
TargetAddressRangeList* rangeList
= _ResolveRangeList(value);
Reference<TargetAddressRangeList> reference(rangeList);
attributeValue.SetToRangeList(rangeList);
}
attributeValue.SetToRangeListPointer(value);
break;
}
case ATTRIBUTE_CLASS_REFERENCE:
if (entry != NULL) {
attributeValue.SetToReference(_ResolveReference(value,
@@ -1334,51 +1380,3 @@ DwarfFile::_ResolveReference(uint64 offset, bool localReference) const
// TODO: Implement program-global references!
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(
const DebugInfoEntry* entry) const;
TargetAddressRangeList* ResolveRangeList(CompilationUnit* unit,
uint64 offset) const;
status_t UnwindCallFrame(CompilationUnit* unit,
target_addr_t location,
const DwarfTargetInterface* inputInterface,