aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2010-08-29 04:25:45 +0000
committerdos-reis <gdr@axiomatics.org>2010-08-29 04:25:45 +0000
commit871c6f7c1422155b3263455e291e6eaace27af87 (patch)
treeb75edc04e4a185cf7230e261dc269ba50f78d231
parentac04b468720e2d7804c4d23eb9c4560f14ad2228 (diff)
downloadopen-axiom-871c6f7c1422155b3263455e291e6eaace27af87.tar.gz
* utils/Makefile.in ($(oa_target_oalib)): Create contaning
directory if necessary. * utils/storage.H (Memory::Factory): New. Allocate, construct, and destroy objects. * utils/sexpr.H (Sexpr::Allocator): Use Memory::Factory. * utils/sexpr.cc: Adjust implementation.
-rw-r--r--src/ChangeLog9
-rw-r--r--src/utils/Makefile.in3
-rw-r--r--src/utils/sexpr.H4
-rw-r--r--src/utils/sexpr.cc6
-rw-r--r--src/utils/storage.H75
5 files changed, 78 insertions, 19 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 90543b37..f24a8bd8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2010-08-28 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * utils/Makefile.in ($(oa_target_oalib)): Create contaning
+ directory if necessary.
+ * utils/storage.H (Memory::Factory): New. Allocate, construct,
+ and destroy objects.
+ * utils/sexpr.H (Sexpr::Allocator): Use Memory::Factory.
+ * utils/sexpr.cc: Adjust implementation.
+
2010-08-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
* utils/Makefile.in: Install libOpenAxiom.a
diff --git a/src/utils/Makefile.in b/src/utils/Makefile.in
index db30091e..2e963e67 100644
--- a/src/utils/Makefile.in
+++ b/src/utils/Makefile.in
@@ -64,6 +64,9 @@ stamp: $(oa_target_oalib) hammer$(EXEEXT)
$(STAMP) stamp
$(oa_target_oalib): libOpenAxiom.$(LIBEXT)
+ if [ ! -d $(axiom_target_libdir) ]; then \
+ mkdir -p $(axiom_target_libdir); \
+ fi
cp $< $@
stamp-headers: $(libOpenAxiom_HEADERS) Makefile
diff --git a/src/utils/sexpr.H b/src/utils/sexpr.H
index 3059dce5..f7c9f766 100644
--- a/src/utils/sexpr.H
+++ b/src/utils/sexpr.H
@@ -348,8 +348,8 @@ namespace OpenAxiom {
UniqueAllocator<Quote> quotes;
UniqueAllocator<Function> funs;
UniqueAllocator<Pair> pairs;
- Memory::Arena<List> lists;
- Memory::Arena<Vector> vectors;
+ Memory::Factory<List> lists;
+ Memory::Factory<Vector> vectors;
List empty_list;
Vector empty_vector;
};
diff --git a/src/utils/sexpr.cc b/src/utils/sexpr.cc
index 248c0649..4910f053 100644
--- a/src/utils/sexpr.cc
+++ b/src/utils/sexpr.cc
@@ -395,7 +395,7 @@ namespace OpenAxiom {
// ---------------
// -- Allocator --
// ---------------
- Allocator::Allocator() : lists(4 * 1024), vectors(1024) { }
+ Allocator::Allocator() { }
// This destructor is defined here so that it provides
// a single instantiation point for destructors of all
@@ -446,14 +446,14 @@ namespace OpenAxiom {
Allocator::make_list(const std::vector<const Syntax*>& elts) {
if (elts.empty())
return &empty_list;
- return new(lists.allocate(1)) List(elts);
+ return lists.make(elts);
}
const Vector*
Allocator::make_vector(const std::vector<const Syntax*>& elts) {
if (elts.empty())
return &empty_vector;
- return new(vectors.allocate(1)) Vector(elts);
+ return vectors.make(elts);
}
// ------------
diff --git a/src/utils/storage.H b/src/utils/storage.H
index 03b03604..ad8eaa09 100644
--- a/src/utils/storage.H
+++ b/src/utils/storage.H
@@ -40,6 +40,7 @@
#include <stddef.h>
#include <string.h>
+#include <new>
#include <cmath>
#include <string>
@@ -184,15 +185,12 @@ namespace OpenAxiom {
// The totality of all objects held in such a storage does not
// necessarily constitute a contiguous block. However,
// it is guaranteed that objects allocated in a single call
- // to `allocate()' occupy a contiguous block of memory.
- // Objects are destroyed when the arena is destroyed. So,
- // allocators of this type implement a form of sticky object
- // allocator.
+ // to `allocate()' occupy a contiguous block of storage.
template<typename T>
struct Arena {
// Acquire storage capable of holding `n' objects of type `T'.
explicit Arena(size_t);
- // Destroy allocated objects when done.
+ // Release all storage acquired by this object, upon end of life.
~Arena();
// allocate storage for `n' more objects of type `T'.
T* allocate(size_t);
@@ -216,14 +214,14 @@ namespace OpenAxiom {
return last_object(s) - first_object(s);
}
- private:
- Storage* store; // active storage to allocate from
-
// The `previous' link in the chain of storage.
static Storage*& previous(Storage* s) {
return *static_cast<Storage**>(s->at_offset(0));
}
+ Storage* store; // active storage to allocate from
+
+ private:
// Acquire storage large enough to hold `n' objects of type `T'.
static Storage* acquire(size_t);
};
@@ -257,12 +255,6 @@ namespace OpenAxiom {
// Destroy objects in the reverse order of their
// their allocation.
while (store != 0) {
- // The first allocated object is right after the `previous'
- // link in the storage chain.
- T* first = first_object(store);
- T* last = last_object(store);
- for (--last; first >= last; --last)
- last->~T();
Storage* current = store;
store = previous(store);
Storage::release(current);
@@ -284,6 +276,61 @@ namespace OpenAxiom {
return s;
}
+ // -------------
+ // -- Factory --
+ // -------------
+ template<typename T>
+ struct Factory : Arena<T> {
+ Factory() : Arena<T>(nominal_population()) { }
+ ~Factory();
+
+ // Allocate storage and value-construct an object of type `T'.
+ T* make() {
+ return new(this->allocate(1)) T();
+ }
+
+ // Allocate storage and construct an object of type `T'.
+ template<typename U>
+ T* make(const U& u) {
+ return new(this->allocate(1)) T(u);
+ }
+
+ // Allocate storage and construct an object of type `T'.
+ template<typename U, typename V>
+ T* make(const U& u, const V& v) {
+ return new(this->allocate(1)) T(u, v);
+ }
+
+ // Allocate storage and construct an object of type `T'.
+ template<typename U, typename V, typename W>
+ T* make(const U& u, const V& v, const W& w) {
+ return new(this->allocate(1)) T(u, v, w);
+ }
+
+ private:
+ // Return 1 or the number of objects that can fit in a page unit.
+ static size_t nominal_population() {
+ const size_t overhead =
+ Storage::round_up(sizeof(Storage),
+ openaxiom_alignment(Storage*))
+ + Storage::round_up(sizeof(Storage*), openaxiom_alignment(T));
+ const size_t psz = page_size();
+ if (overhead + sizeof (T) > psz)
+ return 1;
+ return (psz - overhead) / sizeof(T);
+ }
+ };
+
+ // Destroy objects in the reverse order of their construction.
+ template<typename T>
+ Factory<T>::~Factory() {
+ for (Storage* s = this->store; s != 0; s = Arena<T>::previous(s)) {
+ T* last = Arena<T>::last_object(s);
+ for (--last; last >= Arena<T>::first_object(s); --last)
+ last->~T();
+ }
+ }
+
// -----------------
// -- FileMapping --
// -----------------