From 64edd9dfbc798337d33d3b070a1174c9a1b09eb9 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Fri, 26 Jun 2015 23:02:32 -0700 Subject: Borrow Cycript's CYPool to avoid Depends: apr-lib. --- Menes/Menes.h | 1 + Menes/Pooling.hpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 Menes/Pooling.hpp (limited to 'Menes') 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 . +**/ +/* }}} */ + +#ifndef Menes_Pooling_HPP +#define Menes_Pooling_HPP + +#include +#include +#include +#include + +#include + +#include + +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 + static void delete_(void *data) { + reinterpret_cast(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 + Type_ *malloc(size_t size) { + size = align(size); + + if (size > size_) { + // XXX: is this an optimal malloc size? + size_ = std::max(size, size + align(sizeof(Cleaner))); + data_ = reinterpret_cast(::malloc(size_)); + atexit(free, data_); + _assert(size <= size_); + } + + void *data(data_); + data_ += size; + size_ -= size; + return reinterpret_cast(data); + } + + void atexit(void (*code)(void *), void *data = NULL); +}; + +_finline void *operator new(size_t size, CYPool &pool) { + return pool.malloc(size); +} + +_finline void *operator new [](size_t size, CYPool &pool) { + return pool.malloc(size); +} + +_finline void CYPool::atexit(void (*code)(void *), void *data) { + cleaner_ = new(*this) Cleaner(cleaner_, code, data); +} + +#endif/*Menes_Pooling_HPP*/ -- cgit v1.2.3