Skip to content

Commit

Permalink
assembler: Memory/performance optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
CyberShadow committed Dec 29, 2013
1 parent fbebd86 commit e5e01ea
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions assembler.d
Expand Up @@ -49,25 +49,29 @@ final class Assembler
{
string name;
string[] arguments;
bool isVirtual;
string data;
@property bool isVirtual() { return data ! is null; }

File parent;

const(char)* ptr, end;

enum BUF_SIZE = 256*1024;
enum PADDING = 16;
private char[] buffer;
static char[][] usedBuffers;

ulong filePosition; // File position of buffer.ptr
sizediff_t shift; // Error location adjustment
std.stdio.File f;

this(string name, in char[] data = null, string[] arguments = null)
this(string name, string data = null, string[] arguments = null)
{
this.name = name;
this.arguments = arguments;
this.data = data;
if (data)
{
isVirtual = true;
createBuffer(data.length);
buffer[] = data[];
ptr = buffer.ptr;
Expand All @@ -93,30 +97,39 @@ final class Assembler
{
ptr = result.ptr;
end = ptr + result.length;
if (result.length < BUF_SIZE)
buffer[result.length..result.length+PADDING] = 0;
return true;
}
else
{
f.close();
ptr = end = null;
ptr = end = buffer.ptr + buffer.length - PADDING;
usedBuffers ~= buffer;
buffer = null;
return false;
}
}

void createBuffer(size_t size)
{
// keep a null gutter at the end for readWord, readString
auto bufferSize = size + 16;
if (buffer.length < bufferSize)
buffer.length = bufferSize;
// guarantee that an out-of-bounds access (within a few bytes)
// will result in a null character, as an optimization
auto bufferSize = size + PADDING;
if (usedBuffers.length && usedBuffers[0].length >= bufferSize)
{
buffer = usedBuffers[0];
usedBuffers = usedBuffers[1..$];
}
else
buffer = new char[bufferSize];
ptr = end = buffer.ptr;
buffer[] = 0;
}

@property Position position()
{
return Position(this, filePosition + (ptr - buffer.ptr) + shift);
return Position(this, filePosition + (buffer ? ptr - buffer.ptr : 0) + shift);
}

@property string positionStr()
Expand All @@ -128,7 +141,7 @@ final class Assembler

InputRange!(ubyte[]) dataSource;
if (isVirtual)
dataSource = (cast(ubyte[])buffer).only.inputRangeObject;
dataSource = (cast(ubyte[])data).only.inputRangeObject;
else
{
f.open(name, "rb");
Expand All @@ -153,12 +166,8 @@ final class Assembler

@property char front()
{
if (ptr == end)
{
if (!loadNextChunk())
return 0;
}
return *ptr;
char c;
return (c = *ptr) != 0 ? c : (loadNextChunk(), *ptr);
}

void popFront()
Expand Down Expand Up @@ -224,7 +233,7 @@ final class Assembler
switch (word)
{
case "mixin":
pushFile(new File("#mixin", readString()));
pushFile(new File("#mixin", readString().idup));
break;
case "call": // #mixin with arguments
pushFile(new File("#call", readString().idup, readList!('(', ')', readImmString, false)()));
Expand Down Expand Up @@ -1398,5 +1407,4 @@ struct StackBuf
return (*buffer)[0..ptr-(*buffer).ptr];
}
}

alias StackBuf.create getBuf;

0 comments on commit e5e01ea

Please sign in to comment.