mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
more JIT progress
This commit is contained in:
parent
6b1f01511b
commit
286f290665
107
src/compile.cpp
107
src/compile.cpp
@ -181,7 +181,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
if (nativeMethod) {
|
||||
return 0;
|
||||
} else {
|
||||
return treeNodeKey(t, node);
|
||||
return traceNodeAddress(t, node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -606,7 +606,7 @@ class Frame {
|
||||
assert(t, sp - 2 >= localSize(t, method));
|
||||
assert(t, getBit(map, sp - 1) == 0);
|
||||
assert(t, getBit(map, sp - 2) == 0);
|
||||
return c->stack2(1);
|
||||
return c->stack(1);
|
||||
}
|
||||
|
||||
Operand* topObject() {
|
||||
@ -2743,11 +2743,9 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
||||
for (unsigned i = 0; i < objectPool->length(); i += sizeof(PoolElement)) {
|
||||
PoolElement* e = objectPool->peek<PoolElement>(i);
|
||||
|
||||
singletonMarkObject
|
||||
(t, result, e->offset->value(t->m->system) / BytesPerWord);
|
||||
singletonMarkObject(t, result, e->offset->value(c) / BytesPerWord);
|
||||
|
||||
set(t, result, SingletonBody + e->offset->value(t->m->system),
|
||||
e->value);
|
||||
set(t, result, SingletonBody + e->offset->value(c), e->value);
|
||||
}
|
||||
|
||||
unsigned traceSize = Frame::traceSizeInBytes(t, method);
|
||||
@ -2756,8 +2754,8 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
||||
TraceElement* e = traceLog->peek<TraceElement>(i);
|
||||
|
||||
object node = makeTraceNode
|
||||
(t, reinterpret_cast<intptr_t>(start + e->offset->value(t->m->system)),
|
||||
0, 0, 0, method, e->target, e->virtualCall, mapSize / BytesPerWord,
|
||||
(t, reinterpret_cast<intptr_t>(start + e->offset->value(c)),
|
||||
0, method, e->target, e->virtualCall, mapSize / BytesPerWord,
|
||||
false);
|
||||
|
||||
if (mapSize) {
|
||||
@ -2784,13 +2782,16 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
||||
(t, newTable, i);
|
||||
|
||||
exceptionHandlerStart(newHandler)
|
||||
= c->logicalIpToOffset(exceptionHandlerStart(oldHandler));
|
||||
= c->logicalIpToOffset(exceptionHandlerStart(oldHandler))
|
||||
->value(c);
|
||||
|
||||
exceptionHandlerEnd(newHandler)
|
||||
= c->logicalIpToOffset(exceptionHandlerEnd(oldHandler));
|
||||
= c->logicalIpToOffset(exceptionHandlerEnd(oldHandler))
|
||||
->value(c);
|
||||
|
||||
exceptionHandlerIp(newHandler)
|
||||
= c->logicalIpToOffset(exceptionHandlerIp(oldHandler));
|
||||
= c->logicalIpToOffset(exceptionHandlerIp(oldHandler))
|
||||
->value(c);
|
||||
|
||||
exceptionHandlerCatchType(newHandler)
|
||||
= exceptionHandlerCatchType(oldHandler);
|
||||
@ -2811,7 +2812,8 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
||||
LineNumber* oldLine = lineNumberTableBody(t, oldTable, i);
|
||||
LineNumber* newLine = lineNumberTableBody(t, newTable, i);
|
||||
|
||||
lineNumberIp(newLine) = c->logicalIpToOffset(lineNumberIp(oldLine));
|
||||
lineNumberIp(newLine) = c->logicalIpToOffset(lineNumberIp(oldLine))
|
||||
->value(c);
|
||||
|
||||
lineNumberLine(newLine) = lineNumberLine(oldLine);
|
||||
}
|
||||
@ -2891,7 +2893,7 @@ compileMethod(MyThread* t)
|
||||
} else {
|
||||
if (not traceNodeVirtualCall(t, node)) {
|
||||
Compiler* c = makeCompiler(t->m->system, 0);
|
||||
c->updateCall(reinterpret_cast<void*>(treeNodeKey(t, node)),
|
||||
c->updateCall(reinterpret_cast<void*>(traceNodeAddress(t, node)),
|
||||
&singletonValue(t, methodCompiled(t, target), 0));
|
||||
c->dispose();
|
||||
}
|
||||
@ -3335,8 +3337,8 @@ class MyProcessor: public Processor {
|
||||
s(s),
|
||||
defaultCompiled(0),
|
||||
nativeCompiled(0),
|
||||
addressTree(0),
|
||||
addressTreeSentinal(0),
|
||||
addressTable(0),
|
||||
addressCount(0),
|
||||
indirectCaller(0)
|
||||
{ }
|
||||
|
||||
@ -3451,7 +3453,7 @@ class MyProcessor: public Processor {
|
||||
if (t == t->m->rootThread) {
|
||||
v->visit(&defaultCompiled);
|
||||
v->visit(&nativeCompiled);
|
||||
v->visit(&addressTree);
|
||||
v->visit(&addressTable);
|
||||
}
|
||||
|
||||
for (Reference* r = t->reference; r; r = r->next) {
|
||||
@ -3595,8 +3597,8 @@ class MyProcessor: public Processor {
|
||||
System* s;
|
||||
object defaultCompiled;
|
||||
object nativeCompiled;
|
||||
object addressTree;
|
||||
object addressTreeSentinal;
|
||||
object addressTable;
|
||||
unsigned addressCount;
|
||||
void* indirectCaller;
|
||||
};
|
||||
|
||||
@ -3604,14 +3606,11 @@ MyProcessor*
|
||||
processor(MyThread* t)
|
||||
{
|
||||
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
|
||||
if (p->addressTree == 0) {
|
||||
if (p->addressTable == 0) {
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
if (p->addressTree == 0) {
|
||||
p->addressTreeSentinal = makeTraceNode(t, 0, 0, 0, 0, 0, 0, 0, 0, false);
|
||||
set(t, p->addressTreeSentinal, TreeNodeLeft, p->addressTreeSentinal);
|
||||
set(t, p->addressTreeSentinal, TreeNodeRight, p->addressTreeSentinal);
|
||||
p->addressTree = p->addressTreeSentinal;
|
||||
if (p->addressTable == 0) {
|
||||
p->addressTable = makeArray(t, 128, true);
|
||||
|
||||
Compiler* c = makeCompiler(t->m->system, 0);
|
||||
|
||||
@ -3656,16 +3655,68 @@ object
|
||||
findTraceNode(MyThread* t, void* address)
|
||||
{
|
||||
MyProcessor* p = processor(t);
|
||||
return treeQuery(t, p->addressTree, reinterpret_cast<intptr_t>(address),
|
||||
p->addressTreeSentinal);
|
||||
|
||||
intptr_t key = reinterpret_cast<intptr_t>(address);
|
||||
unsigned index = static_cast<uintptr_t>(key)
|
||||
& (arrayLength(t, p->addressTable) - 1);
|
||||
|
||||
for (object n = arrayBody(t, p->addressTable, index);
|
||||
n; n = tripleThird(t, n))
|
||||
{
|
||||
intptr_t k = traceNodeAddress(t, n);
|
||||
|
||||
if (k == key) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
abort(t);
|
||||
}
|
||||
|
||||
object
|
||||
resizeTable(MyThread* t, object oldTable, unsigned newLength)
|
||||
{
|
||||
PROTECT(t, oldTable);
|
||||
|
||||
object newTable = makeArray(t, newLength, true);
|
||||
|
||||
for (unsigned i = 0; i < arrayLength(t, oldTable); ++i) {
|
||||
object next;
|
||||
for (object p = arrayBody(t, oldTable, i); p; p = next) {
|
||||
next = traceNodeNext(t, p);
|
||||
|
||||
intptr_t k = traceNodeAddress(t, p);
|
||||
|
||||
unsigned index = k & (newLength - 1);
|
||||
|
||||
set(t, p, TraceNodeNext, arrayBody(t, newTable, index));
|
||||
set(t, newTable, ArrayBody + (index * BytesPerWord), p);
|
||||
}
|
||||
}
|
||||
|
||||
return newTable;
|
||||
}
|
||||
|
||||
void
|
||||
insertTraceNode(MyThread* t, object node)
|
||||
{
|
||||
MyProcessor* p = processor(t);
|
||||
p->addressTree = treeInsert
|
||||
(t, p->addressTree, node, p->addressTreeSentinal);
|
||||
ENTER(t, Thread::ExclusiveState);
|
||||
|
||||
++ p->addressCount;
|
||||
|
||||
if (p->addressCount >= arrayLength(t, p->addressTable) * 2) {
|
||||
PROTECT(t, node);
|
||||
|
||||
p->addressTable = resizeTable
|
||||
(t, p->addressTable, arrayLength(t, p->addressTable) * 2);
|
||||
}
|
||||
|
||||
intptr_t key = traceNodeAddress(t, node);
|
||||
unsigned index = static_cast<uintptr_t>(key)
|
||||
& (arrayLength(t, p->addressTable) - 1);
|
||||
|
||||
set(t, node, TraceNodeNext, arrayBody(t, p->addressTable, index));
|
||||
set(t, p->addressTable, ArrayBody + (index * BytesPerWord), node);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
1212
src/compiler.cpp
1212
src/compiler.cpp
File diff suppressed because it is too large
Load Diff
@ -7,11 +7,13 @@ namespace vm {
|
||||
|
||||
class Operand { };
|
||||
|
||||
class Compiler;
|
||||
|
||||
class Promise {
|
||||
public:
|
||||
virtual ~Promise() { }
|
||||
|
||||
virtual unsigned value(System* s) = 0;
|
||||
virtual unsigned value(Compiler*) = 0;
|
||||
};
|
||||
|
||||
class Compiler {
|
||||
@ -20,32 +22,23 @@ class Compiler {
|
||||
|
||||
virtual Promise* poolOffset() = 0;
|
||||
virtual Promise* codeOffset() = 0;
|
||||
virtual Promise* logicalIpToOffset(unsigned) = 0;
|
||||
|
||||
virtual Operand* poolAppend(Operand*) = 0;
|
||||
|
||||
virtual Operand* constant(intptr_t) = 0;
|
||||
|
||||
virtual void push(Operand*) = 0;
|
||||
virtual void push2(Operand*) = 0;
|
||||
virtual Operand* stack(unsigned) = 0;
|
||||
virtual Operand* stack2(unsigned) = 0;
|
||||
virtual Operand* pop() = 0;
|
||||
virtual Operand* pop2() = 0;
|
||||
virtual void pop(Operand*) = 0;
|
||||
virtual void pop2(Operand*) = 0;
|
||||
|
||||
virtual Operand* stack() = 0;
|
||||
virtual Operand* base() = 0;
|
||||
virtual Operand* thread() = 0;
|
||||
virtual Operand* indirectTarget() = 0;
|
||||
virtual Operand* temporary() = 0;
|
||||
virtual Operand* stack(unsigned) = 0;
|
||||
virtual void release(Operand*) = 0;
|
||||
|
||||
virtual Operand* label() = 0;
|
||||
virtual void mark(Operand*) = 0;
|
||||
|
||||
virtual Operand* call(Operand*) = 0;
|
||||
virtual Operand* alignedCall(Operand*) = 0;
|
||||
virtual Operand* indirectCall
|
||||
(Operand* address, unsigned argumentCount, ...) = 0;
|
||||
virtual void indirectCallNoReturn
|
||||
@ -56,6 +49,14 @@ class Compiler {
|
||||
virtual void return_(Operand*) = 0;
|
||||
virtual void ret() = 0;
|
||||
|
||||
virtual void push(Operand*) = 0;
|
||||
virtual void push2(Operand*) = 0;
|
||||
virtual Operand* pop() = 0;
|
||||
virtual Operand* pop2() = 0;
|
||||
virtual void pop(Operand*) = 0;
|
||||
virtual void pop2(Operand*) = 0;
|
||||
virtual Operand* call(Operand*) = 0;
|
||||
virtual Operand* alignedCall(Operand*) = 0;
|
||||
virtual void mov(Operand* src, Operand* dst) = 0;
|
||||
virtual void cmp(Operand* subtrahend, Operand* minuend) = 0;
|
||||
virtual void jl(Operand*) = 0;
|
||||
@ -92,12 +93,11 @@ class Compiler {
|
||||
|
||||
virtual void startLogicalIp(unsigned) = 0;
|
||||
virtual Operand* logicalIp(unsigned) = 0;
|
||||
virtual unsigned logicalIpToOffset(unsigned) = 0;
|
||||
|
||||
virtual unsigned size() = 0;
|
||||
virtual void writeTo(void*) = 0;
|
||||
|
||||
virtual void updateCall(void* returnAddress, void* newTarget);
|
||||
virtual void updateCall(void* returnAddress, void* newTarget) = 0;
|
||||
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
@ -91,20 +91,9 @@
|
||||
(object method)
|
||||
(int ip))
|
||||
|
||||
(type treeNode
|
||||
(intptr_t key)
|
||||
(uintptr_t red)
|
||||
(object left)
|
||||
(object right))
|
||||
|
||||
(type treePath
|
||||
(uintptr_t fresh)
|
||||
(object node)
|
||||
(object root)
|
||||
(object ancestors))
|
||||
|
||||
(type traceNode
|
||||
(extends treeNode)
|
||||
(intptr_t address)
|
||||
(object next)
|
||||
(object method)
|
||||
(object target)
|
||||
(uintptr_t virtualCall)
|
||||
|
225
src/util.cpp
225
src/util.cpp
@ -18,202 +18,6 @@ clone(Thread* t, object o)
|
||||
return clone;
|
||||
}
|
||||
|
||||
object
|
||||
treeFind(Thread* t, object old, object node, object sentinal)
|
||||
{
|
||||
PROTECT(t, old);
|
||||
PROTECT(t, node);
|
||||
PROTECT(t, sentinal);
|
||||
|
||||
object newRoot = clone(t, old);
|
||||
PROTECT(t, newRoot);
|
||||
|
||||
object new_ = newRoot;
|
||||
PROTECT(t, new_);
|
||||
|
||||
object ancestors = 0;
|
||||
PROTECT(t, ancestors);
|
||||
|
||||
while (old != sentinal) {
|
||||
ancestors = makePair(t, new_, ancestors);
|
||||
|
||||
intptr_t difference = treeNodeKey(t, node) - treeNodeKey(t, old);
|
||||
if (difference < 0) {
|
||||
old = treeNodeLeft(t, old);
|
||||
object n = clone(t, old);
|
||||
set(t, new_, TreeNodeLeft, n);
|
||||
new_ = n;
|
||||
} else if (difference > 0) {
|
||||
old = treeNodeRight(t, old);
|
||||
object n = clone(t, old);
|
||||
set(t, new_, TreeNodeRight, n);
|
||||
new_ = n;
|
||||
} else {
|
||||
return makeTreePath(t, false, new_, newRoot, pairSecond(t, ancestors));
|
||||
}
|
||||
}
|
||||
|
||||
object class_ = objectClass(t, node);
|
||||
unsigned size = baseSize(t, node, class_) * BytesPerWord;
|
||||
unsigned treeNodeSize = classFixedSize
|
||||
(t, arrayBody(t, t->m->types, Machine::TreeNodeType)) * BytesPerWord;
|
||||
unsigned diff = treeNodeSize - size;
|
||||
|
||||
if (diff) {
|
||||
memcpy(reinterpret_cast<uint8_t*>(new_) + treeNodeSize,
|
||||
reinterpret_cast<uint8_t*>(node) + treeNodeSize,
|
||||
diff);
|
||||
}
|
||||
|
||||
return makeTreePath(t, true, new_, newRoot, ancestors);
|
||||
}
|
||||
|
||||
object
|
||||
leftRotate(Thread* t, object n)
|
||||
{
|
||||
object child = clone(t, treeNodeRight(t, n));
|
||||
set(t, n, TreeNodeRight, treeNodeLeft(t, child));
|
||||
set(t, child, TreeNodeLeft, n);
|
||||
return child;
|
||||
}
|
||||
|
||||
object
|
||||
rightRotate(Thread* t, object n)
|
||||
{
|
||||
object child = clone(t, treeNodeLeft(t, n));
|
||||
set(t, n, TreeNodeLeft, treeNodeRight(t, child));
|
||||
set(t, child, TreeNodeRight, n);
|
||||
return child;
|
||||
}
|
||||
|
||||
object
|
||||
treeAdd(Thread* t, object path)
|
||||
{
|
||||
object new_ = treePathNode(t, path);
|
||||
PROTECT(t, new_);
|
||||
|
||||
object newRoot = treePathRoot(t, path);
|
||||
PROTECT(t, newRoot);
|
||||
|
||||
object ancestors = treePathAncestors(t, path);
|
||||
PROTECT(t, ancestors);
|
||||
|
||||
// rebalance
|
||||
treeNodeRed(t, new_) = true;
|
||||
while (ancestors != 0 and treeNodeRed(t, pairFirst(t, ancestors))) {
|
||||
if (pairFirst(t, ancestors)
|
||||
== treeNodeLeft(t, pairFirst(t, pairSecond(t, ancestors))))
|
||||
{
|
||||
if (treeNodeRed
|
||||
(t, treeNodeRight(t, pairFirst(t, pairSecond(t, ancestors)))))
|
||||
{
|
||||
treeNodeRed(t, pairFirst(t, ancestors)) = true;
|
||||
|
||||
object n = clone
|
||||
(t, treeNodeRight(t, pairFirst(t, pairSecond(t, ancestors))));
|
||||
|
||||
set(t, pairFirst(t, pairSecond(t, ancestors)), TreeNodeRight, n);
|
||||
|
||||
treeNodeRed
|
||||
(t, treeNodeRight
|
||||
(t, pairFirst(t, pairSecond(t, ancestors)))) = false;
|
||||
|
||||
treeNodeRed(t, pairFirst(t, pairSecond(t, ancestors))) = false;
|
||||
|
||||
new_ = pairFirst(t, pairSecond(t, ancestors));
|
||||
ancestors = pairSecond(t, pairSecond(t, ancestors));
|
||||
} else {
|
||||
if (new_ == treeNodeRight(t, pairFirst(t, ancestors))) {
|
||||
new_ = pairFirst(t, ancestors);
|
||||
ancestors = pairSecond(t, ancestors);
|
||||
|
||||
object n = leftRotate(t, new_);
|
||||
|
||||
if (new_ == treeNodeRight(t, pairFirst(t, ancestors))) {
|
||||
set(t, pairFirst(t, ancestors), TreeNodeRight, n);
|
||||
} else {
|
||||
set(t, pairFirst(t, ancestors), TreeNodeLeft, n);
|
||||
}
|
||||
ancestors = makePair(t, n, ancestors);
|
||||
}
|
||||
treeNodeRed(t, pairFirst(t, ancestors)) = false;
|
||||
treeNodeRed(t, pairFirst(t, pairSecond(t, ancestors))) = true;
|
||||
|
||||
object n = rightRotate(t, pairFirst(t, pairSecond(t, ancestors)));
|
||||
if (pairSecond(t, pairSecond(t, ancestors)) == 0) {
|
||||
newRoot = n;
|
||||
} else if (treeNodeRight
|
||||
(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))))
|
||||
== pairFirst(t, pairSecond(t, ancestors)))
|
||||
{
|
||||
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
|
||||
TreeNodeRight, n);
|
||||
} else {
|
||||
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
|
||||
TreeNodeLeft, n);
|
||||
}
|
||||
// done
|
||||
}
|
||||
} else { // this is just the reverse of the code above (right and
|
||||
// left swapped):
|
||||
if (treeNodeRed
|
||||
(t, treeNodeLeft(t, pairFirst(t, pairSecond(t, ancestors)))))
|
||||
{
|
||||
treeNodeRed(t, pairFirst(t, ancestors)) = true;
|
||||
|
||||
object n = clone
|
||||
(t, treeNodeLeft(t, pairFirst(t, pairSecond(t, ancestors))));
|
||||
|
||||
set(t, pairFirst(t, pairSecond(t, ancestors)), TreeNodeLeft, n);
|
||||
|
||||
treeNodeRed
|
||||
(t, treeNodeLeft
|
||||
(t, pairFirst(t, pairSecond(t, ancestors)))) = false;
|
||||
|
||||
treeNodeRed(t, pairFirst(t, pairSecond(t, ancestors))) = false;
|
||||
|
||||
new_ = pairFirst(t, pairSecond(t, ancestors));
|
||||
ancestors = pairSecond(t, pairSecond(t, ancestors));
|
||||
} else {
|
||||
if (new_ == treeNodeLeft(t, pairFirst(t, ancestors))) {
|
||||
new_ = pairFirst(t, ancestors);
|
||||
ancestors = pairSecond(t, ancestors);
|
||||
|
||||
object n = rightRotate(t, new_);
|
||||
|
||||
if (new_ == treeNodeLeft(t, pairFirst(t, ancestors))) {
|
||||
set(t, pairFirst(t, ancestors), TreeNodeLeft, n);
|
||||
} else {
|
||||
set(t, pairFirst(t, ancestors), TreeNodeRight, n);
|
||||
}
|
||||
ancestors = makePair(t, n, ancestors);
|
||||
}
|
||||
treeNodeRed(t, pairFirst(t, ancestors)) = false;
|
||||
treeNodeRed(t, pairFirst(t, pairSecond(t, ancestors))) = true;
|
||||
|
||||
object n = leftRotate(t, pairFirst(t, pairSecond(t, ancestors)));
|
||||
if (pairSecond(t, pairSecond(t, ancestors)) == 0) {
|
||||
newRoot = n;
|
||||
} else if (treeNodeLeft
|
||||
(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))))
|
||||
== pairFirst(t, pairSecond(t, ancestors)))
|
||||
{
|
||||
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
|
||||
TreeNodeLeft, n);
|
||||
} else {
|
||||
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
|
||||
TreeNodeRight, n);
|
||||
}
|
||||
// done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
treeNodeRed(t, newRoot) = false;
|
||||
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace vm {
|
||||
@ -465,33 +269,4 @@ vectorAppend(Thread* t, object vector, object value)
|
||||
return vector;
|
||||
}
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, object tree, intptr_t key, object sentinal)
|
||||
{
|
||||
object node = tree;
|
||||
while (node != sentinal) {
|
||||
intptr_t difference = key - treeNodeKey(t, node);
|
||||
if (difference < 0) {
|
||||
node = treeNodeLeft(t, node);
|
||||
} else if (difference > 0) {
|
||||
node = treeNodeRight(t, node);
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
object
|
||||
treeInsert(Thread* t, object tree, object node, object sentinal)
|
||||
{
|
||||
object path = treeFind(t, tree, node, sentinal);
|
||||
if (treePathFresh(t, path)) {
|
||||
return treeAdd(t, path);
|
||||
} else {
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
|
@ -73,12 +73,6 @@ listAppend(Thread* t, object list, object value);
|
||||
object
|
||||
vectorAppend(Thread* t, object vector, object value);
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, object tree, intptr_t key, object sentinal);
|
||||
|
||||
object
|
||||
treeInsert(Thread* t, object tree, object node, object sentinal);
|
||||
|
||||
} // vm
|
||||
|
||||
#endif//UTIL_H
|
||||
|
16
src/vector.h
16
src/vector.h
@ -35,6 +35,7 @@ class Vector {
|
||||
s->free(data);
|
||||
}
|
||||
data = newData;
|
||||
capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +83,10 @@ class Vector {
|
||||
append(&v, BytesPerWord);
|
||||
}
|
||||
|
||||
void appendAddress(void* v) {
|
||||
append(&v, BytesPerWord);
|
||||
}
|
||||
|
||||
unsigned length() {
|
||||
return position;
|
||||
}
|
||||
@ -91,17 +96,6 @@ class Vector {
|
||||
assert(s, offset + sizeof(T) <= position);
|
||||
return reinterpret_cast<T*>(data + offset);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* push(const T& v) {
|
||||
return static_cast<T*>(append(&v, sizeof(T)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T pop() {
|
||||
T r; pop(&r, sizeof(T));
|
||||
return r;
|
||||
}
|
||||
|
||||
System* s;
|
||||
uint8_t* data;
|
||||
|
62
src/zone.h
Normal file
62
src/zone.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef ZONE_H
|
||||
#define ZONE_H
|
||||
|
||||
#include "system.h"
|
||||
|
||||
namespace vm {
|
||||
|
||||
class Zone {
|
||||
public:
|
||||
class Segment {
|
||||
public:
|
||||
Segment(Segment* next): next(next) { }
|
||||
|
||||
Segment* next;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
Zone(System* s, unsigned minimumCapacity):
|
||||
s(s),
|
||||
segment(0),
|
||||
position(0),
|
||||
capacity(0),
|
||||
minimumCapacity(minimumCapacity)
|
||||
{ }
|
||||
|
||||
~Zone() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
for (Segment* seg = segment, *next; seg; seg = next) {
|
||||
next = seg->next;
|
||||
s->free(seg);
|
||||
}
|
||||
}
|
||||
|
||||
void ensure(unsigned space) {
|
||||
if (position + space > capacity) {
|
||||
capacity = max(space, max(minimumCapacity, capacity * 2));
|
||||
segment = new (s->allocate(sizeof(Segment) + capacity)) Segment(segment);
|
||||
position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate(unsigned size) {
|
||||
size = pad(size);
|
||||
ensure(size);
|
||||
void* r = segment->data + position;
|
||||
position += size;
|
||||
return r;
|
||||
}
|
||||
|
||||
System* s;
|
||||
Segment* segment;
|
||||
unsigned position;
|
||||
unsigned capacity;
|
||||
unsigned minimumCapacity;
|
||||
};
|
||||
|
||||
} // namespace vm
|
||||
|
||||
#endif//ZONE_H
|
Loading…
x
Reference in New Issue
Block a user