summaryrefslogtreecommitdiff
path: root/src/emscripten-optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/emscripten-optimizer')
-rw-r--r--src/emscripten-optimizer/simple_ast.cpp45
-rw-r--r--src/emscripten-optimizer/simple_ast.h78
2 files changed, 45 insertions, 78 deletions
diff --git a/src/emscripten-optimizer/simple_ast.cpp b/src/emscripten-optimizer/simple_ast.cpp
index 4f36036ae..7379e9740 100644
--- a/src/emscripten-optimizer/simple_ast.cpp
+++ b/src/emscripten-optimizer/simple_ast.cpp
@@ -54,32 +54,7 @@ bool Ref::operator!() {
// Arena
-Arena arena;
-
-Arena::~Arena() {
- for (auto* chunk : chunks) {
- delete[] chunk;
- }
- for (auto* chunk : arr_chunks) {
- delete[] chunk;
- }
-}
-
-Ref Arena::alloc() {
- if (chunks.size() == 0 || index == CHUNK_SIZE) {
- chunks.push_back(new Value[CHUNK_SIZE]);
- index = 0;
- }
- return &chunks.back()[index++];
-}
-
-ArrayStorage* Arena::allocArray() {
- if (arr_chunks.size() == 0 || arr_index == CHUNK_SIZE) {
- arr_chunks.push_back(new ArrayStorage[CHUNK_SIZE]);
- arr_index = 0;
- }
- return &arr_chunks.back()[arr_index++];
-}
+GlobalMixedArena arena;
// dump
@@ -161,7 +136,7 @@ void traversePre(Ref node, std::function<void (Ref)> visit) {
int index = 0;
ArrayStorage* arr = &node->getArray();
int arrsize = (int)arr->size();
- Ref* arrdata = arr->data();
+ Ref* arrdata = &(*arr)[0];
stack.push_back(TraverseInfo(node, arr));
while (1) {
if (index < arrsize) {
@@ -173,7 +148,7 @@ void traversePre(Ref node, std::function<void (Ref)> visit) {
visit(sub);
arr = &sub->getArray();
arrsize = (int)arr->size();
- arrdata = arr->data();
+ arrdata = &(*arr)[0];
stack.push_back(TraverseInfo(sub, arr));
}
} else {
@@ -183,7 +158,7 @@ void traversePre(Ref node, std::function<void (Ref)> visit) {
index = back.index;
arr = back.arr;
arrsize = (int)arr->size();
- arrdata = arr->data();
+ arrdata = &(*arr)[0];
}
}
}
@@ -196,7 +171,7 @@ void traversePrePost(Ref node, std::function<void (Ref)> visitPre, std::function
int index = 0;
ArrayStorage* arr = &node->getArray();
int arrsize = (int)arr->size();
- Ref* arrdata = arr->data();
+ Ref* arrdata = &(*arr)[0];
stack.push_back(TraverseInfo(node, arr));
while (1) {
if (index < arrsize) {
@@ -208,7 +183,7 @@ void traversePrePost(Ref node, std::function<void (Ref)> visitPre, std::function
visitPre(sub);
arr = &sub->getArray();
arrsize = (int)arr->size();
- arrdata = arr->data();
+ arrdata = &(*arr)[0];
stack.push_back(TraverseInfo(sub, arr));
}
} else {
@@ -219,7 +194,7 @@ void traversePrePost(Ref node, std::function<void (Ref)> visitPre, std::function
index = back.index;
arr = back.arr;
arrsize = (int)arr->size();
- arrdata = arr->data();
+ arrdata = &(*arr)[0];
}
}
}
@@ -232,7 +207,7 @@ void traversePrePostConditional(Ref node, std::function<bool (Ref)> visitPre, st
int index = 0;
ArrayStorage* arr = &node->getArray();
int arrsize = (int)arr->size();
- Ref* arrdata = arr->data();
+ Ref* arrdata = &(*arr)[0];
stack.push_back(TraverseInfo(node, arr));
while (1) {
if (index < arrsize) {
@@ -244,7 +219,7 @@ void traversePrePostConditional(Ref node, std::function<bool (Ref)> visitPre, st
index = 0;
arr = &sub->getArray();
arrsize = (int)arr->size();
- arrdata = arr->data();
+ arrdata = &(*arr)[0];
stack.push_back(TraverseInfo(sub, arr));
}
}
@@ -256,7 +231,7 @@ void traversePrePostConditional(Ref node, std::function<bool (Ref)> visitPre, st
index = back.index;
arr = back.arr;
arrsize = (int)arr->size();
- arrdata = arr->data();
+ arrdata = &(*arr)[0];
}
}
}
diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h
index e89ddb666..f4dce76aa 100644
--- a/src/emscripten-optimizer/simple_ast.h
+++ b/src/emscripten-optimizer/simple_ast.h
@@ -36,6 +36,7 @@
#include "parser.h"
#include "snprintf.h"
#include "support/safe_integer.h"
+#include "mixed_arena.h"
#define err(str) fprintf(stderr, str "\n");
#define errv(str, ...) fprintf(stderr, str "\n", __VA_ARGS__);
@@ -73,25 +74,28 @@ struct Ref {
// Arena allocation, free it all on process exit
-typedef std::vector<Ref> ArrayStorage;
-
-struct Arena {
- #define CHUNK_SIZE 1000
- std::vector<Value*> chunks;
- int index; // in last chunk
-
- std::vector<ArrayStorage*> arr_chunks;
- int arr_index;
+// A mixed arena for global allocation only, so members do not
+// receive an allocator, they all use the global one anyhow
+class GlobalMixedArena : public MixedArena {
+public:
+ template<class T>
+ T* alloc() {
+ auto* ret = static_cast<T*>(allocSpace(sizeof(T)));
+ new (ret) T();
+ return ret;
+ }
+};
- Arena() : index(0), arr_index(0) {}
- ~Arena();
+extern GlobalMixedArena arena;
- Ref alloc();
- ArrayStorage* allocArray();
+class ArrayStorage : public ArenaVectorBase<ArrayStorage, Ref> {
+public:
+ void allocate(size_t size) {
+ allocatedElements = size;
+ data = static_cast<Ref*>(arena.allocSpace(sizeof(Ref) * allocatedElements));
+ }
};
-extern Arena arena;
-
// Main value type
struct Value {
enum Type {
@@ -139,7 +143,7 @@ struct Value {
}
void free() {
- if (type == Array) { arr->clear(); arr->shrink_to_fit(); }
+ if (type == Array) { arr->clear(); }
else if (type == Object) delete obj;
type = Null;
num = 0;
@@ -166,14 +170,14 @@ struct Value {
Value& setArray(ArrayStorage &a) {
free();
type = Array;
- arr = arena.allocArray();
+ arr = arena.alloc<ArrayStorage>();
*arr = a;
return *this;
}
Value& setArray(size_t size_hint=0) {
free();
type = Array;
- arr = arena.allocArray();
+ arr = arena.alloc<ArrayStorage>();
arr->reserve(size_hint);
return *this;
}
@@ -322,7 +326,7 @@ struct Value {
skip();
setArray();
while (*curr != ']') {
- Ref temp = arena.alloc();
+ Ref temp = arena.alloc<Value>();
arr->push_back(temp);
curr = temp->parse(curr);
skip();
@@ -364,7 +368,7 @@ struct Value {
assert(*curr == ':');
curr++;
skip();
- Ref value = arena.alloc();
+ Ref value = arena.alloc<Value>();
curr = value->parse(curr);
(*obj)[key] = value;
skip();
@@ -473,14 +477,14 @@ struct Value {
if (old != size) arr->resize(size);
if (old < size) {
for (auto i = old; i < size; i++) {
- (*arr)[i] = arena.alloc();
+ (*arr)[i] = arena.alloc<Value>();
}
}
}
Ref& operator[](unsigned x) {
assert(isArray());
- return arr->at(x);
+ return (*arr)[x];
}
Value& push_back(Ref r) {
@@ -501,18 +505,6 @@ struct Value {
return arr->back();
}
- void splice(int x, int num) {
- assert(isArray());
- arr->erase(arr->begin() + x, arr->begin() + x + num);
- }
-
- void insert(int x, int num) {
- arr->insert(arr->begin() + x, num, Ref());
- }
- void insert(int x, Ref node) {
- arr->insert(arr->begin() + x, 1, node);
- }
-
int indexOf(Ref other) {
assert(isArray());
for (size_t i = 0; i < arr->size(); i++) {
@@ -523,7 +515,7 @@ struct Value {
Ref map(std::function<Ref (Ref node)> func) {
assert(isArray());
- Ref ret = arena.alloc();
+ Ref ret = arena.alloc<Value>();
ret->setArray();
for (size_t i = 0; i < arr->size(); i++) {
ret->push_back(func((*arr)[i]));
@@ -533,7 +525,7 @@ struct Value {
Ref filter(std::function<bool (Ref node)> func) {
assert(isArray());
- Ref ret = arena.alloc();
+ Ref ret = arena.alloc<Value>();
ret->setArray();
for (size_t i = 0; i < arr->size(); i++) {
Ref curr = (*arr)[i];
@@ -1332,16 +1324,16 @@ class ValueBuilder {
static IStringSet statable;
static Ref makeRawString(const IString& s) {
- return &arena.alloc()->setString(s);
+ return &arena.alloc<Value>()->setString(s);
}
static Ref makeNull() {
- return &arena.alloc()->setNull();
+ return &arena.alloc<Value>()->setNull();
}
public:
static Ref makeRawArray(int size_hint=0) {
- return &arena.alloc()->setArray(size_hint);
+ return &arena.alloc<Value>()->setArray(size_hint);
}
static Ref makeToplevel() {
@@ -1471,7 +1463,7 @@ public:
}
static Ref makeDouble(double num) {
- return &arena.alloc()->setNumber(num);
+ return &arena.alloc<Value>()->setNumber(num);
}
static Ref makeInt(uint32_t num) {
return makeDouble(double(num));
@@ -1489,7 +1481,7 @@ public:
static Ref makeBinary(Ref left, IString op, Ref right) {
if (op == SET) {
return &makeRawArray(4)->push_back(makeRawString(ASSIGN))
- .push_back(&arena.alloc()->setBool(true))
+ .push_back(&arena.alloc<Value>()->setBool(true))
.push_back(left)
.push_back(right);
} else if (op == COMMA) {
@@ -1670,13 +1662,13 @@ public:
static Ref makeAssign(Ref target, Ref value) {
return &makeRawArray(3)->push_back(makeRawString(ASSIGN))
- .push_back(&arena.alloc()->setBool(true))
+ .push_back(&arena.alloc<Value>()->setBool(true))
.push_back(target)
.push_back(value);
}
static Ref makeAssign(IString target, Ref value) {
return &makeRawArray(3)->push_back(makeRawString(ASSIGN))
- .push_back(&arena.alloc()->setBool(true))
+ .push_back(&arena.alloc<Value>()->setBool(true))
.push_back(makeName(target))
.push_back(value);
}