Skip to content

Commit

Permalink
Merge pull request #174 from unknownbrackets/pool-stats
Browse files Browse the repository at this point in the history
Add pool info to stats output
  • Loading branch information
Kingcom committed Jul 12, 2020
2 parents b8eb757 + d086452 commit e7ebd4f
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 27 deletions.
23 changes: 14 additions & 9 deletions Archs/ARM/Pool.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "stdafx.h"
#include <unordered_map>
#include "Pool.h"
#include "Arm.h"
#include "Core/Allocations.h"
#include "Core/Common.h"
#include "Core/FileManager.h"

Expand Down Expand Up @@ -32,16 +34,20 @@ void ArmStateCommand::writeSymData(SymbolData& symData) const

ArmPoolCommand::ArmPoolCommand()
{

position = -1;
}

bool ArmPoolCommand::Validate()
{
int64_t fileID = g_fileManager->getOpenFileID();
if (position != -1)
Allocations::forgetPool(fileID, position, values.size() * 4);
position = g_fileManager->getVirtualAddress();

size_t oldSize = values.size();
values.clear();

std::unordered_map<int32_t, size_t> usedValues;
for (ArmPoolEntry& entry: Arm.getPoolContent())
{
size_t index = values.size();
Expand All @@ -50,25 +56,24 @@ bool ArmPoolCommand::Validate()
// we aren't in an unordinarily long validation loop
if (Global.validationPasses < 10)
{
for (size_t i = 0; i < values.size(); i++)
{
if (values[i] == entry.value)
{
index = i;
break;
}
}
auto it = usedValues.find(entry.value);
if (it != usedValues.end())
index = it->second;
}

if (index == values.size())
{
usedValues[entry.value] = index;
values.push_back(entry.value);
}

entry.command->applyFileInfo();
entry.command->setPoolAddress(position+index*4);
}

Arm.clearPoolContent();
g_fileManager->advanceMemory(values.size()*4);
Allocations::setPool(fileID, position, values.size() * 4);

return oldSize != values.size();
}
Expand Down
7 changes: 3 additions & 4 deletions Commands/CDirectiveArea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,11 @@ bool CDirectiveArea::Validate()
if (areaSize != oldAreaSize || contentSize != oldContentSize)
result = true;

std::shared_ptr<AssemblerFile> file = g_fileManager->getOpenFile();
static_assert(sizeof(int64_t) >= sizeof(intptr_t), "Assumes pointers are <= 64 bit");
int64_t fileID = g_fileManager->getOpenFileID();
if ((oldPosition != position || areaSize == 0) && oldAreaSize != 0)
Allocations::forgetArea((int64_t)(intptr_t)file.get(), oldPosition, oldAreaSize);
Allocations::forgetArea(fileID, oldPosition, oldAreaSize);
if (areaSize != 0)
Allocations::setArea((int64_t)(intptr_t)file.get(), position, areaSize, contentSize, fillExpression.isLoaded());
Allocations::setArea(fileID, position, areaSize, contentSize, fillExpression.isLoaded());

return result;
}
Expand Down
38 changes: 35 additions & 3 deletions Core/Allocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Core/Common.h"

std::map<Allocations::Key, Allocations::Usage> Allocations::allocations;
std::map<Allocations::Key, int64_t> Allocations::pools;

void Allocations::clear()
{
Expand All @@ -19,9 +20,22 @@ void Allocations::forgetArea(int64_t fileID, int64_t position, int64_t space)
{
Key key{ fileID, position };
auto it = allocations.find(key);
if (it != allocations.end() && it->second.space == space) {
if (it != allocations.end() && it->second.space == space)
allocations.erase(it);
}
}

void Allocations::setPool(int64_t fileID, int64_t position, int64_t size)
{
Key key{ fileID, position };
pools[key] = size;
}

void Allocations::forgetPool(int64_t fileID, int64_t position, int64_t size)
{
Key key{ fileID, position };
auto it = pools.find(key);
if (it != pools.end() && it->second == size)
pools.erase(it);
}

void Allocations::validateOverlap()
Expand Down Expand Up @@ -59,7 +73,13 @@ void Allocations::validateOverlap()
AllocationStats Allocations::collectStats()
{
AllocationStats stats{};
collectAreaStats(stats);
collectPoolStats(stats);
return stats;
}

void Allocations::collectAreaStats(AllocationStats &stats)
{
// Need to work out overlaps.
Key lastKey{ -1, -1 };
int64_t lastEndPosition = -1;
Expand Down Expand Up @@ -114,6 +134,18 @@ AllocationStats Allocations::collectStats()

if (lastKey.position != -1)
applyUsage(lastKey.position, lastUsage);
}

return stats;
void Allocations::collectPoolStats(AllocationStats &stats)
{
for (auto it : pools)
{
if (it.second > stats.largestPoolSize)
{
stats.largestPoolPosition = it.first.position;
stats.largestPoolSize = it.second;
}

stats.totalPoolSize += it.second;
}
}
24 changes: 20 additions & 4 deletions Core/Allocations.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

#include <map>

struct AllocationStats {
struct AllocationStats
{
int64_t largestPosition;
int64_t largestSize;
int64_t largestUsage;
Expand All @@ -13,19 +14,28 @@ struct AllocationStats {

int64_t totalSize;
int64_t totalUsage;

int64_t largestPoolPosition;
int64_t largestPoolSize;
int64_t totalPoolSize;
};

class Allocations {
class Allocations
{
public:
static void clear();
static void setArea(int64_t fileID, int64_t position, int64_t space, int64_t usage, bool usesFill);
static void forgetArea(int64_t fileID, int64_t position, int64_t space);

static void setPool(int64_t fileID, int64_t position, int64_t size);
static void forgetPool(int64_t fileID, int64_t position, int64_t size);

static void validateOverlap();
static AllocationStats collectStats();

private:
struct Key {
struct Key
{
int64_t fileID;
int64_t position;

Expand All @@ -34,10 +44,16 @@ class Allocations {
return std::tie(fileID, position) < std::tie(other.fileID, other.position);
}
};
struct Usage {
struct Usage
{
int64_t space;
int64_t usage;
bool usesFill;
};

static void collectAreaStats(AllocationStats &stats);
static void collectPoolStats(AllocationStats &stats);

static std::map<Key, Usage> allocations;
static std::map<Key, int64_t> pools;
};
15 changes: 11 additions & 4 deletions Core/Assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,18 @@ bool encodeAssembly(std::unique_ptr<CAssemblerCommand> content, SymbolData& symD
return true;
}

static void printStats(const AllocationStats &stats) {
Logger::printLine(L"Total: %lld / %lld", stats.totalUsage, stats.totalSize);
Logger::printLine(L"Largest: 0x%08llX, %lld / %lld", stats.largestPosition, stats.largestUsage, stats.largestSize);
static void printStats(const AllocationStats &stats)
{
Logger::printLine(L"Total areas: %lld / %lld", stats.totalUsage, stats.totalSize);
Logger::printLine(L"Largest area: 0x%08llX, %lld / %lld", stats.largestPosition, stats.largestUsage, stats.largestSize);
int64_t startFreePosition = stats.largestFreePosition + stats.largestFreeUsage;
Logger::printLine(L"Most free: 0x%08llX, %lld / %lld (free at 0x%08llX)", stats.largestFreePosition, stats.largestFreeUsage, stats.largestFreeSize, startFreePosition);
Logger::printLine(L"Most free area: 0x%08llX, %lld / %lld (free at 0x%08llX)", stats.largestFreePosition, stats.largestFreeUsage, stats.largestFreeSize, startFreePosition);

if (stats.totalPoolSize != 0)
{
Logger::printLine(L"Total pool size: %lld", stats.totalPoolSize);
Logger::printLine(L"Largest pool: 0x%08llX, %lld", stats.largestPoolPosition, stats.largestPoolSize);
}
}

bool runArmips(ArmipsArguments& settings)
Expand Down
8 changes: 8 additions & 0 deletions Core/FileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,11 @@ bool FileManager::advanceMemory(size_t bytes)
int64_t pos = activeFile->getVirtualAddress();
return activeFile->seekVirtual(pos+bytes);
}

int64_t FileManager::getOpenFileID() {
if (checkActiveFile() == false)
return 0;

static_assert(sizeof(int64_t) >= sizeof(intptr_t), "Assumes pointers are <= 64 bit");
return (int64_t)(intptr_t)activeFile.get();
}
1 change: 1 addition & 0 deletions Core/FileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class FileManager
bool seekPhysical(int64_t physicalAddress);
bool advanceMemory(size_t bytes);
std::shared_ptr<AssemblerFile> getOpenFile() { return activeFile; };
int64_t getOpenFileID();
void setEndianness(Endianness endianness) { this->endianness = endianness; };
Endianness getEndianness() { return endianness; }
private:
Expand Down
6 changes: 3 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ Specifies the working directory to be used during execution.
#### `-stat`
Outputs statistics for bytes used within areas after completion. Example output:
```
Total: 5342 / 7934
Largest: 0x0806E80C, 532 / 1156
Most free: 0x0806E80C, 532 / 1156 (free at 0x0806EA20)
Total areas: 5342 / 7934
Largest area: 0x0806E80C, 532 / 1156
Most free area: 0x0806E80C, 532 / 1156 (free at 0x0806EA20)
```

# 2. Installation
Expand Down

0 comments on commit e7ebd4f

Please sign in to comment.