summaryrefslogtreecommitdiff
path: root/Menes
diff options
context:
space:
mode:
authorJay Freeman (saurik) <saurik@saurik.com>2015-06-26 23:02:32 -0700
committerJay Freeman (saurik) <saurik@saurik.com>2015-06-26 23:02:44 -0700
commit64edd9dfbc798337d33d3b070a1174c9a1b09eb9 (patch)
treeb0dbd784b8f81306061752e38b724d00136a0480 /Menes
parentb4fd1197563aca30cf01bf3efaa5c015ba768e11 (diff)
Borrow Cycript's CYPool to avoid Depends: apr-lib.
Diffstat (limited to 'Menes')
-rw-r--r--Menes/Menes.h1
-rw-r--r--Menes/Pooling.hpp117
2 files changed, 118 insertions, 0 deletions
diff --git a/Menes/Menes.h b/Menes/Menes.h
index 5da16ba..0a421c7 100644
--- a/Menes/Menes.h
+++ b/Menes/Menes.h
@@ -24,6 +24,7 @@
#include "Menes/Function.h"
#include "Menes/ObjectHandle.h"
+#include "Menes/Pooling.hpp"
#include "Menes/invocationWithSelector.h"
#include "Menes/radixSortWithSelector.h"
diff --git a/Menes/Pooling.hpp b/Menes/Pooling.hpp
new file mode 100644
index 0000000..751f397
--- /dev/null
+++ b/Menes/Pooling.hpp
@@ -0,0 +1,117 @@
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2014 Jay Freeman (saurik)
+*/
+
+/* GNU Affero General Public License, Version 3 {{{ */
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#ifndef Menes_Pooling_HPP
+#define Menes_Pooling_HPP
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <algorithm>
+
+#include <stdint.h>
+
+class CYPool;
+_finline void *operator new(size_t size, CYPool &pool);
+_finline void *operator new [](size_t size, CYPool &pool);
+
+class CYPool {
+ private:
+ uint8_t *data_;
+ size_t size_;
+
+ struct Cleaner {
+ Cleaner *next_;
+ void (*code_)(void *);
+ void *data_;
+
+ Cleaner(Cleaner *next, void (*code)(void *), void *data) :
+ next_(next),
+ code_(code),
+ data_(data)
+ {
+ }
+ } *cleaner_;
+
+ static _finline size_t align(size_t size) {
+ // XXX: alignment is more complex than this
+ return (size + 7) & ~0x3;
+ }
+
+ template <typename Type_>
+ static void delete_(void *data) {
+ reinterpret_cast<Type_ *>(data)->~Type_();
+ }
+
+ CYPool(const CYPool &);
+
+ public:
+ CYPool() :
+ data_(NULL),
+ size_(0),
+ cleaner_(NULL)
+ {
+ }
+
+ ~CYPool() {
+ for (Cleaner *cleaner(cleaner_); cleaner != NULL; ) {
+ Cleaner *next(cleaner->next_);
+ (*cleaner->code_)(cleaner->data_);
+ cleaner = next;
+ }
+ }
+
+ template <typename Type_>
+ Type_ *malloc(size_t size) {
+ size = align(size);
+
+ if (size > size_) {
+ // XXX: is this an optimal malloc size?
+ size_ = std::max<size_t>(size, size + align(sizeof(Cleaner)));
+ data_ = reinterpret_cast<uint8_t *>(::malloc(size_));
+ atexit(free, data_);
+ _assert(size <= size_);
+ }
+
+ void *data(data_);
+ data_ += size;
+ size_ -= size;
+ return reinterpret_cast<Type_ *>(data);
+ }
+
+ void atexit(void (*code)(void *), void *data = NULL);
+};
+
+_finline void *operator new(size_t size, CYPool &pool) {
+ return pool.malloc<void>(size);
+}
+
+_finline void *operator new [](size_t size, CYPool &pool) {
+ return pool.malloc<void>(size);
+}
+
+_finline void CYPool::atexit(void (*code)(void *), void *data) {
+ cleaner_ = new(*this) Cleaner(cleaner_, code, data);
+}
+
+#endif/*Menes_Pooling_HPP*/