* Virtualized SourceCode and implemented a derived class DisassembledCode, which

allows to implement StatementAtAddress() in O(log(n).
* Added SourceCode::StatementAtLine().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31174 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-06-22 01:13:57 +00:00
parent 21821017e7
commit 7367310fbe
6 changed files with 220 additions and 117 deletions
+1
View File
@@ -57,6 +57,7 @@ Application Debugger :
ThreadListView.cpp
# model
DisassembledCode.cpp
Image.cpp
ImageInfo.cpp
SourceCode.cpp
+7 -14
View File
@@ -13,8 +13,8 @@
#include "CpuStateX86.h"
#include "DebuggerInterface.h"
#include "DisassembledCode.h"
#include "FunctionDebugInfo.h"
#include "SourceCode.h"
#include "StackFrame.h"
#include "Statement.h"
@@ -150,10 +150,10 @@ status_t
ArchitectureX86::DisassembleCode(FunctionDebugInfo* function,
const void* buffer, size_t bufferSize, SourceCode*& _sourceCode)
{
SourceCode* source = new(std::nothrow) SourceCode;
DisassembledCode* source = new(std::nothrow) DisassembledCode;
if (source == NULL)
return B_NO_MEMORY;
Reference<SourceCode> sourceReference(source, true);
Reference<DisassembledCode> sourceReference(source, true);
// init disassembler
DisassemblerX86 disassembler;
@@ -163,9 +163,8 @@ ArchitectureX86::DisassembleCode(FunctionDebugInfo* function,
// add a function name line
BString functionName(function->PrettyName());
if (!source->AddLine((functionName << ':').String()))
if (!source->AddCommentLine((functionName << ':').String()))
return B_NO_MEMORY;
uint32 lineIndex = 1;
// disassemble the instructions
BString line;
@@ -174,16 +173,10 @@ ArchitectureX86::DisassembleCode(FunctionDebugInfo* function,
bool breakpointAllowed;
while (disassembler.GetNextInstruction(line, instructionAddress,
instructionSize, breakpointAllowed) == B_OK) {
Statement* statement = new(std::nothrow) ContiguousStatement(
SourceLocation(lineIndex), SourceLocation(lineIndex + 1),
TargetAddressRange(instructionAddress, instructionSize));
if (statement == NULL)
if (!source->AddInstructionLine(line, instructionAddress,
instructionSize, breakpointAllowed)) {
return B_NO_MEMORY;
if (!source->AddStatement(statement) || !source->AddLine(line.String()))
return B_NO_MEMORY;
lineIndex++;
}
}
_sourceCode = sourceReference.Detach();
@@ -0,0 +1,147 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "DisassembledCode.h"
#include <stdlib.h>
#include <string.h>
#include <new>
#include <String.h>
#include "Statement.h"
struct DisassembledCode::Line {
BString line;
ContiguousStatement* statement;
Line(const BString& line, ContiguousStatement* statement)
:
line(line),
statement(statement)
{
}
};
DisassembledCode::DisassembledCode()
:
fLines(20, true)
{
}
DisassembledCode::~DisassembledCode()
{
for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++)
statement->RemoveReference();
}
int32
DisassembledCode::CountLines() const
{
return fLines.CountItems();
}
const char*
DisassembledCode::LineAt(int32 index) const
{
Line* line = fLines.ItemAt(index);
return line != NULL ? line->line.String() : NULL;
}
int32
DisassembledCode::CountStatements() const
{
return fStatements.CountItems();
}
Statement*
DisassembledCode::StatementAt(int32 index) const
{
return fStatements.ItemAt(index);
}
Statement*
DisassembledCode::StatementAtLine(int32 index) const
{
Line* line = fLines.ItemAt(index);
return line != NULL ? line->statement : NULL;
}
Statement*
DisassembledCode::StatementAtAddress(target_addr_t address) const
{
return fStatements.BinarySearchByKey(address, &_CompareAddressStatement);
}
bool
DisassembledCode::AddCommentLine(const BString& line)
{
return _AddLine(line, NULL);
}
bool
DisassembledCode::AddInstructionLine(const BString& line, target_addr_t address,
target_size_t size, bool breakpointAllowed)
{
int32 lineIndex = fLines.CountItems();
ContiguousStatement* statement = new(std::nothrow) ContiguousStatement(
SourceLocation(lineIndex), SourceLocation(lineIndex + 1),
TargetAddressRange(address, size));
// TODO: breakpointAllowed!
if (statement == NULL)
return false;
if (!fStatements.AddItem(statement)) {
delete statement;
return false;
}
if (!_AddLine(line, statement))
return false;
return true;
}
bool
DisassembledCode::_AddLine(const BString& _line, ContiguousStatement* statement)
{
Line* line = new(std::nothrow) Line(_line, statement);
if (line == NULL)
return false;
if (!fLines.AddItem(line)) {
delete line;
return false;
}
return true;
}
/*static*/ int
DisassembledCode::_CompareAddressStatement(const target_addr_t* address,
const ContiguousStatement* statement)
{
const TargetAddressRange& range = statement->AddressRange();
if (*address < range.Start())
return -1;
return *address < range.End() ? 0 : 1;
}
@@ -0,0 +1,57 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef DISASSEMBLED_CODE_H
#define DISASSEMBLED_CODE_H
#include <ObjectList.h>
#include "SourceCode.h"
class BString;
class ContiguousStatement;
class DisassembledCode : public SourceCode {
public:
DisassembledCode();
~DisassembledCode();
virtual int32 CountLines() const;
virtual const char* LineAt(int32 index) const;
virtual int32 CountStatements() const;
virtual Statement* StatementAt(int32 index) const;
virtual Statement* StatementAtLine(int32 index) const;
virtual Statement* StatementAtAddress(target_addr_t address) const;
public:
bool AddCommentLine(const BString& line);
bool AddInstructionLine(const BString& line,
target_addr_t address, target_size_t size,
bool breakpointAllowed);
// instructions must be added in
// ascending address order
private:
struct Line;
typedef BObjectList<Line> LineList;
typedef BObjectList<ContiguousStatement> StatementList;
private:
bool _AddLine(const BString& line,
ContiguousStatement* statement);
static int _CompareAddressStatement(
const target_addr_t* address,
const ContiguousStatement* statement);
private:
LineList fLines;
StatementList fStatements;
};
#endif // DISASSEMBLED_CODE_H
-82
View File
@@ -5,89 +5,7 @@
#include "SourceCode.h"
#include <stdlib.h>
#include <string.h>
#include "Statement.h"
SourceCode::SourceCode()
{
}
SourceCode::~SourceCode()
{
for (int32 i = 0; char* line = fLines.ItemAt(i); i++)
free(line);
for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++)
statement->RemoveReference();
}
int32
SourceCode::CountLines() const
{
return fLines.CountItems();
}
const char*
SourceCode::LineAt(int32 index) const
{
return fLines.ItemAt(index);
}
int32
SourceCode::CountStatements() const
{
return fStatements.CountItems();
}
Statement*
SourceCode::StatementAt(int32 index) const
{
return fStatements.ItemAt(index);
}
Statement*
SourceCode::StatementAtAddress(target_addr_t address) const
{
// TODO: Optimize!
for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++) {
if (statement->ContainsAddress(address))
return statement;
}
return NULL;
}
bool
SourceCode::AddLine(const char* _line)
{
char* line = strdup(_line);
if (line == NULL)
return false;
if (!fLines.AddItem(line)) {
free(line);
return false;
}
return true;
}
bool
SourceCode::AddStatement(Statement* statement)
{
if (!fStatements.AddItem(statement)) {
statement->RemoveReference();
return false;
}
return true;
}
+8 -21
View File
@@ -5,7 +5,6 @@
#ifndef SOURCE_CODE_H
#define SOURCE_CODE_H
#include <ObjectList.h>
#include <Referenceable.h>
#include "ArchitectureTypes.h"
@@ -16,28 +15,16 @@ class Statement;
class SourceCode : public Referenceable {
public:
SourceCode();
~SourceCode();
virtual ~SourceCode();
int32 CountLines() const;
const char* LineAt(int32 index) const;
virtual int32 CountLines() const = 0;
virtual const char* LineAt(int32 index) const = 0;
int32 CountStatements() const;
Statement* StatementAt(int32 index) const;
Statement* StatementAtAddress(target_addr_t address) const;
bool AddLine(const char* line);
// clones
bool AddStatement(Statement* statement);
// takes over reference
private:
typedef BObjectList<char> LineList;
typedef BObjectList<Statement> StatementList;
private:
LineList fLines;
StatementList fStatements;
virtual int32 CountStatements() const = 0;
virtual Statement* StatementAt(int32 index) const = 0;
virtual Statement* StatementAtLine(int32 index) const = 0;
virtual Statement* StatementAtAddress(target_addr_t address)
const = 0;
};