diff options
Diffstat (limited to 'src/emscripten-optimizer')
-rw-r--r-- | src/emscripten-optimizer/simple_ast.cpp | 45 | ||||
-rw-r--r-- | src/emscripten-optimizer/simple_ast.h | 78 |
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); } |