From: Daniel Karbach <daniel.karbach@localhorst.tv>
Date: Tue, 9 Oct 2012 21:27:55 +0000 (+0200)
Subject: better allocation in interpreter
X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=754442d4502b743a46831055484c3fa9fa621ec2;p=l2e.git

better allocation in interpreter
---

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<PostponedDefinition>::const_iterator i(postponedDefinitions.begin()), end(postponedDefinitions.end()); i != end; ++i) {
-		delete i->identifier;
-	}
 	for (std::map<string, SDL_Surface *>::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<int, vector<void *> >::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
-		for (vector<void *>::const_iterator j(i->second.begin()), end(i->second.end()); j != end; ++j) {
-			delete[] reinterpret_cast<char *>(*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<int>(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<PropertyList *> &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<std::string, ParsedDefinition> parsedDefinitions;
 	std::vector<PostponedDefinition> postponedDefinitions;
 	std::map<std::string, SDL_Surface *> 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<char *>::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 <deque>
+
+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<char *> 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;