reduce vm::Zone interface

This commit is contained in:
Joshua Warner 2014-05-04 22:02:47 -06:00
parent eb92c904c6
commit 2d0ac3ac17
7 changed files with 63 additions and 75 deletions

View File

@ -118,7 +118,7 @@ class OffsetPromise : public Promise {
class ListenPromise : public Promise { class ListenPromise : public Promise {
public: public:
ListenPromise(vm::System* s, util::Allocator* allocator) ListenPromise(vm::System* s, util::AllocOnly* allocator)
: s(s), allocator(allocator), listener(0) : s(s), allocator(allocator), listener(0)
{ {
} }
@ -142,7 +142,7 @@ class ListenPromise : public Promise {
} }
vm::System* s; vm::System* s;
util::Allocator* allocator; util::AllocOnly* allocator;
Listener* listener; Listener* listener;
Promise* promise; Promise* promise;
}; };
@ -150,7 +150,7 @@ class ListenPromise : public Promise {
class DelayedPromise : public ListenPromise { class DelayedPromise : public ListenPromise {
public: public:
DelayedPromise(vm::System* s, DelayedPromise(vm::System* s,
util::Allocator* allocator, util::AllocOnly* allocator,
Promise* basis, Promise* basis,
DelayedPromise* next) DelayedPromise* next)
: ListenPromise(s, allocator), basis(basis), next(next) : ListenPromise(s, allocator), basis(basis), next(next)

View File

@ -16,24 +16,21 @@
namespace avian { namespace avian {
namespace util { namespace util {
class Allocator { class AllocOnly {
public: public:
// Returns null on failure
virtual void* tryAllocate(size_t size) = 0;
// Aborts on failure
virtual void* allocate(size_t size) = 0; virtual void* allocate(size_t size) = 0;
};
// By contract, size MUST be the original size of the allocated data, and p class Allocator : public AllocOnly {
// MUST point to the original base of the allocated data. No partial frees. public:
virtual void* tryAllocate(size_t size) = 0;
virtual void free(const void* p, size_t size) = 0; virtual void free(const void* p, size_t size) = 0;
}; };
} // namespace util } // namespace util
} // namespace avian } // namespace avian
inline void* operator new(size_t size, avian::util::Allocator* allocator) inline void* operator new(size_t size, avian::util::AllocOnly* allocator)
{ {
return allocator->allocate(size); return allocator->allocate(size);
} }

View File

@ -69,12 +69,12 @@ class Slice {
return Slice<T>(this->begin() + begin, count); return Slice<T>(this->begin() + begin, count);
} }
static Slice<T> alloc(Allocator* a, size_t count) static Slice<T> alloc(AllocOnly* a, size_t count)
{ {
return Slice<T>((T*)a->allocate(sizeof(T) * count), count); return Slice<T>((T*)a->allocate(sizeof(T) * count), count);
} }
static Slice<T> allocAndSet(Allocator* a, size_t count, const T& item) static Slice<T> allocAndSet(AllocOnly* a, size_t count, const T& item)
{ {
Slice<T> slice(alloc(a, count)); Slice<T> slice(alloc(a, count));
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
@ -83,14 +83,14 @@ class Slice {
return slice; return slice;
} }
Slice<T> clone(Allocator* a, size_t newCount) Slice<T> clone(AllocOnly* a, size_t newCount)
{ {
T* newItems = (T*)a->allocate(newCount * sizeof(T)); T* newItems = (T*)a->allocate(newCount * sizeof(T));
memcpy(newItems, items, min(count, newCount) * sizeof(T)); memcpy(newItems, items, min(count, newCount) * sizeof(T));
return Slice<T>(newItems, newCount); return Slice<T>(newItems, newCount);
} }
Slice<T> cloneAndSet(Allocator* a, size_t newCount, const T& item) Slice<T> cloneAndSet(AllocOnly* a, size_t newCount, const T& item)
{ {
Slice<T> slice(clone(a, newCount)); Slice<T> slice(clone(a, newCount));
for (size_t i = count; i < newCount; i++) { for (size_t i = count; i < newCount; i++) {

View File

@ -17,7 +17,7 @@
namespace vm { namespace vm {
class Zone : public avian::util::Allocator { class Zone : public avian::util::AllocOnly {
public: public:
class Segment { class Segment {
public: public:
@ -31,9 +31,8 @@ class Zone : public avian::util::Allocator {
uint8_t data[0]; uint8_t data[0];
}; };
Zone(System* s, Allocator* allocator, unsigned minimumFootprint) Zone(avian::util::Allocator* allocator, size_t minimumFootprint)
: s(s), : allocator(allocator),
allocator(allocator),
segment(0), segment(0),
minimumFootprint(minimumFootprint < sizeof(Segment) minimumFootprint(minimumFootprint < sizeof(Segment)
? 0 ? 0
@ -56,6 +55,46 @@ class Zone : public avian::util::Allocator {
segment = 0; segment = 0;
} }
virtual void* allocate(size_t size)
{
size = pad(size);
void* p = tryAllocate(size);
if (p) {
return p;
} else {
ensure(size);
void* r = segment->data + segment->position;
segment->position += size;
return r;
}
}
void* peek(size_t size)
{
size = pad(size);
Segment* s = segment;
while (s->position < size) {
size -= s->position;
s = s->next;
}
return s->data + (s->position - size);
}
void pop(size_t size)
{
size = pad(size);
Segment* s = segment;
while (s->position < size) {
size -= s->position;
Segment* next = s->next;
allocator->free(s, sizeof(Segment) + s->size);
s = next;
}
s->position -= size;
segment = s;
}
private:
static unsigned padToPage(unsigned size) static unsigned padToPage(unsigned size)
{ {
return (size + (LikelyPageSizeInBytes - 1)) & ~(LikelyPageSizeInBytes - 1); return (size + (LikelyPageSizeInBytes - 1)) & ~(LikelyPageSizeInBytes - 1);
@ -95,7 +134,7 @@ class Zone : public avian::util::Allocator {
} }
} }
virtual void* tryAllocate(size_t size) void* tryAllocate(size_t size)
{ {
size = pad(size); size = pad(size);
if (tryEnsure(size)) { if (tryEnsure(size)) {
@ -107,54 +146,7 @@ class Zone : public avian::util::Allocator {
} }
} }
virtual void* allocate(size_t size) avian::util::Allocator* allocator;
{
size = pad(size);
void* p = tryAllocate(size);
if (p) {
return p;
} else {
ensure(size);
void* r = segment->data + segment->position;
segment->position += size;
return r;
}
}
void* peek(unsigned size)
{
size = pad(size);
Segment* s = segment;
while (s->position < size) {
size -= s->position;
s = s->next;
}
return s->data + (s->position - size);
}
void pop(unsigned size)
{
size = pad(size);
Segment* s = segment;
while (s->position < size) {
size -= s->position;
Segment* next = s->next;
allocator->free(s, sizeof(Segment) + s->size);
s = next;
}
s->position -= size;
segment = s;
}
virtual void free(const void*, size_t)
{
// not supported
abort(s);
}
System* s;
Allocator* allocator;
void* context;
Segment* segment; Segment* segment;
unsigned minimumFootprint; unsigned minimumFootprint;
}; };

View File

@ -1158,7 +1158,7 @@ class Context {
Context(MyThread* t, BootContext* bootContext, GcMethod* method) Context(MyThread* t, BootContext* bootContext, GcMethod* method)
: thread(t), : thread(t),
zone(t->m->system, t->m->heap, InitialZoneCapacityInBytes), zone(t->m->heap, InitialZoneCapacityInBytes),
assembler(t->arch->makeAssembler(t->m->heap, &zone)), assembler(t->arch->makeAssembler(t->m->heap, &zone)),
client(t), client(t),
compiler(makeCompiler(t->m->system, assembler, &zone, &client)), compiler(makeCompiler(t->m->system, assembler, &zone, &client)),
@ -1191,7 +1191,7 @@ class Context {
Context(MyThread* t) Context(MyThread* t)
: thread(t), : thread(t),
zone(t->m->system, t->m->heap, InitialZoneCapacityInBytes), zone(t->m->heap, InitialZoneCapacityInBytes),
assembler(t->arch->makeAssembler(t->m->heap, &zone)), assembler(t->arch->makeAssembler(t->m->heap, &zone)),
client(t), client(t),
compiler(0), compiler(0),
@ -3743,8 +3743,7 @@ class Stack {
Stack* s; Stack* s;
}; };
Stack(MyThread* t) Stack(MyThread* t) : thread(t), zone(t->m->heap, 0), resource(this)
: thread(t), zone(t->m->system, t->m->heap, 0), resource(this)
{ {
} }

View File

@ -1431,7 +1431,7 @@ void writeBootImage2(Thread* t,
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
roots(t)->setOutOfMemoryError(t, throwable); roots(t)->setOutOfMemoryError(t, throwable);
Zone zone(t->m->system, t->m->heap, 64 * 1024); Zone zone(t->m->heap, 64 * 1024);
class MyCompilationHandler : public Processor::CompilationHandler { class MyCompilationHandler : public Processor::CompilationHandler {
public: public:

View File

@ -52,7 +52,7 @@ class Asm {
Assembler* a; Assembler* a;
Asm(BasicEnv& env) Asm(BasicEnv& env)
: zone(env.s, env.heap, 8192), a(env.arch->makeAssembler(env.heap, &zone)) : zone(env.heap, 8192), a(env.arch->makeAssembler(env.heap, &zone))
{ {
} }