By making this union .small_insn a uintptr_t, so it's the same size as
.large_insn, we can avoid some memory allocation without taking any more
memory in Instruction itself. (PPC instructions are always 32-bit, so
there it's left as unsigned int.)
With this optimization on x86_64, the number of large_insn allocations
required is greatly reduced. Many instructions are more than 4 bytes,
but it's less common to have more than 8 bytes.
---
instructionAPI/h/Instruction.h | 4 ++++
instructionAPI/src/Instruction.C | 18 +++++++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/instructionAPI/h/Instruction.h b/instructionAPI/h/Instruction.h
index befa5f2399e8..be52a5b1467d 100644
--- a/instructionAPI/h/Instruction.h
+++ b/instructionAPI/h/Instruction.h
@@ -79,7 +79,11 @@ namespace Dyninst
INSTRUCTION_EXPORT static void version(int& major, int& minor, int& maintenance);
union raw_insn_T
{
+#if defined(__powerpc__) || defined(__powerpc64__)
unsigned int small_insn;
+#else
+ uintptr_t small_insn;
+#endif
unsigned char* large_insn;
};
public:
diff --git a/instructionAPI/src/Instruction.C b/instructionAPI/src/Instruction.C
index 728fd1b6b6a7..a8fa4bd3789d 100644
--- a/instructionAPI/src/Instruction.C
+++ b/instructionAPI/src/Instruction.C
@@ -95,7 +95,7 @@ namespace Dyninst
{
m_size = size;
m_RawInsn.small_insn = 0;
- if(size <= sizeof(unsigned int))
+ if(size <= sizeof(raw_insn_T::small_insn))
{
memcpy(&m_RawInsn, raw, size);
}
@@ -135,7 +135,7 @@ namespace Dyninst
INSTRUCTION_EXPORT Instruction::~Instruction()
{
- if(m_size > sizeof(unsigned int))
+ if(m_size > sizeof(raw_insn_T::small_insn))
{
delete[] m_RawInsn.large_insn;
}
@@ -154,13 +154,13 @@ namespace Dyninst
m_Operands = o.m_Operands;
//m_Operands.reserve(o.m_Operands.size());
//std::copy(o.m_Operands.begin(), o.m_Operands.end(), std::back_inserter(m_Operands));
- if(m_size > sizeof(unsigned int))
+ if(m_size > sizeof(raw_insn_T::small_insn))
{
delete[] m_RawInsn.large_insn;
}
m_size = o.m_size;
- if(o.m_size > sizeof(unsigned int))
+ if(o.m_size > sizeof(raw_insn_T::small_insn))
{
m_RawInsn.large_insn = new unsigned char[o.m_size];
memcpy(m_RawInsn.large_insn, o.m_RawInsn.large_insn, m_size);
@@ -186,13 +186,13 @@ namespace Dyninst
m_Operands = rhs.m_Operands;
//m_Operands.reserve(rhs.m_Operands.size());
//std::copy(rhs.m_Operands.begin(), rhs.m_Operands.end(), std::back_inserter(m_Operands));
- if(m_size > sizeof(unsigned int))
+ if(m_size > sizeof(raw_insn_T::small_insn))
{
delete[] m_RawInsn.large_insn;
}
m_size = rhs.m_size;
- if(rhs.m_size > sizeof(unsigned int))
+ if(rhs.m_size > sizeof(raw_insn_T::small_insn))
{
m_RawInsn.large_insn = new unsigned char[rhs.m_size];
memcpy(m_RawInsn.large_insn, rhs.m_RawInsn.large_insn, m_size);
@@ -248,7 +248,7 @@ namespace Dyninst
INSTRUCTION_EXPORT const void* Instruction::ptr() const
{
- if(m_size > sizeof(unsigned int))
+ if(m_size > sizeof(raw_insn_T::small_insn))
{
return m_RawInsn.large_insn;
}
@@ -259,8 +259,8 @@ namespace Dyninst
}
INSTRUCTION_EXPORT unsigned char Instruction::rawByte(unsigned int index) const
{
- if(index > m_size) return 0;
- if(m_size > sizeof(unsigned int))
+ if(index >= m_size) return 0;
+ if(m_size > sizeof(raw_insn_T::small_insn))
{
return m_RawInsn.large_insn[index];
}
--
1.8.5.3
|