Add a limit for the number of instructions in a function (#843)
This commit is contained in:
parent
d925de2d0e
commit
e5858e2c7d
1 changed files with 14 additions and 0 deletions
|
@ -10,6 +10,11 @@ namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
static class Decoder
|
static class Decoder
|
||||||
{
|
{
|
||||||
|
// We define a limit on the number of instructions that a function may have,
|
||||||
|
// this prevents functions being potentially too large, which would
|
||||||
|
// take too long to compile and use too much memory.
|
||||||
|
private const int MaxInstsPerFunction = 5000;
|
||||||
|
|
||||||
private delegate object MakeOp(InstDescriptor inst, ulong address, int opCode);
|
private delegate object MakeOp(InstDescriptor inst, ulong address, int opCode);
|
||||||
|
|
||||||
private static ConcurrentDictionary<Type, MakeOp> _opActivators;
|
private static ConcurrentDictionary<Type, MakeOp> _opActivators;
|
||||||
|
@ -36,10 +41,17 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
|
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
|
||||||
|
|
||||||
|
int opsCount = 0;
|
||||||
|
|
||||||
Block GetBlock(ulong blkAddress)
|
Block GetBlock(ulong blkAddress)
|
||||||
{
|
{
|
||||||
if (!visited.TryGetValue(blkAddress, out Block block))
|
if (!visited.TryGetValue(blkAddress, out Block block))
|
||||||
{
|
{
|
||||||
|
if (opsCount > MaxInstsPerFunction)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
block = new Block(blkAddress);
|
block = new Block(blkAddress);
|
||||||
|
|
||||||
workQueue.Enqueue(block);
|
workQueue.Enqueue(block);
|
||||||
|
@ -92,6 +104,8 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
FillBlock(memory, mode, currBlock, limitAddress);
|
FillBlock(memory, mode, currBlock, limitAddress);
|
||||||
|
|
||||||
|
opsCount += currBlock.OpCodes.Count;
|
||||||
|
|
||||||
if (currBlock.OpCodes.Count != 0)
|
if (currBlock.OpCodes.Count != 0)
|
||||||
{
|
{
|
||||||
// Set child blocks. "Branch" is the block the branch instruction
|
// Set child blocks. "Branch" is the block the branch instruction
|
||||||
|
|
Reference in a new issue