<commit_before>#include "MipsExecutor.h"

CMipsExecutor::CMipsExecutor(CMIPS& context, uint32 maxAddress)
: m_context(context)
, m_subTableCount(0)
#ifdef DEBUGGER_INCLUDED
, m_breakpointsDisabledOnce(false)
#endif
{
	if(maxAddress < 0x10000)
	{
		maxAddress = 0x10000;
	}
	assert((maxAddress & 0xFFFF) == 0);
	if(maxAddress == 0)
	{
		m_subTableCount = 0x10000;
	}
	else
	{
		m_subTableCount = maxAddress / 0x10000;
	}
	m_blockTable = new CBasicBlock**[m_subTableCount];
	memset(m_blockTable, 0, sizeof(CBasicBlock**) * m_subTableCount);
}

CMipsExecutor::~CMipsExecutor()
{
	for(unsigned int i = 0; i < m_subTableCount; i++)
	{
		CBasicBlock** subTable = m_blockTable[i];
		if(subTable != NULL)
		{
			delete [] subTable;
		}
	}
	delete [] m_blockTable;
}

void CMipsExecutor::Reset()
{
	ClearActiveBlocks();
}

void CMipsExecutor::ClearActiveBlocks()
{
	for(unsigned int i = 0; i < m_subTableCount; i++)
	{
		CBasicBlock** subTable = m_blockTable[i];
		if(subTable != NULL)
		{
			delete [] subTable;
			m_blockTable[i] = NULL;
		}
	}
	
	m_blocks.clear();
}

void CMipsExecutor::ClearActiveBlocksInRange(uint32 start, uint32 end)
{
	uint32 hiStart = start >> 16;
	uint32 hiEnd = end >> 16;

	std::set<CBasicBlock*> blocksToDelete;

	for(uint32 hi = hiStart; hi <= hiEnd; hi++)
	{
		CBasicBlock** table = m_blockTable[hi];
		if(table == nullptr) continue;

		for(uint32 lo = 0; lo < 0x10000; lo += 4)
		{
			uint32 tableAddress = (hi << 16) | lo;
			if(tableAddress < start) continue;
			if(tableAddress >= end) continue;
			CBasicBlock* block = table[lo / 4];
			if(block == nullptr) continue;
			table[lo / 4] = nullptr;
			blocksToDelete.insert(block);
		}
	}

	if(!blocksToDelete.empty())
	{
		m_blocks.remove_if([&] (const BasicBlockPtr& block) { return blocksToDelete.find(block.get()) != std::end(blocksToDelete); });
	}
}

int CMipsExecutor::Execute(int cycles)
{
	CBasicBlock* block(nullptr);
	while(cycles > 0)
	{
		uint32 address = m_context.m_pAddrTranslator(&m_context, m_context.m_State.nPC);
		if(!block || address != block->GetBeginAddress())
		{
			block = FindBlockStartingAt(address);
			if(block == NULL)
			{
				//We need to partition the space and compile the blocks
				PartitionFunction(address);
				block = FindBlockStartingAt(address);
				if(block == NULL)
				{
					throw std::runtime_error("Couldn't create block starting at address.");
				}
			}
			if(!block->IsCompiled())<commit_msg>Added comment about something that should be done later.<commit_after>#include "MipsExecutor.h"

CMipsExecutor::CMipsExecutor(CMIPS& context, uint32 maxAddress)
: m_context(context)
, m_subTableCount(0)
#ifdef DEBUGGER_INCLUDED
, m_breakpointsDisabledOnce(false)
#endif
{
	if(maxAddress < 0x10000)
	{
		maxAddress = 0x10000;
	}
	assert((maxAddress & 0xFFFF) == 0);
	if(maxAddress == 0)
	{
		m_subTableCount = 0x10000;
	}
	else
	{
		m_subTableCount = maxAddress / 0x10000;
	}
	m_blockTable = new CBasicBlock**[m_subTableCount];
	memset(m_blockTable, 0, sizeof(CBasicBlock**) * m_subTableCount);
}

CMipsExecutor::~CMipsExecutor()
{
	for(unsigned int i = 0; i < m_subTableCount; i++)
	{
		CBasicBlock** subTable = m_blockTable[i];
		if(subTable != NULL)
		{
			delete [] subTable;
		}
	}
	delete [] m_blockTable;
}

void CMipsExecutor::Reset()
{
	ClearActiveBlocks();
}

void CMipsExecutor::ClearActiveBlocks()
{
	for(unsigned int i = 0; i < m_subTableCount; i++)
	{
		CBasicBlock** subTable = m_blockTable[i];
		if(subTable != NULL)
		{
			delete [] subTable;
			m_blockTable[i] = NULL;
		}
	}
	
	m_blocks.clear();
}

void CMipsExecutor::ClearActiveBlocksInRange(uint32 start, uint32 end)
{
	uint32 hiStart = start >> 16;
	uint32 hiEnd = end >> 16;

	std::set<CBasicBlock*> blocksToDelete;

	for(uint32 hi = hiStart; hi <= hiEnd; hi++)
	{
		CBasicBlock** table = m_blockTable[hi];
		if(table == nullptr) continue;

		for(uint32 lo = 0; lo < 0x10000; lo += 4)
		{
			uint32 tableAddress = (hi << 16) | lo;
			if(tableAddress < start) continue;
			if(tableAddress >= end) continue;
			CBasicBlock* block = table[lo / 4];
			if(block == nullptr) continue;
			table[lo / 4] = nullptr;
			blocksToDelete.insert(block);
		}
	}

	if(!blocksToDelete.empty())
	{
		//TODO: Actually delete the blocks, because remove_if only rearranges items leaving us a new end iterator
		m_blocks.remove_if([&] (const BasicBlockPtr& block) { return blocksToDelete.find(block.get()) != std::end(blocksToDelete); });
	}
}

int CMipsExecutor::Execute(int cycles)
{
	CBasicBlock* block(nullptr);
	while(cycles > 0)
	{
		uint32 address = m_context.m_pAddrTranslator(&m_context, m_context.m_State.nPC);
		if(!block || address != block->GetBeginAddress())
		{
			block = FindBlockStartingAt(address);
			if(block == NULL)
			{
				//We need to partition the space and compile the blocks
				PartitionFunction(address);
				block = FindBlockStartingAt(address);
				if(block == NULL)
				{
					throw std::runtime_error("Couldn't create block starting at address.");
				}
			}
			if(!block->IsCompiled())
{'fraction_non_alphanumeric': 0.14119767674744643, 'fraction_numerical': 0.02643701181654316, 'mean_word_length': 4.393088552915767, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2606702', 'n_tokens_mistral': 2062, 'n_tokens_neox': 1803, 'n_words': 379}