From 754442d4502b743a46831055484c3fa9fa621ec2 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 9 Oct 2012 23:27:55 +0200 Subject: [PATCH] better allocation in interpreter --- Debug/src/loader/subdir.mk | 3 ++ Release/src/loader/subdir.mk | 3 ++ src/loader/Interpreter.cpp | 33 +++++++------------ src/loader/Interpreter.h | 5 ++- src/loader/PagedAllocator.cpp | 60 +++++++++++++++++++++++++++++++++++ src/loader/PagedAllocator.h | 42 ++++++++++++++++++++++++ src/loader/fwd.h | 1 + 7 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 src/loader/PagedAllocator.cpp create mode 100644 src/loader/PagedAllocator.h diff --git a/Debug/src/loader/subdir.mk b/Debug/src/loader/subdir.mk index 7a5dbb3..a7ad663 100644 --- a/Debug/src/loader/subdir.mk +++ b/Debug/src/loader/subdir.mk @@ -6,6 +6,7 @@ CPP_SRCS += \ ../src/loader/Caster.cpp \ ../src/loader/Interpreter.cpp \ +../src/loader/PagedAllocator.cpp \ ../src/loader/ParsedSource.cpp \ ../src/loader/Parser.cpp \ ../src/loader/Tokenizer.cpp \ @@ -15,6 +16,7 @@ CPP_SRCS += \ OBJS += \ ./src/loader/Caster.o \ ./src/loader/Interpreter.o \ +./src/loader/PagedAllocator.o \ ./src/loader/ParsedSource.o \ ./src/loader/Parser.o \ ./src/loader/Tokenizer.o \ @@ -24,6 +26,7 @@ OBJS += \ CPP_DEPS += \ ./src/loader/Caster.d \ ./src/loader/Interpreter.d \ +./src/loader/PagedAllocator.d \ ./src/loader/ParsedSource.d \ ./src/loader/Parser.d \ ./src/loader/Tokenizer.d \ diff --git a/Release/src/loader/subdir.mk b/Release/src/loader/subdir.mk index d405524..86ed9d6 100644 --- a/Release/src/loader/subdir.mk +++ b/Release/src/loader/subdir.mk @@ -6,6 +6,7 @@ CPP_SRCS += \ ../src/loader/Caster.cpp \ ../src/loader/Interpreter.cpp \ +../src/loader/PagedAllocator.cpp \ ../src/loader/ParsedSource.cpp \ ../src/loader/Parser.cpp \ ../src/loader/Tokenizer.cpp \ @@ -15,6 +16,7 @@ CPP_SRCS += \ OBJS += \ ./src/loader/Caster.o \ ./src/loader/Interpreter.o \ +./src/loader/PagedAllocator.o \ ./src/loader/ParsedSource.o \ ./src/loader/Parser.o \ ./src/loader/Tokenizer.o \ @@ -24,6 +26,7 @@ OBJS += \ CPP_DEPS += \ ./src/loader/Caster.d \ ./src/loader/Interpreter.d \ +./src/loader/PagedAllocator.d \ ./src/loader/ParsedSource.d \ ./src/loader/Parser.d \ ./src/loader/Tokenizer.d \ diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index a3d382c..5da1ff3 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -54,18 +54,9 @@ using std::vector; namespace loader { Interpreter::~Interpreter() { - for (vector::const_iterator i(postponedDefinitions.begin()), end(postponedDefinitions.end()); i != end; ++i) { - delete i->identifier; - } for (std::map::const_iterator i(imageCache.begin()), end(imageCache.end()); i != end; ++i) { SDL_FreeSurface(i->second); } - // TODO: maybe need to reverse the array deletion check if most objects turn out to be arrays (of char) - for (std::map >::const_iterator i(values.begin()), end(values.end()); i != end; ++i) { - for (vector::const_iterator j(i->second.begin()), end(i->second.end()); j != end; ++j) { - delete[] reinterpret_cast(*j); - } - } } @@ -120,7 +111,7 @@ void Interpreter::ReadLiteral(const Definition &dfn) { (dfn.GetLiteral()->GetType() == Literal::PATH || dfn.GetLiteral()->GetType() == Literal::STRING) ? dfn.GetLiteral()->GetString().size() : td.Size()); - char *object(new char[size]); + char *object(alloc.Alloc(size)); if (dfn.GetLiteral()->GetType() == Literal::OBJECT) { ReadObject(typeId, id, object, *dfn.GetLiteral()->GetProperties()); } else { @@ -170,7 +161,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { if (v.GetLiteral().IsObject()) { int typeId(TypeDescription::GetTypeId(v.GetLiteral().GetTypeName())); const TypeDescription &td(TypeDescription::Get(typeId)); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); td.Construct(object); int id(values[typeId].size()); values[typeId].push_back(object); @@ -190,7 +181,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { typeId = TypeDescription::GetTypeId("Boolean"); id = values[typeId].size(); const TypeDescription &td(TypeDescription::Get(typeId)); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); values[typeId].push_back(new (object) bool(v.GetLiteral().GetBoolean())); } break; @@ -199,7 +190,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { typeId = TypeDescription::GetTypeId("Color"); id = values[typeId].size(); const TypeDescription &td(TypeDescription::Get(typeId)); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); values[typeId].push_back(new (object) Color(v.GetLiteral().GetRed(), v.GetLiteral().GetGreen(), v.GetLiteral().GetBlue(), v.GetLiteral().GetAlpha())); } break; @@ -208,7 +199,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { typeId = TypeDescription::GetTypeId("Number"); id = values[typeId].size(); const TypeDescription &td(TypeDescription::Get(typeId)); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); values[typeId].push_back(new (object) int(v.GetLiteral().GetNumber())); } break; @@ -216,7 +207,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { { typeId = TypeDescription::GetTypeId("Path"); id = values[typeId].size(); - char *str(new char[v.GetLiteral().GetString().size() + 1]); + char *str(alloc.Alloc(v.GetLiteral().GetString().size() + 1)); std::memcpy(str, v.GetLiteral().GetString().c_str(), v.GetLiteral().GetString().size()); str[v.GetLiteral().GetString().size()] = '\0'; values[typeId].push_back(str); @@ -226,7 +217,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { { typeId = TypeDescription::GetTypeId("String"); id = values[typeId].size(); - char *str(new char[v.GetLiteral().GetString().size() + 1]); + char *str(alloc.Alloc(v.GetLiteral().GetString().size() + 1)); std::memcpy(str, v.GetLiteral().GetString().c_str(), v.GetLiteral().GetString().size()); str[v.GetLiteral().GetString().size()] = '\0'; values[typeId].push_back(str); @@ -237,7 +228,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { typeId = TypeDescription::GetTypeId("Vector"); id = values[typeId].size(); const TypeDescription &td(TypeDescription::Get(typeId)); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); values[typeId].push_back(new (object) Vector(v.GetLiteral().GetX(), v.GetLiteral().GetY())); } break; @@ -246,7 +237,7 @@ void *Interpreter::GetObject(int typeId, const Value &v) { typeId = TypeDescription::GetTypeId(v.GetLiteral().GetTypeName()); const TypeDescription &td(TypeDescription::Get(typeId)); id = values[typeId].size(); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); td.Construct(object); ReadObject(typeId, id, object, *v.GetLiteral().GetProperties()); } @@ -265,7 +256,7 @@ void Interpreter::ReadObject(const Definition &dfn) { int typeId(TypeDescription::GetTypeId(dfn.TypeName())); const TypeDescription &td(TypeDescription::Get(typeId)); int id(values[typeId].size()); - char *object(new char[td.Size()]); + char *object(alloc.Alloc(td.Size())); td.Construct(object); values[typeId].push_back(object); ReadObject(typeId, id, object, *dfn.GetProperties()); @@ -282,7 +273,7 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis char *dest(object + fd.Offset()); if (fd.IsAggregate()) { int arraySize(i->second->GetLiteral().ArraySize()); - char *aggregate(new char[fieldType.Size() * arraySize]); + char *aggregate(alloc.Alloc(fieldType.Size() * arraySize)); char *iter(aggregate); if (i->second->GetLiteral().GetType() == Literal::ARRAY_PROPS) { const vector &list(i->second->GetLiteral().GetPropertyLists()); @@ -340,7 +331,7 @@ bool Interpreter::CanLink(const Value &v) const { } void Interpreter::Postpone(int type, int id, std::ptrdiff_t offset, const std::string &identifier, int linkedType, bool inlined) { - char *str(new char[identifier.size() + 1]); + char *str(alloc.Alloc(identifier.size() + 1)); std::memcpy(str, identifier.c_str(), identifier.size()); str[identifier.size()] = '\0'; postponedDefinitions.push_back(PostponedDefinition(type, id, offset, str, linkedType, inlined)); diff --git a/src/loader/Interpreter.h b/src/loader/Interpreter.h index 9e90bcc..15cebd5 100644 --- a/src/loader/Interpreter.h +++ b/src/loader/Interpreter.h @@ -9,6 +9,7 @@ #define LOADER_INTERPRETER_H_ #include "fwd.h" +#include "PagedAllocator.h" #include "ParsedSource.h" #include "TypeDescription.h" #include "../battle/fwd.h" @@ -36,7 +37,7 @@ public: }; public: - explicit Interpreter(const ParsedSource &source) : source(source) { } + explicit Interpreter(const ParsedSource &source) : source(source), alloc(4096) { } ~Interpreter(); private: Interpreter(const Interpreter &); @@ -88,6 +89,8 @@ private: private: const ParsedSource &source; + PagedAllocator alloc; + std::map parsedDefinitions; std::vector postponedDefinitions; std::map imageCache; diff --git a/src/loader/PagedAllocator.cpp b/src/loader/PagedAllocator.cpp new file mode 100644 index 0000000..4853a1e --- /dev/null +++ b/src/loader/PagedAllocator.cpp @@ -0,0 +1,60 @@ +/* + * PagedAllocator.cpp + * + * Created on: Oct 9, 2012 + * Author: holy + */ + +#include "PagedAllocator.h" + +using std::deque; + +namespace loader { + +PagedAllocator::PagedAllocator(unsigned int pageSize) +: head(0) +, pageSize(pageSize) { + NewPage(); +} + +PagedAllocator::~PagedAllocator() { + for (deque::const_iterator i(pages.begin()), end(pages.end()); i != end; ++i) { + delete[] *i; + } +} + + +char *PagedAllocator::Alloc(unsigned int size) { + if (size > pageSize) { + char *page(new char[size]); + pages.push_front(page); + return page; + } + unsigned int free(Free()); + if (free < size) { + NewPage(); + } + char *chunk(head); + head += size; + return chunk; +} + +unsigned int PagedAllocator::Free() const { + return pageSize - (head - CurrentPage()); +} + +void PagedAllocator::NewPage() { + char *page(new char[pageSize]); + pages.push_back(page); + head = page; +} + +char *PagedAllocator::CurrentPage() { + return pages.back(); +} + +const char *PagedAllocator::CurrentPage() const { + return pages.back(); +} + +} diff --git a/src/loader/PagedAllocator.h b/src/loader/PagedAllocator.h new file mode 100644 index 0000000..48cda27 --- /dev/null +++ b/src/loader/PagedAllocator.h @@ -0,0 +1,42 @@ +/* + * PagedAllocator.h + * + * Created on: Oct 9, 2012 + * Author: holy + */ + +#ifndef LOADER_PAGEDALLOCATOR_H_ +#define LOADER_PAGEDALLOCATOR_H_ + +#include + +namespace loader { + +class PagedAllocator { + +public: + explicit PagedAllocator(unsigned int pageSize); + ~PagedAllocator(); +private: + PagedAllocator(const PagedAllocator &); + PagedAllocator &operator =(const PagedAllocator &); + +public: + char *Alloc(unsigned int size); + +private: + unsigned int Free() const; + void NewPage(); + char *CurrentPage(); + const char *CurrentPage() const; + +private: + char *head; + std::deque pages; + const unsigned int pageSize; + +}; + +} + +#endif /* LOADER_PAGEDALLOCATOR_H_ */ diff --git a/src/loader/fwd.h b/src/loader/fwd.h index cdb2eaf..2f90849 100644 --- a/src/loader/fwd.h +++ b/src/loader/fwd.h @@ -16,6 +16,7 @@ class Definition; class FieldDescription; class Interpreter; class Literal; +class PagedAllocator; class ParsedSource; class Parser; class PropertyList; -- 2.39.2