mirror of
https://github.com/corda/corda.git
synced 2025-06-05 17:01:45 +00:00
simplify memory allocation interfaces
This commit is contained in:
parent
d77ffa8e21
commit
0d3e6b7793
@ -18,9 +18,9 @@ namespace vm {
|
|||||||
class Allocator {
|
class Allocator {
|
||||||
public:
|
public:
|
||||||
virtual ~Allocator() { }
|
virtual ~Allocator() { }
|
||||||
virtual void* tryAllocate(unsigned size, bool executable) = 0;
|
virtual void* tryAllocate(unsigned size) = 0;
|
||||||
virtual void* allocate(unsigned size, bool executable) = 0;
|
virtual void* allocate(unsigned size) = 0;
|
||||||
virtual void free(const void* p, unsigned size, bool executable) = 0;
|
virtual void free(const void* p, unsigned size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -147,10 +147,10 @@ Java_java_lang_ClassLoader_defineClass
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
uint8_t* buffer = static_cast<uint8_t*>
|
uint8_t* buffer = static_cast<uint8_t*>
|
||||||
(t->m->heap->allocate(length, false));
|
(t->m->heap->allocate(length));
|
||||||
memcpy(buffer, &byteArrayBody(t, *b, offset), length);
|
memcpy(buffer, &byteArrayBody(t, *b, offset), length);
|
||||||
object c = parseClass(t, buffer, length);
|
object c = parseClass(t, buffer, length);
|
||||||
t->m->heap->free(buffer, length, false);
|
t->m->heap->free(buffer, length);
|
||||||
return makeLocalReference(t, c);
|
return makeLocalReference(t, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ class Context {
|
|||||||
|
|
||||||
Context(MyThread* t, object method, uint8_t* indirectCaller):
|
Context(MyThread* t, object method, uint8_t* indirectCaller):
|
||||||
t(t),
|
t(t),
|
||||||
zone(t->m->system, t->m->heap, false, 16 * 1024),
|
zone(t->m->system, t->m->heap, 16 * 1024),
|
||||||
c(makeCompiler(t->m->system, t->m->heap, &zone, indirectCaller)),
|
c(makeCompiler(t->m->system, t->m->heap, &zone, indirectCaller)),
|
||||||
method(method),
|
method(method),
|
||||||
objectPool(0),
|
objectPool(0),
|
||||||
@ -501,7 +501,7 @@ class Context {
|
|||||||
|
|
||||||
Context(MyThread* t):
|
Context(MyThread* t):
|
||||||
t(t),
|
t(t),
|
||||||
zone(t->m->system, t->m->heap, false, LikelyPageSizeInBytes),
|
zone(t->m->system, t->m->heap, LikelyPageSizeInBytes),
|
||||||
c(makeCompiler(t->m->system, t->m->heap, &zone, 0)),
|
c(makeCompiler(t->m->system, t->m->heap, &zone, 0)),
|
||||||
method(0),
|
method(0),
|
||||||
objectPool(0),
|
objectPool(0),
|
||||||
@ -3765,7 +3765,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Allocator*
|
Allocator*
|
||||||
codeAllocator(MyThread* t);
|
codeZone(MyThread* t);
|
||||||
|
|
||||||
int
|
int
|
||||||
compareTraceElementPointers(const void* va, const void* vb)
|
compareTraceElementPointers(const void* va, const void* vb)
|
||||||
@ -3811,8 +3811,8 @@ finish(MyThread* t, Context* context, const char* name)
|
|||||||
unsigned count = ceiling(c->codeSize() + c->poolSize(), BytesPerWord);
|
unsigned count = ceiling(c->codeSize() + c->poolSize(), BytesPerWord);
|
||||||
unsigned size = count + singletonMaskSize(count);
|
unsigned size = count + singletonMaskSize(count);
|
||||||
object result = allocate3
|
object result = allocate3
|
||||||
(t, codeAllocator(t), Machine::ImmortalAllocation,
|
(t, codeZone(t), Machine::ImmortalAllocation,
|
||||||
SingletonBody + (size * BytesPerWord), true, true);
|
SingletonBody + (size * BytesPerWord), true);
|
||||||
initSingleton(t, result, size, true);
|
initSingleton(t, result, size, true);
|
||||||
mark(t, result, 0);
|
mark(t, result, 0);
|
||||||
singletonMask(t, result)[0] = 1;
|
singletonMask(t, result)[0] = 1;
|
||||||
@ -4679,6 +4679,27 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
|
|
||||||
class MyProcessor: public Processor {
|
class MyProcessor: public Processor {
|
||||||
public:
|
public:
|
||||||
|
class CodeAllocator: public Allocator {
|
||||||
|
public:
|
||||||
|
CodeAllocator(System* s): s(s) { }
|
||||||
|
|
||||||
|
virtual void* tryAllocate(unsigned size) {
|
||||||
|
return s->tryAllocateExecutable(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* allocate(unsigned size) {
|
||||||
|
void* p = tryAllocate(size);
|
||||||
|
expect(s, p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void free(const void* p, unsigned size) {
|
||||||
|
s->freeExecutable(p, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
System* s;
|
||||||
|
};
|
||||||
|
|
||||||
MyProcessor(System* s, Allocator* allocator):
|
MyProcessor(System* s, Allocator* allocator):
|
||||||
s(s),
|
s(s),
|
||||||
allocator(allocator),
|
allocator(allocator),
|
||||||
@ -4690,13 +4711,14 @@ class MyProcessor: public Processor {
|
|||||||
methodTreeSentinal(0),
|
methodTreeSentinal(0),
|
||||||
indirectCaller(0),
|
indirectCaller(0),
|
||||||
indirectCallerSize(0),
|
indirectCallerSize(0),
|
||||||
codeAllocator(s, allocator, true, 64 * 1024)
|
codeAllocator(s),
|
||||||
|
codeZone(s, &codeAllocator, 64 * 1024)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual Thread*
|
virtual Thread*
|
||||||
makeThread(Machine* m, object javaThread, Thread* parent)
|
makeThread(Machine* m, object javaThread, Thread* parent)
|
||||||
{
|
{
|
||||||
MyThread* t = new (m->heap->allocate(sizeof(MyThread), false))
|
MyThread* t = new (m->heap->allocate(sizeof(MyThread)))
|
||||||
MyThread(m, javaThread, parent);
|
MyThread(m, javaThread, parent);
|
||||||
t->init();
|
t->init();
|
||||||
return t;
|
return t;
|
||||||
@ -4836,7 +4858,7 @@ class MyProcessor: public Processor {
|
|||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
PROTECT(t, o);
|
PROTECT(t, o);
|
||||||
|
|
||||||
Reference* r = new (t->m->heap->allocate(sizeof(Reference), false))
|
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
|
||||||
Reference(o, &(t->reference));
|
Reference(o, &(t->reference));
|
||||||
|
|
||||||
return &(r->target);
|
return &(r->target);
|
||||||
@ -4951,15 +4973,15 @@ class MyProcessor: public Processor {
|
|||||||
vm::dispose(t, t->reference);
|
vm::dispose(t, t->reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
t->m->heap->free(t, sizeof(*t), false);
|
t->m->heap->free(t, sizeof(*t));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
codeAllocator.dispose();
|
codeZone.dispose();
|
||||||
|
|
||||||
s->handleSegFault(0);
|
s->handleSegFault(0);
|
||||||
|
|
||||||
allocator->free(this, sizeof(*this), false);
|
allocator->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object getStackTrace(Thread* vmt, Thread* vmTarget) {
|
virtual object getStackTrace(Thread* vmt, Thread* vmTarget) {
|
||||||
@ -5013,7 +5035,8 @@ class MyProcessor: public Processor {
|
|||||||
uint8_t* indirectCaller;
|
uint8_t* indirectCaller;
|
||||||
unsigned indirectCallerSize;
|
unsigned indirectCallerSize;
|
||||||
SegFaultHandler segFaultHandler;
|
SegFaultHandler segFaultHandler;
|
||||||
Zone codeAllocator;
|
CodeAllocator codeAllocator;
|
||||||
|
Zone codeZone;
|
||||||
};
|
};
|
||||||
|
|
||||||
MyProcessor*
|
MyProcessor*
|
||||||
@ -5040,7 +5063,7 @@ processor(MyThread* t)
|
|||||||
|
|
||||||
p->indirectCallerSize = c->codeSize();
|
p->indirectCallerSize = c->codeSize();
|
||||||
p->indirectCaller = static_cast<uint8_t*>
|
p->indirectCaller = static_cast<uint8_t*>
|
||||||
(p->codeAllocator.allocate(p->indirectCallerSize));
|
(p->codeZone.allocate(p->indirectCallerSize));
|
||||||
c->writeTo(p->indirectCaller);
|
c->writeTo(p->indirectCaller);
|
||||||
|
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
@ -5256,8 +5279,8 @@ methodTreeSentinal(MyThread* t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Allocator*
|
Allocator*
|
||||||
codeAllocator(MyThread* t) {
|
codeZone(MyThread* t) {
|
||||||
return &(processor(t)->codeAllocator);
|
return &(processor(t)->codeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -5267,7 +5290,7 @@ namespace vm {
|
|||||||
Processor*
|
Processor*
|
||||||
makeProcessor(System* system, Allocator* allocator)
|
makeProcessor(System* system, Allocator* allocator)
|
||||||
{
|
{
|
||||||
return new (allocator->allocate(sizeof(MyProcessor), false))
|
return new (allocator->allocate(sizeof(MyProcessor)))
|
||||||
MyProcessor(system, allocator);
|
MyProcessor(system, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,26 +19,19 @@ namespace {
|
|||||||
void*
|
void*
|
||||||
allocate(System* s, unsigned size)
|
allocate(System* s, unsigned size)
|
||||||
{
|
{
|
||||||
void* p = s->tryAllocate(size, false);
|
void* p = s->tryAllocate(size);
|
||||||
if (p == 0) abort();
|
if (p == 0) abort();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
free(System* s, const void* p, unsigned size)
|
|
||||||
{
|
|
||||||
s->free(p, size, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
append(System* s, unsigned* length, const char* a, const char* b,
|
append(System* s, const char* a, const char* b,
|
||||||
const char* c)
|
const char* c)
|
||||||
{
|
{
|
||||||
unsigned al = strlen(a);
|
unsigned al = strlen(a);
|
||||||
unsigned bl = strlen(b);
|
unsigned bl = strlen(b);
|
||||||
unsigned cl = strlen(c);
|
unsigned cl = strlen(c);
|
||||||
*length = al + bl + cl;
|
char* p = static_cast<char*>(allocate(s, (al + bl + cl) + 1));
|
||||||
char* p = static_cast<char*>(allocate(s, *length + 1));
|
|
||||||
memcpy(p, a, al);
|
memcpy(p, a, al);
|
||||||
memcpy(p + al, b, bl);
|
memcpy(p + al, b, bl);
|
||||||
memcpy(p + al + bl, c, cl + 1);
|
memcpy(p + al + bl, c, cl + 1);
|
||||||
@ -46,11 +39,10 @@ append(System* s, unsigned* length, const char* a, const char* b,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
copy(System* s, unsigned* length, const char* a)
|
copy(System* s, const char* a)
|
||||||
{
|
{
|
||||||
unsigned al = strlen(a);
|
unsigned al = strlen(a);
|
||||||
*length = al;
|
char* p = static_cast<char*>(allocate(s, al + 1));
|
||||||
char* p = static_cast<char*>(allocate(s, *length + 1));
|
|
||||||
memcpy(p, a, al + 1);
|
memcpy(p, a, al + 1);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -78,16 +70,15 @@ class Element {
|
|||||||
|
|
||||||
class DirectoryElement: public Element {
|
class DirectoryElement: public Element {
|
||||||
public:
|
public:
|
||||||
DirectoryElement(System* s, const char* name, unsigned nameLength):
|
DirectoryElement(System* s, const char* name):
|
||||||
s(s), name(name), nameLength(nameLength)
|
s(s), name(name)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual System::Region* find(const char* name) {
|
virtual System::Region* find(const char* name) {
|
||||||
unsigned length;
|
const char* file = append(s, this->name, "/", name);
|
||||||
const char* file = append(s, &length, this->name, "/", name);
|
|
||||||
System::Region* region;
|
System::Region* region;
|
||||||
System::Status status = s->map(®ion, file);
|
System::Status status = s->map(®ion, file);
|
||||||
free(s, file, length + 1);
|
s->free(file);
|
||||||
|
|
||||||
if (s->success(status)) {
|
if (s->success(status)) {
|
||||||
return region;
|
return region;
|
||||||
@ -97,21 +88,19 @@ class DirectoryElement: public Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual bool exists(const char* name) {
|
virtual bool exists(const char* name) {
|
||||||
unsigned length;
|
const char* file = append(s, this->name, "/", name);
|
||||||
const char* file = append(s, &length, this->name, "/", name);
|
|
||||||
System::FileType type = s->identify(file);
|
System::FileType type = s->identify(file);
|
||||||
free(s, file, length + 1);
|
s->free(file);
|
||||||
return type != System::DoesNotExist;
|
return type != System::DoesNotExist;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
free(s, name, nameLength + 1);
|
s->free(name);
|
||||||
free(s, this, sizeof(*this));
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned nameLength;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PointerRegion: public System::Region {
|
class PointerRegion: public System::Region {
|
||||||
@ -131,7 +120,7 @@ class PointerRegion: public System::Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
free(s, this, sizeof(*this));
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -155,7 +144,7 @@ class DataRegion: public System::Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
free(s, this, sizeof(*this) + length_);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -376,8 +365,8 @@ class JarIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
free(s, nodes, sizeof(Node) * capacity);
|
s->free(nodes);
|
||||||
free(s, this, sizeof(*this) + (sizeof(Node*) * capacity));
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -390,8 +379,8 @@ class JarIndex {
|
|||||||
|
|
||||||
class JarElement: public Element {
|
class JarElement: public Element {
|
||||||
public:
|
public:
|
||||||
JarElement(System* s, const char* name, unsigned nameLength):
|
JarElement(System* s, const char* name):
|
||||||
s(s), name(name), nameLength(nameLength), index(0)
|
s(s), name(name), index(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
@ -421,29 +410,27 @@ class JarElement: public Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
free(s, name, nameLength + 1);
|
s->free(name);
|
||||||
if (index) {
|
if (index) {
|
||||||
index->dispose();
|
index->dispose();
|
||||||
}
|
}
|
||||||
if (region) {
|
if (region) {
|
||||||
region->dispose();
|
region->dispose();
|
||||||
}
|
}
|
||||||
free(s, this, sizeof(*this));
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned nameLength;
|
|
||||||
System::Region* region;
|
System::Region* region;
|
||||||
JarIndex* index;
|
JarIndex* index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BuiltinElement: public JarElement {
|
class BuiltinElement: public JarElement {
|
||||||
public:
|
public:
|
||||||
BuiltinElement(System* s, const char* name, unsigned nameLength,
|
BuiltinElement(System* s, const char* name, const char* libraryName):
|
||||||
const char* libraryName):
|
JarElement(s, name),
|
||||||
JarElement(s, name, nameLength),
|
libraryName(libraryName ? copy(s, libraryName) : 0)
|
||||||
libraryName(libraryName ? copy(s, &libraryNameLength, libraryName) : 0)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
@ -468,13 +455,12 @@ class BuiltinElement: public JarElement {
|
|||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
library->disposeAll();
|
library->disposeAll();
|
||||||
free(s, libraryName, libraryNameLength + 1);
|
s->free(libraryName);
|
||||||
JarElement::dispose();
|
JarElement::dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
System::Library* library;
|
System::Library* library;
|
||||||
const char* libraryName;
|
const char* libraryName;
|
||||||
unsigned libraryNameLength;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Element*
|
Element*
|
||||||
@ -519,7 +505,7 @@ parsePath(System* s, const char* path, const char* bootLibrary)
|
|||||||
name[token.length - 2] = 0;
|
name[token.length - 2] = 0;
|
||||||
|
|
||||||
e = new (allocate(s, sizeof(BuiltinElement)))
|
e = new (allocate(s, sizeof(BuiltinElement)))
|
||||||
BuiltinElement(s, name, token.length - 2, bootLibrary);
|
BuiltinElement(s, name, bootLibrary);
|
||||||
} else {
|
} else {
|
||||||
char* name = static_cast<char*>(allocate(s, token.length + 1));
|
char* name = static_cast<char*>(allocate(s, token.length + 1));
|
||||||
memcpy(name, token.s, token.length);
|
memcpy(name, token.s, token.length);
|
||||||
@ -527,17 +513,16 @@ parsePath(System* s, const char* path, const char* bootLibrary)
|
|||||||
|
|
||||||
switch (s->identify(name)) {
|
switch (s->identify(name)) {
|
||||||
case System::File: {
|
case System::File: {
|
||||||
e = new (allocate(s, sizeof(JarElement)))
|
e = new (allocate(s, sizeof(JarElement))) JarElement(s, name);
|
||||||
JarElement(s, name, token.length);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case System::Directory: {
|
case System::Directory: {
|
||||||
e = new (allocate(s, sizeof(DirectoryElement)))
|
e = new (allocate(s, sizeof(DirectoryElement)))
|
||||||
DirectoryElement(s, name, token.length);
|
DirectoryElement(s, name);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
free(s, name, token.length + 1);
|
s->free(name);
|
||||||
e = 0;
|
e = 0;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -561,7 +546,7 @@ class MyFinder: public Finder {
|
|||||||
MyFinder(System* system, const char* path, const char* bootLibrary):
|
MyFinder(System* system, const char* path, const char* bootLibrary):
|
||||||
system(system),
|
system(system),
|
||||||
path_(parsePath(system, path, bootLibrary)),
|
path_(parsePath(system, path, bootLibrary)),
|
||||||
pathString(copy(system, &pathStringLength, path))
|
pathString(copy(system, path))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual System::Region* find(const char* name) {
|
virtual System::Region* find(const char* name) {
|
||||||
@ -595,14 +580,13 @@ class MyFinder: public Finder {
|
|||||||
e = e->next;
|
e = e->next;
|
||||||
t->dispose();
|
t->dispose();
|
||||||
}
|
}
|
||||||
free(system, pathString, pathStringLength + 1);
|
system->free(pathString);
|
||||||
free(system, this, sizeof(*this));
|
system->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* system;
|
System* system;
|
||||||
Element* path_;
|
Element* path_;
|
||||||
const char* pathString;
|
const char* pathString;
|
||||||
unsigned pathStringLength;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
49
src/heap.cpp
49
src/heap.cpp
@ -58,8 +58,8 @@ void assert(Context*, bool);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
System* system(Context*);
|
System* system(Context*);
|
||||||
void* tryAllocate(Context* c, unsigned size, bool executable);
|
void* tryAllocate(Context* c, unsigned size);
|
||||||
void free(Context* c, const void* p, unsigned size, bool executable);
|
void free(Context* c, const void* p, unsigned size);
|
||||||
|
|
||||||
inline void*
|
inline void*
|
||||||
get(void* o, unsigned offsetInWords)
|
get(void* o, unsigned offsetInWords)
|
||||||
@ -314,8 +314,7 @@ class Segment {
|
|||||||
capacity_ = desired;
|
capacity_ = desired;
|
||||||
while (data == 0) {
|
while (data == 0) {
|
||||||
data = static_cast<uintptr_t*>
|
data = static_cast<uintptr_t*>
|
||||||
(tryAllocate
|
(tryAllocate(context, (footprint(capacity_)) * BytesPerWord));
|
||||||
(context, (footprint(capacity_)) * BytesPerWord, false));
|
|
||||||
|
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
if (capacity_ > minimum) {
|
if (capacity_ > minimum) {
|
||||||
@ -353,7 +352,7 @@ class Segment {
|
|||||||
|
|
||||||
void replaceWith(Segment* s) {
|
void replaceWith(Segment* s) {
|
||||||
if (data) {
|
if (data) {
|
||||||
free(context, data, (footprint(capacity())) * BytesPerWord, false);
|
free(context, data, (footprint(capacity())) * BytesPerWord);
|
||||||
}
|
}
|
||||||
data = s->data;
|
data = s->data;
|
||||||
s->data = 0;
|
s->data = 0;
|
||||||
@ -404,7 +403,7 @@ class Segment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
free(context, data, (footprint(capacity())) * BytesPerWord, false);
|
free(context, data, (footprint(capacity())) * BytesPerWord);
|
||||||
data = 0;
|
data = 0;
|
||||||
map = 0;
|
map = 0;
|
||||||
}
|
}
|
||||||
@ -783,7 +782,7 @@ free(Context* c, Fixie** fixies)
|
|||||||
if (DebugFixies) {
|
if (DebugFixies) {
|
||||||
fprintf(stderr, "free fixie %p\n", f);
|
fprintf(stderr, "free fixie %p\n", f);
|
||||||
}
|
}
|
||||||
free(c, f, f->totalSize(), false);
|
free(c, f, f->totalSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1628,12 +1627,12 @@ collect(Context* c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* tryAllocate(Context* c, unsigned size, bool executable)
|
void* tryAllocate(Context* c, unsigned size)
|
||||||
{
|
{
|
||||||
ACQUIRE(c->lock);
|
ACQUIRE(c->lock);
|
||||||
|
|
||||||
if (size + c->count < c->limit) {
|
if (size + c->count < c->limit) {
|
||||||
void* p = c->system->tryAllocate(size, executable);
|
void* p = c->system->tryAllocate(size);
|
||||||
if (p) {
|
if (p) {
|
||||||
c->count += size;
|
c->count += size;
|
||||||
return p;
|
return p;
|
||||||
@ -1642,16 +1641,16 @@ void* tryAllocate(Context* c, unsigned size, bool executable)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(Context* c, const void* p, unsigned size, bool executable) {
|
void free(Context* c, const void* p, unsigned size) {
|
||||||
ACQUIRE(c->lock);
|
ACQUIRE(c->lock);
|
||||||
|
|
||||||
expect(c->system, c->count >= size);
|
expect(c->system, c->count >= size);
|
||||||
c->system->free(p, size, executable);
|
c->system->free(p);
|
||||||
c->count -= size;
|
c->count -= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(Context* c, const void* p, unsigned size, bool executable) {
|
void free_(Context* c, const void* p, unsigned size) {
|
||||||
free(c, p, size, executable);
|
free(c, p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyHeap: public Heap {
|
class MyHeap: public Heap {
|
||||||
@ -1665,18 +1664,18 @@ class MyHeap: public Heap {
|
|||||||
c.client = client;
|
c.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned size, bool executable) {
|
virtual void* tryAllocate(unsigned size) {
|
||||||
return ::tryAllocate(&c, size, executable);
|
return ::tryAllocate(&c, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* allocate(unsigned size, bool executable) {
|
virtual void* allocate(unsigned size) {
|
||||||
void* p = ::tryAllocate(&c, size, executable);
|
void* p = ::tryAllocate(&c, size);
|
||||||
expect(c.system, p);
|
expect(c.system, p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void free(const void* p, unsigned size, bool executable) {
|
virtual void free(const void* p, unsigned size) {
|
||||||
free_(&c, p, size, executable);
|
free_(&c, p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void collect(CollectionType type, unsigned incomingFootprint) {
|
virtual void collect(CollectionType type, unsigned incomingFootprint) {
|
||||||
@ -1690,16 +1689,15 @@ class MyHeap: public Heap {
|
|||||||
bool objectMask, unsigned* totalInBytes)
|
bool objectMask, unsigned* totalInBytes)
|
||||||
{
|
{
|
||||||
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
||||||
return (new (allocator->allocate(*totalInBytes, false))
|
return (new (allocator->allocate(*totalInBytes))
|
||||||
Fixie(sizeInWords, objectMask, &(c.fixies), false))->body();
|
Fixie(sizeInWords, objectMask, &(c.fixies), false))->body();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords,
|
virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords,
|
||||||
bool executable, bool objectMask,
|
bool objectMask, unsigned* totalInBytes)
|
||||||
unsigned* totalInBytes)
|
|
||||||
{
|
{
|
||||||
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
||||||
return (new (allocator->allocate(*totalInBytes, executable))
|
return (new (allocator->allocate(*totalInBytes))
|
||||||
Fixie(sizeInWords, objectMask, &(c.tenuredFixies), true))->body();
|
Fixie(sizeInWords, objectMask, &(c.tenuredFixies), true))->body();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1809,7 +1807,7 @@ class MyHeap: public Heap {
|
|||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
c.dispose();
|
c.dispose();
|
||||||
assert(&c, c.count == 0);
|
assert(&c, c.count == 0);
|
||||||
c.system->free(this, sizeof(*this), false);
|
c.system->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context c;
|
Context c;
|
||||||
@ -1822,8 +1820,7 @@ namespace vm {
|
|||||||
Heap*
|
Heap*
|
||||||
makeHeap(System* system, unsigned limit)
|
makeHeap(System* system, unsigned limit)
|
||||||
{
|
{
|
||||||
return new (system->tryAllocate(sizeof(MyHeap), false))
|
return new (system->tryAllocate(sizeof(MyHeap))) MyHeap(system, limit);
|
||||||
MyHeap(system, limit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -60,8 +60,7 @@ class Heap: public Allocator {
|
|||||||
virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords,
|
virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||||
bool objectMask, unsigned* totalInBytes) = 0;
|
bool objectMask, unsigned* totalInBytes) = 0;
|
||||||
virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords,
|
virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords,
|
||||||
bool executable, bool objectMask,
|
bool objectMask, unsigned* totalInBytes) = 0;
|
||||||
unsigned* totalInBytes) = 0;
|
|
||||||
virtual bool needsMark(void* p) = 0;
|
virtual bool needsMark(void* p) = 0;
|
||||||
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
||||||
virtual void pad(void* p) = 0;
|
virtual void pad(void* p) = 0;
|
||||||
|
@ -101,7 +101,7 @@ GetStringChars(Thread* t, jstring s, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
jchar* chars = static_cast<jchar*>
|
jchar* chars = static_cast<jchar*>
|
||||||
(t->m->heap->allocate((stringLength(t, *s) + 1) * sizeof(jchar), false));
|
(t->m->heap->allocate((stringLength(t, *s) + 1) * sizeof(jchar)));
|
||||||
stringChars(t, *s, chars);
|
stringChars(t, *s, chars);
|
||||||
|
|
||||||
if (isCopy) *isCopy = true;
|
if (isCopy) *isCopy = true;
|
||||||
@ -113,7 +113,7 @@ ReleaseStringChars(Thread* t, jstring s, const jchar* chars)
|
|||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
t->m->heap->free(chars, (stringLength(t, *s) + 1) * sizeof(jchar), false);
|
t->m->heap->free(chars, (stringLength(t, *s) + 1) * sizeof(jchar));
|
||||||
}
|
}
|
||||||
|
|
||||||
jsize JNICALL
|
jsize JNICALL
|
||||||
@ -130,7 +130,7 @@ GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
char* chars = static_cast<char*>
|
char* chars = static_cast<char*>
|
||||||
(t->m->heap->allocate(stringLength(t, *s) + 1, false));
|
(t->m->heap->allocate(stringLength(t, *s) + 1));
|
||||||
stringChars(t, *s, chars);
|
stringChars(t, *s, chars);
|
||||||
|
|
||||||
if (isCopy) *isCopy = true;
|
if (isCopy) *isCopy = true;
|
||||||
@ -142,7 +142,7 @@ ReleaseStringUTFChars(Thread* t, jstring s, const char* chars)
|
|||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
t->m->heap->free(chars, stringLength(t, *s) + 1, false);
|
t->m->heap->free(chars, stringLength(t, *s) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
jsize JNICALL
|
jsize JNICALL
|
||||||
@ -1177,7 +1177,7 @@ NewGlobalRef(Thread* t, jobject o)
|
|||||||
ACQUIRE(t, t->m->referenceLock);
|
ACQUIRE(t, t->m->referenceLock);
|
||||||
|
|
||||||
if (o) {
|
if (o) {
|
||||||
Reference* r = new (t->m->heap->allocate(sizeof(Reference), false))
|
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
|
||||||
Reference(*o, &(t->m->jniReferences));
|
Reference(*o, &(t->m->jniReferences));
|
||||||
|
|
||||||
return &(r->target);
|
return &(r->target);
|
||||||
@ -1322,7 +1322,7 @@ GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
|
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
|
||||||
jboolean* p = static_cast<jboolean*>(t->m->heap->allocate(size, false));
|
jboolean* p = static_cast<jboolean*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &booleanArrayBody(t, *array, 0), size);
|
memcpy(p, &booleanArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1340,7 +1340,7 @@ GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
|
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
|
||||||
jbyte* p = static_cast<jbyte*>(t->m->heap->allocate(size, false));
|
jbyte* p = static_cast<jbyte*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &byteArrayBody(t, *array, 0), size);
|
memcpy(p, &byteArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1358,7 +1358,7 @@ GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
|
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
|
||||||
jchar* p = static_cast<jchar*>(t->m->heap->allocate(size, false));
|
jchar* p = static_cast<jchar*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &charArrayBody(t, *array, 0), size);
|
memcpy(p, &charArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1376,7 +1376,7 @@ GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
|
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
|
||||||
jshort* p = static_cast<jshort*>(t->m->heap->allocate(size, false));
|
jshort* p = static_cast<jshort*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &shortArrayBody(t, *array, 0), size);
|
memcpy(p, &shortArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1394,7 +1394,7 @@ GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = intArrayLength(t, *array) * sizeof(jint);
|
unsigned size = intArrayLength(t, *array) * sizeof(jint);
|
||||||
jint* p = static_cast<jint*>(t->m->heap->allocate(size, false));
|
jint* p = static_cast<jint*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &intArrayBody(t, *array, 0), size);
|
memcpy(p, &intArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1412,7 +1412,7 @@ GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
|
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
|
||||||
jlong* p = static_cast<jlong*>(t->m->heap->allocate(size, false));
|
jlong* p = static_cast<jlong*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &longArrayBody(t, *array, 0), size);
|
memcpy(p, &longArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1430,7 +1430,7 @@ GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
|
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
|
||||||
jfloat* p = static_cast<jfloat*>(t->m->heap->allocate(size, false));
|
jfloat* p = static_cast<jfloat*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &floatArrayBody(t, *array, 0), size);
|
memcpy(p, &floatArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1448,7 +1448,7 @@ GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
|
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
|
||||||
jdouble* p = static_cast<jdouble*>(t->m->heap->allocate(size, false));
|
jdouble* p = static_cast<jdouble*>(t->m->heap->allocate(size));
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy(p, &doubleArrayBody(t, *array, 0), size);
|
memcpy(p, &doubleArrayBody(t, *array, 0), size);
|
||||||
}
|
}
|
||||||
@ -1475,7 +1475,7 @@ ReleaseBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1493,7 +1493,7 @@ ReleaseByteArrayElements(Thread* t, jbyteArray array, jbyte* p, jint mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1511,7 +1511,7 @@ ReleaseCharArrayElements(Thread* t, jcharArray array, jchar* p, jint mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1529,7 +1529,7 @@ ReleaseShortArrayElements(Thread* t, jshortArray array, jshort* p, jint mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1547,7 +1547,7 @@ ReleaseIntArrayElements(Thread* t, jintArray array, jint* p, jint mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1565,7 +1565,7 @@ ReleaseLongArrayElements(Thread* t, jlongArray array, jlong* p, jint mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1583,7 +1583,7 @@ ReleaseFloatArrayElements(Thread* t, jfloatArray array, jfloat* p, jint mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1602,7 +1602,7 @@ ReleaseDoubleArrayElements(Thread* t, jdoubleArray array, jdouble* p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 0 or mode == JNI_ABORT) {
|
if (mode == 0 or mode == JNI_ABORT) {
|
||||||
t->m->heap->free(p, size, false);
|
t->m->heap->free(p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2079,7 +2079,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
|||||||
Finder* f = makeFinder(s, a->classpath, bootLibrary);
|
Finder* f = makeFinder(s, a->classpath, bootLibrary);
|
||||||
Processor* p = makeProcessor(s, h);
|
Processor* p = makeProcessor(s, h);
|
||||||
|
|
||||||
*m = new (h->allocate(sizeof(Machine), false))
|
*m = new (h->allocate(sizeof(Machine)))
|
||||||
Machine(s, h, f, p, bootLibrary, builtins);
|
Machine(s, h, f, p, bootLibrary, builtins);
|
||||||
|
|
||||||
*t = p->makeThread(*m, 0, 0);
|
*t = p->makeThread(*m, 0, 0);
|
||||||
|
@ -478,9 +478,9 @@ void
|
|||||||
postCollect(Thread* t)
|
postCollect(Thread* t)
|
||||||
{
|
{
|
||||||
#ifdef VM_STRESS
|
#ifdef VM_STRESS
|
||||||
t->m->heap->free(t->defaultHeap, Thread::HeapSizeInBytes, false);
|
t->m->heap->free(t->defaultHeap, Thread::HeapSizeInBytes);
|
||||||
t->defaultHeap = static_cast<uintptr_t*>
|
t->defaultHeap = static_cast<uintptr_t*>
|
||||||
(t->m->heap->allocate(Thread::HeapSizeInBytes, false));
|
(t->m->heap->allocate(Thread::HeapSizeInBytes));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
t->heap = t->defaultHeap;
|
t->heap = t->defaultHeap;
|
||||||
@ -489,7 +489,7 @@ postCollect(Thread* t)
|
|||||||
|
|
||||||
if (t->backupHeap) {
|
if (t->backupHeap) {
|
||||||
t->m->heap->free
|
t->m->heap->free
|
||||||
(t->backupHeap, t->backupHeapSizeInWords * BytesPerWord, false);
|
(t->backupHeap, t->backupHeapSizeInWords * BytesPerWord);
|
||||||
t->backupHeapIndex = 0;
|
t->backupHeapIndex = 0;
|
||||||
t->backupHeapSizeInWords = 0;
|
t->backupHeapSizeInWords = 0;
|
||||||
}
|
}
|
||||||
@ -653,8 +653,7 @@ parsePool(Thread* t, Stream& s)
|
|||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
uint32_t* index = static_cast<uint32_t*>
|
uint32_t* index = static_cast<uint32_t*>(t->m->heap->allocate(count * 4));
|
||||||
(t->m->heap->allocate(count * 4, false));
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
index[i] = s.position();
|
index[i] = s.position();
|
||||||
@ -700,7 +699,7 @@ parsePool(Thread* t, Stream& s)
|
|||||||
i += parsePoolEntry(t, s, index, pool, i);
|
i += parsePoolEntry(t, s, index, pool, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
t->m->heap->free(index, count * 4, false);
|
t->m->heap->free(index, count * 4);
|
||||||
|
|
||||||
s.setPosition(end);
|
s.setPosition(end);
|
||||||
}
|
}
|
||||||
@ -1625,7 +1624,7 @@ class HeapClient: public Heap::Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
m->heap->free(this, sizeof(*this), false);
|
m->heap->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1641,7 +1640,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
|||||||
const char* builtins):
|
const char* builtins):
|
||||||
vtable(&javaVMVTable),
|
vtable(&javaVMVTable),
|
||||||
system(system),
|
system(system),
|
||||||
heapClient(new (heap->allocate(sizeof(HeapClient), false))
|
heapClient(new (heap->allocate(sizeof(HeapClient)))
|
||||||
HeapClient(this)),
|
HeapClient(this)),
|
||||||
heap(heap),
|
heap(heap),
|
||||||
finder(finder),
|
finder(finder),
|
||||||
@ -1704,16 +1703,16 @@ Machine::dispose()
|
|||||||
for (Reference* r = jniReferences; r;) {
|
for (Reference* r = jniReferences; r;) {
|
||||||
Reference* tmp = r;
|
Reference* tmp = r;
|
||||||
r = r->next;
|
r = r->next;
|
||||||
heap->free(tmp, sizeof(*tmp), false);
|
heap->free(tmp, sizeof(*tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < heapPoolIndex; ++i) {
|
for (unsigned i = 0; i < heapPoolIndex; ++i) {
|
||||||
heap->free(heapPool[i], Thread::HeapSizeInBytes, false);
|
heap->free(heapPool[i], Thread::HeapSizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static_cast<HeapClient*>(heapClient)->dispose();
|
static_cast<HeapClient*>(heapClient)->dispose();
|
||||||
|
|
||||||
heap->free(this, sizeof(*this), false);
|
heap->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
||||||
@ -1732,7 +1731,7 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
protector(0),
|
protector(0),
|
||||||
runnable(this),
|
runnable(this),
|
||||||
defaultHeap(static_cast<uintptr_t*>
|
defaultHeap(static_cast<uintptr_t*>
|
||||||
(m->heap->allocate(HeapSizeInBytes, false))),
|
(m->heap->allocate(HeapSizeInBytes))),
|
||||||
heap(defaultHeap),
|
heap(defaultHeap),
|
||||||
backupHeap(0),
|
backupHeap(0),
|
||||||
backupHeapIndex(0),
|
backupHeapIndex(0),
|
||||||
@ -1872,7 +1871,7 @@ Thread::dispose()
|
|||||||
systemThread->dispose();
|
systemThread->dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
m->heap->free(defaultHeap, Thread::HeapSizeInBytes, false);
|
m->heap->free(defaultHeap, Thread::HeapSizeInBytes);
|
||||||
|
|
||||||
m->processor->dispose(this);
|
m->processor->dispose(this);
|
||||||
}
|
}
|
||||||
@ -2032,12 +2031,12 @@ allocate2(Thread* t, unsigned sizeInBytes, bool objectMask)
|
|||||||
(t, t->m->heap,
|
(t, t->m->heap,
|
||||||
ceiling(sizeInBytes, BytesPerWord) > Thread::HeapSizeInWords ?
|
ceiling(sizeInBytes, BytesPerWord) > Thread::HeapSizeInWords ?
|
||||||
Machine::FixedAllocation : Machine::MovableAllocation,
|
Machine::FixedAllocation : Machine::MovableAllocation,
|
||||||
sizeInBytes, false, objectMask);
|
sizeInBytes, objectMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
||||||
unsigned sizeInBytes, bool executable, bool objectMask)
|
unsigned sizeInBytes, bool objectMask)
|
||||||
{
|
{
|
||||||
if (t->backupHeap) {
|
if (t->backupHeap) {
|
||||||
expect(t, t->backupHeapIndex + ceiling(sizeInBytes, BytesPerWord)
|
expect(t, t->backupHeapIndex + ceiling(sizeInBytes, BytesPerWord)
|
||||||
@ -2069,7 +2068,7 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
|||||||
t->heap = 0;
|
t->heap = 0;
|
||||||
if (t->m->heapPoolIndex < Machine::HeapPoolSize) {
|
if (t->m->heapPoolIndex < Machine::HeapPoolSize) {
|
||||||
t->heap = static_cast<uintptr_t*>
|
t->heap = static_cast<uintptr_t*>
|
||||||
(t->m->heap->tryAllocate(Thread::HeapSizeInBytes, false));
|
(t->m->heap->tryAllocate(Thread::HeapSizeInBytes));
|
||||||
if (t->heap) {
|
if (t->heap) {
|
||||||
t->m->heapPool[t->m->heapPoolIndex++] = t->heap;
|
t->m->heapPool[t->m->heapPoolIndex++] = t->heap;
|
||||||
t->heapOffset += t->heapIndex;
|
t->heapOffset += t->heapIndex;
|
||||||
@ -2107,8 +2106,7 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
|||||||
unsigned total;
|
unsigned total;
|
||||||
object o = static_cast<object>
|
object o = static_cast<object>
|
||||||
(t->m->heap->allocateImmortal
|
(t->m->heap->allocateImmortal
|
||||||
(allocator, ceiling(sizeInBytes, BytesPerWord),
|
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
||||||
executable, objectMask, &total));
|
|
||||||
|
|
||||||
cast<uintptr_t>(o, 0) = FixedMark;
|
cast<uintptr_t>(o, 0) = FixedMark;
|
||||||
|
|
||||||
@ -2754,7 +2752,7 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
killZombies(t, m->rootThread);
|
killZombies(t, m->rootThread);
|
||||||
|
|
||||||
for (unsigned i = 0; i < m->heapPoolIndex; ++i) {
|
for (unsigned i = 0; i < m->heapPoolIndex; ++i) {
|
||||||
m->heap->free(m->heapPool[i], Thread::HeapSizeInBytes, false);
|
m->heap->free(m->heapPool[i], Thread::HeapSizeInBytes);
|
||||||
}
|
}
|
||||||
m->heapPoolIndex = 0;
|
m->heapPoolIndex = 0;
|
||||||
|
|
||||||
|
@ -1331,7 +1331,7 @@ dispose(Thread* t, Reference* r)
|
|||||||
if (r->next) {
|
if (r->next) {
|
||||||
r->next->handle = r->handle;
|
r->next->handle = r->handle;
|
||||||
}
|
}
|
||||||
t->m->heap->free(r, sizeof(*r), false);
|
t->m->heap->free(r, sizeof(*r));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1437,7 +1437,7 @@ ensure(Thread* t, unsigned sizeInBytes)
|
|||||||
{
|
{
|
||||||
expect(t, t->backupHeap == 0);
|
expect(t, t->backupHeap == 0);
|
||||||
t->backupHeap = static_cast<uintptr_t*>
|
t->backupHeap = static_cast<uintptr_t*>
|
||||||
(t->m->heap->allocate(pad(sizeInBytes), false));
|
(t->m->heap->allocate(pad(sizeInBytes)));
|
||||||
t->backupHeapIndex = 0;
|
t->backupHeapIndex = 0;
|
||||||
t->backupHeapSizeInWords = ceiling(sizeInBytes, BytesPerWord);
|
t->backupHeapSizeInWords = ceiling(sizeInBytes, BytesPerWord);
|
||||||
}
|
}
|
||||||
@ -1448,7 +1448,7 @@ allocate2(Thread* t, unsigned sizeInBytes, bool objectMask);
|
|||||||
|
|
||||||
object
|
object
|
||||||
allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
||||||
unsigned sizeInBytes, bool executable, bool objectMask);
|
unsigned sizeInBytes, bool objectMask);
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
allocateSmall(Thread* t, unsigned sizeInBytes)
|
allocateSmall(Thread* t, unsigned sizeInBytes)
|
||||||
|
@ -105,7 +105,7 @@ run(void* r)
|
|||||||
void*
|
void*
|
||||||
allocate(System* s, unsigned size)
|
allocate(System* s, unsigned size)
|
||||||
{
|
{
|
||||||
void* p = s->tryAllocate(size, false);
|
void* p = s->tryAllocate(size);
|
||||||
if (p == 0) abort();
|
if (p == 0) abort();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
@ -195,7 +195,7 @@ class MySystem: public System {
|
|||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -394,7 +394,7 @@ class MySystem: public System {
|
|||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
expect(s, owner_ == 0);
|
expect(s, owner_ == 0);
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -425,7 +425,7 @@ class MySystem: public System {
|
|||||||
int r UNUSED = pthread_key_delete(key);
|
int r UNUSED = pthread_key_delete(key);
|
||||||
expect(s, r == 0);
|
expect(s, r == 0);
|
||||||
|
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -452,7 +452,7 @@ class MySystem: public System {
|
|||||||
if (start_) {
|
if (start_) {
|
||||||
munmap(start_, length_);
|
munmap(start_, length_);
|
||||||
}
|
}
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -505,10 +505,10 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name_) {
|
if (name_) {
|
||||||
s->free(name_, nameLength + 1, false);
|
s->free(name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -549,36 +549,32 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned size, bool executable) {
|
virtual void* tryAllocate(unsigned sizeInBytes) {
|
||||||
assert(this, (not executable) or (size % LikelyPageSizeInBytes == 0));
|
return malloc(sizeInBytes);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MAP_32BIT
|
virtual void free(const void* p) {
|
||||||
#define MAP_32BIT 0
|
if (p) ::free(const_cast<void*>(p));
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (executable) {
|
virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
|
||||||
void* p = mmap(0, size, PROT_EXEC | PROT_READ | PROT_WRITE,
|
assert(this, sizeInBytes % LikelyPageSizeInBytes == 0);
|
||||||
MAP_PRIVATE | MAP_ANON | MAP_32BIT, -1, 0);
|
|
||||||
|
|
||||||
if (p == MAP_FAILED) {
|
void* p = mmap(0, sizeInBytes, PROT_EXEC | PROT_READ | PROT_WRITE,
|
||||||
return 0;
|
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
} else {
|
|
||||||
return p;
|
if (p == MAP_FAILED) {
|
||||||
}
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return malloc(size);
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void free(const void* p, unsigned size, bool executable) {
|
virtual void freeExecutable(const void* p, unsigned sizeInBytes) {
|
||||||
if (p) {
|
assert(this, sizeInBytes % LikelyPageSizeInBytes == 0);
|
||||||
if (executable) {
|
|
||||||
int r UNUSED = munmap(const_cast<void*>(p), size);
|
int r UNUSED = munmap(const_cast<void*>(p), sizeInBytes);
|
||||||
assert(this, r == 0);
|
assert(this, r == 0);
|
||||||
} else {
|
|
||||||
::free(const_cast<void*>(p));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool success(Status s) {
|
virtual bool success(Status s) {
|
||||||
@ -719,7 +715,7 @@ class MySystem: public System {
|
|||||||
n = static_cast<char*>(allocate(this, nameLength + 1));
|
n = static_cast<char*>(allocate(this, nameLength + 1));
|
||||||
memcpy(n, name, nameLength + 1);
|
memcpy(n, name, nameLength + 1);
|
||||||
if (alreadyAllocated) {
|
if (alreadyAllocated) {
|
||||||
free(name, nameLength, false);
|
free(name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n = 0;
|
n = 0;
|
||||||
|
@ -123,8 +123,10 @@ class System {
|
|||||||
virtual ~System() { }
|
virtual ~System() { }
|
||||||
|
|
||||||
virtual bool success(Status) = 0;
|
virtual bool success(Status) = 0;
|
||||||
virtual void* tryAllocate(unsigned size, bool executable) = 0;
|
virtual void* tryAllocate(unsigned sizeInBytes) = 0;
|
||||||
virtual void free(const void* p, unsigned size, bool executable) = 0;
|
virtual void free(const void* p) = 0;
|
||||||
|
virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0;
|
||||||
|
virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0;
|
||||||
virtual Status attach(Runnable*) = 0;
|
virtual Status attach(Runnable*) = 0;
|
||||||
virtual Status start(Runnable*) = 0;
|
virtual Status start(Runnable*) = 0;
|
||||||
virtual Status make(Mutex**) = 0;
|
virtual Status make(Mutex**) = 0;
|
||||||
|
@ -32,7 +32,7 @@ class Vector {
|
|||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (data and minimumCapacity >= 0) {
|
if (data and minimumCapacity >= 0) {
|
||||||
allocator->free(data, capacity, false);
|
allocator->free(data, capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,10 +52,10 @@ class Vector {
|
|||||||
unsigned newCapacity = max
|
unsigned newCapacity = max
|
||||||
(position + space, max(minimumCapacity, capacity * 2));
|
(position + space, max(minimumCapacity, capacity * 2));
|
||||||
uint8_t* newData = static_cast<uint8_t*>
|
uint8_t* newData = static_cast<uint8_t*>
|
||||||
(allocator->allocate(newCapacity, false));
|
(allocator->allocate(newCapacity));
|
||||||
if (data) {
|
if (data) {
|
||||||
memcpy(newData, data, position);
|
memcpy(newData, data, position);
|
||||||
allocator->free(data, capacity, false);
|
allocator->free(data, capacity);
|
||||||
}
|
}
|
||||||
data = newData;
|
data = newData;
|
||||||
capacity = newCapacity;
|
capacity = newCapacity;
|
||||||
|
@ -70,7 +70,7 @@ run(void* r)
|
|||||||
void*
|
void*
|
||||||
allocate(System* s, unsigned size)
|
allocate(System* s, unsigned size)
|
||||||
{
|
{
|
||||||
void* p = s->tryAllocate(size, false);
|
void* p = s->tryAllocate(size);
|
||||||
if (p == 0) abort();
|
if (p == 0) abort();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ class MySystem: public System {
|
|||||||
CloseHandle(event);
|
CloseHandle(event);
|
||||||
CloseHandle(mutex);
|
CloseHandle(mutex);
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
@ -148,7 +148,7 @@ class MySystem: public System {
|
|||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
CloseHandle(mutex);
|
CloseHandle(mutex);
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -362,7 +362,7 @@ class MySystem: public System {
|
|||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
assert(s, owner_ == 0);
|
assert(s, owner_ == 0);
|
||||||
CloseHandle(mutex);
|
CloseHandle(mutex);
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -393,7 +393,7 @@ class MySystem: public System {
|
|||||||
bool r UNUSED = TlsFree(key);
|
bool r UNUSED = TlsFree(key);
|
||||||
assert(s, r);
|
assert(s, r);
|
||||||
|
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -425,7 +425,7 @@ class MySystem: public System {
|
|||||||
if (mapping) CloseHandle(mapping);
|
if (mapping) CloseHandle(mapping);
|
||||||
if (file) CloseHandle(file);
|
if (file) CloseHandle(file);
|
||||||
}
|
}
|
||||||
system->free(this, sizeof(*this), false);
|
system->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* system;
|
System* system;
|
||||||
@ -437,12 +437,10 @@ class MySystem: public System {
|
|||||||
|
|
||||||
class Library: public System::Library {
|
class Library: public System::Library {
|
||||||
public:
|
public:
|
||||||
Library(System* s, HMODULE handle, const char* name, size_t nameLength,
|
Library(System* s, HMODULE handle, const char* name, bool mapName):
|
||||||
bool mapName):
|
|
||||||
s(s),
|
s(s),
|
||||||
handle(handle),
|
handle(handle),
|
||||||
name_(name),
|
name_(name),
|
||||||
nameLength(nameLength),
|
|
||||||
mapName_(mapName),
|
mapName_(mapName),
|
||||||
next_(0)
|
next_(0)
|
||||||
{ }
|
{ }
|
||||||
@ -484,16 +482,15 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name_) {
|
if (name_) {
|
||||||
s->free(name_, nameLength + 1, false);
|
s->free(name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->free(this, sizeof(*this), false);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
HMODULE handle;
|
HMODULE handle;
|
||||||
const char* name_;
|
const char* name_;
|
||||||
size_t nameLength;
|
|
||||||
bool mapName_;
|
bool mapName_;
|
||||||
System::Library* next_;
|
System::Library* next_;
|
||||||
};
|
};
|
||||||
@ -503,14 +500,25 @@ class MySystem: public System {
|
|||||||
assert(this, mutex);
|
assert(this, mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned size, bool) {
|
virtual void* tryAllocate(unsigned sizeInBytes) {
|
||||||
return malloc(size);
|
return malloc(sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void free(const void* p, unsigned, bool) {
|
virtual void free(const void* p) {
|
||||||
if (p) ::free(const_cast<void*>(p));
|
if (p) ::free(const_cast<void*>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
|
||||||
|
assert(this, sizeInBytes % LikelyPageSizeInBytes == 0);
|
||||||
|
|
||||||
|
return VirtualAlloc(0, sizeInBytes, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void freeExecutable(const void* p, unsigned) {
|
||||||
|
int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE);
|
||||||
|
assert(this, r);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool success(Status s) {
|
virtual bool success(Status s) {
|
||||||
return s == 0;
|
return s == 0;
|
||||||
}
|
}
|
||||||
@ -674,7 +682,7 @@ class MySystem: public System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*lib = new (allocate(this, sizeof(Library)))
|
*lib = new (allocate(this, sizeof(Library)))
|
||||||
Library(this, handle, n, nameLength, mapName);
|
Library(this, handle, n, mapName);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
31
src/zone.h
31
src/zone.h
@ -27,11 +27,9 @@ class Zone: public Allocator {
|
|||||||
uint8_t data[0];
|
uint8_t data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
Zone(System* s, Allocator* allocator, bool executable,
|
Zone(System* s, Allocator* allocator, unsigned minimumFootprint):
|
||||||
unsigned minimumFootprint):
|
|
||||||
s(s),
|
s(s),
|
||||||
allocator(allocator),
|
allocator(allocator),
|
||||||
executable(executable),
|
|
||||||
segment(0),
|
segment(0),
|
||||||
position(0),
|
position(0),
|
||||||
minimumFootprint(minimumFootprint < sizeof(Segment) ? 0 :
|
minimumFootprint(minimumFootprint < sizeof(Segment) ? 0 :
|
||||||
@ -45,11 +43,11 @@ class Zone: public Allocator {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
for (Segment* seg = segment, *next; seg; seg = next) {
|
for (Segment* seg = segment, *next; seg; seg = next) {
|
||||||
next = seg->next;
|
next = seg->next;
|
||||||
allocator->free(seg, sizeof(Segment) + seg->size, executable);
|
allocator->free(seg, sizeof(Segment) + seg->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ensure(unsigned space, bool executable) {
|
bool ensure(unsigned space) {
|
||||||
if (segment == 0 or position + space > segment->size) {
|
if (segment == 0 or position + space > segment->size) {
|
||||||
unsigned size = max
|
unsigned size = max
|
||||||
(space, max
|
(space, max
|
||||||
@ -60,10 +58,10 @@ class Zone: public Allocator {
|
|||||||
size = (size + (LikelyPageSizeInBytes - 1))
|
size = (size + (LikelyPageSizeInBytes - 1))
|
||||||
& ~(LikelyPageSizeInBytes - 1);
|
& ~(LikelyPageSizeInBytes - 1);
|
||||||
|
|
||||||
void* p = allocator->tryAllocate(size, executable);
|
void* p = allocator->tryAllocate(size);
|
||||||
if (p == 0) {
|
if (p == 0) {
|
||||||
size = space + sizeof(Segment);
|
size = space + sizeof(Segment);
|
||||||
void* p = allocator->tryAllocate(size, executable);
|
void* p = allocator->tryAllocate(size);
|
||||||
if (p == 0) {
|
if (p == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,11 +73,9 @@ class Zone: public Allocator {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned size, bool executable) {
|
virtual void* tryAllocate(unsigned size) {
|
||||||
assert(s, executable == this->executable);
|
|
||||||
|
|
||||||
size = pad(size);
|
size = pad(size);
|
||||||
if (ensure(size, executable)) {
|
if (ensure(size)) {
|
||||||
void* r = segment->data + position;
|
void* r = segment->data + position;
|
||||||
position += size;
|
position += size;
|
||||||
return r;
|
return r;
|
||||||
@ -88,27 +84,20 @@ class Zone: public Allocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* allocate(unsigned size, bool executable) {
|
virtual void* allocate(unsigned size) {
|
||||||
assert(s, executable == this->executable);
|
void* p = tryAllocate(size);
|
||||||
|
|
||||||
void* p = tryAllocate(size, executable);
|
|
||||||
expect(s, p);
|
expect(s, p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void free(const void*, unsigned, bool) {
|
virtual void free(const void*, unsigned) {
|
||||||
// not supported
|
// not supported
|
||||||
abort(s);
|
abort(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* allocate(unsigned size) {
|
|
||||||
return allocate(size, executable);
|
|
||||||
}
|
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
Allocator* allocator;
|
Allocator* allocator;
|
||||||
void* context;
|
void* context;
|
||||||
bool executable;
|
|
||||||
Segment* segment;
|
Segment* segment;
|
||||||
unsigned position;
|
unsigned position;
|
||||||
unsigned minimumFootprint;
|
unsigned minimumFootprint;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user