Skip to content

Commit 25213a8

Browse files
committed
Represent operand lists and label maps more efficiently within IL instructions
Rather than using chains of `UNDEF` instructions, the contents of these lists are in a vector alongside the instructions. The instruction itself stores the entry count and offset into this second vector at which the associated items can be found. This improves analysis performance by around 2% and decreases memory usage by around 5%.
1 parent 8f6762f commit 25213a8

7 files changed

Lines changed: 107 additions & 138 deletions

binaryninjacore.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6445,6 +6445,8 @@ extern "C"
64456445
BINARYNINJACOREAPI uint64_t* BNLowLevelILGetOperandList(
64466446
BNLowLevelILFunction* func, size_t expr, size_t operand, size_t* count);
64476447
BINARYNINJACOREAPI void BNLowLevelILFreeOperandList(uint64_t* operands);
6448+
BINARYNINJACOREAPI const uint64_t* BNLowLevelILGetOperandPointer(
6449+
BNLowLevelILFunction* func, size_t offset);
64486450

64496451
BINARYNINJACOREAPI size_t BNCacheLowLevelILPossibleValueSet(BNLowLevelILFunction* func, BNPossibleValueSet* pvs);
64506452
BINARYNINJACOREAPI BNPossibleValueSet BNGetCachedLowLevelILPossibleValueSet(BNLowLevelILFunction* func, size_t idx);
@@ -6602,6 +6604,8 @@ extern "C"
66026604
BINARYNINJACOREAPI uint64_t* BNMediumLevelILGetOperandList(
66036605
BNMediumLevelILFunction* func, size_t expr, size_t operand, size_t* count);
66046606
BINARYNINJACOREAPI void BNMediumLevelILFreeOperandList(uint64_t* operands);
6607+
BINARYNINJACOREAPI const uint64_t* BNMediumLevelILGetOperandPointer(
6608+
BNMediumLevelILFunction* func, size_t offset);
66056609

66066610
BINARYNINJACOREAPI size_t BNCacheMediumLevelILPossibleValueSet(BNMediumLevelILFunction* func, BNPossibleValueSet* pvs);
66076611
BINARYNINJACOREAPI BNPossibleValueSet BNGetCachedMediumLevelILPossibleValueSet(BNMediumLevelILFunction* func, size_t idx);
@@ -6763,6 +6767,8 @@ extern "C"
67636767
BINARYNINJACOREAPI uint64_t* BNHighLevelILGetOperandList(
67646768
BNHighLevelILFunction* func, size_t expr, size_t operand, size_t* count);
67656769
BINARYNINJACOREAPI void BNHighLevelILFreeOperandList(uint64_t* operands);
6770+
BINARYNINJACOREAPI const uint64_t* BNHighLevelILGetOperandPointer(
6771+
BNHighLevelILFunction* func, size_t offset);
67666772

67676773
BINARYNINJACOREAPI size_t BNCacheHighLevelILPossibleValueSet(BNHighLevelILFunction* func, BNPossibleValueSet* pvs);
67686774
BINARYNINJACOREAPI BNPossibleValueSet BNGetCachedHighLevelILPossibleValueSet(BNHighLevelILFunction* func, size_t idx);

highlevelilinstruction.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -288,31 +288,26 @@ bool HighLevelILIntegerList::ListIterator::operator<(const ListIterator& a) cons
288288
HighLevelILIntegerList::ListIterator& HighLevelILIntegerList::ListIterator::operator++()
289289
{
290290
count--;
291-
if (count == 0)
292-
return *this;
293-
294-
operand++;
295-
if (operand >= 4)
296-
{
297-
operand = 0;
298-
instr = function->GetRawExpr((size_t)instr.operands[4]);
299-
}
291+
cur++;
300292
return *this;
301293
}
302294

303295

304296
uint64_t HighLevelILIntegerList::ListIterator::operator*()
305297
{
306-
return instr.operands[operand];
298+
return *cur;
307299
}
308300

309301

310302
HighLevelILIntegerList::HighLevelILIntegerList(
311-
HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count)
303+
HighLevelILFunction* func, size_t offset, size_t count)
312304
{
313305
m_start.function = func;
314-
m_start.instr = instr;
315-
m_start.operand = 0;
306+
#ifdef BINARYNINJACORE_LIBRARY
307+
m_start.cur = func->GetOperandPointer(offset);
308+
#else
309+
m_start.cur = BNHighLevelILGetOperandPointer(func->GetObject(), offset);
310+
#endif
316311
m_start.count = count;
317312
}
318313

@@ -327,7 +322,7 @@ HighLevelILIntegerList::const_iterator HighLevelILIntegerList::end() const
327322
{
328323
const_iterator result;
329324
result.function = m_start.function;
330-
result.operand = 0;
325+
result.cur = m_start.cur + m_start.count;
331326
result.count = 0;
332327
return result;
333328
}
@@ -343,10 +338,7 @@ uint64_t HighLevelILIntegerList::operator[](size_t i) const
343338
{
344339
if (i >= size())
345340
throw HighLevelILInstructionAccessException();
346-
auto iter = begin();
347-
for (size_t j = 0; j < i; j++)
348-
++iter;
349-
return *iter;
341+
return m_start.cur[i];
350342
}
351343

352344

@@ -367,8 +359,8 @@ size_t HighLevelILIndexList::ListIterator::operator*()
367359

368360

369361
HighLevelILIndexList::HighLevelILIndexList(
370-
HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count) :
371-
m_list(func, instr, count)
362+
HighLevelILFunction* func, size_t offset, size_t count) :
363+
m_list(func, offset, count)
372364
{}
373365

374366

@@ -427,9 +419,9 @@ const HighLevelILInstruction HighLevelILInstructionList::ListIterator::operator*
427419
}
428420

429421

430-
HighLevelILInstructionList::HighLevelILInstructionList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr,
422+
HighLevelILInstructionList::HighLevelILInstructionList(HighLevelILFunction* func, size_t offset,
431423
size_t count, bool asFullAst, size_t instructionIndex) :
432-
m_list(func, instr, count),
424+
m_list(func, offset, count),
433425
m_ast(asFullAst), m_instructionIndex(instructionIndex)
434426
{}
435427

@@ -492,8 +484,8 @@ const SSAVariable HighLevelILSSAVariableList::ListIterator::operator*()
492484

493485

494486
HighLevelILSSAVariableList::HighLevelILSSAVariableList(
495-
HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count) :
496-
m_list(func, instr, count & (~1))
487+
HighLevelILFunction* func, size_t offset, size_t count) :
488+
m_list(func, offset, count & (~1))
497489
{}
498490

499491

@@ -800,19 +792,19 @@ SSAVariable HighLevelILInstructionBase::GetRawOperandAsSSAVariable(size_t operan
800792
HighLevelILInstructionList HighLevelILInstructionBase::GetRawOperandAsExprList(size_t operand) const
801793
{
802794
return HighLevelILInstructionList(
803-
function, function->GetRawExpr(operands[operand + 1]), operands[operand], ast, instructionIndex);
795+
function, (size_t)operands[operand + 1], (size_t)operands[operand], ast, instructionIndex);
804796
}
805797

806798

807799
HighLevelILSSAVariableList HighLevelILInstructionBase::GetRawOperandAsSSAVariableList(size_t operand) const
808800
{
809-
return HighLevelILSSAVariableList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]);
801+
return HighLevelILSSAVariableList(function, (size_t)operands[operand + 1], (size_t)operands[operand]);
810802
}
811803

812804

813805
HighLevelILIndexList HighLevelILInstructionBase::GetRawOperandAsIndexList(size_t operand) const
814806
{
815-
return HighLevelILIndexList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]);
807+
return HighLevelILIndexList(function, (size_t)operands[operand + 1], (size_t)operands[operand]);
816808
}
817809

818810

highlevelilinstruction.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ namespace BinaryNinja
196196
#else
197197
Ref<HighLevelILFunction> function;
198198
#endif
199-
BNHighLevelILInstruction instr;
200-
size_t operand, count;
199+
const uint64_t* cur;
200+
size_t count;
201201

202202
bool operator==(const ListIterator& a) const;
203203
bool operator!=(const ListIterator& a) const;
@@ -212,7 +212,7 @@ namespace BinaryNinja
212212
public:
213213
typedef ListIterator const_iterator;
214214

215-
HighLevelILIntegerList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count);
215+
HighLevelILIntegerList(HighLevelILFunction* func, size_t offset, size_t count);
216216

217217
const_iterator begin() const;
218218
const_iterator end() const;
@@ -252,7 +252,7 @@ namespace BinaryNinja
252252
public:
253253
typedef ListIterator const_iterator;
254254

255-
HighLevelILIndexList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count);
255+
HighLevelILIndexList(HighLevelILFunction* func, size_t offset, size_t count);
256256

257257
const_iterator begin() const;
258258
const_iterator end() const;
@@ -296,7 +296,7 @@ namespace BinaryNinja
296296
public:
297297
typedef ListIterator const_iterator;
298298

299-
HighLevelILInstructionList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count,
299+
HighLevelILInstructionList(HighLevelILFunction* func, size_t offset, size_t count,
300300
bool asFullAst, size_t instructionIndex);
301301

302302
const_iterator begin() const;
@@ -338,7 +338,7 @@ namespace BinaryNinja
338338
public:
339339
typedef ListIterator const_iterator;
340340

341-
HighLevelILSSAVariableList(HighLevelILFunction* func, const BNHighLevelILInstruction& instr, size_t count);
341+
HighLevelILSSAVariableList(HighLevelILFunction* func, size_t offset, size_t count);
342342

343343
const_iterator begin() const;
344344
const_iterator end() const;

0 commit comments

Comments
 (0)