mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
implement persistent red-black tree in util.cpp based on PersistentSet.java
This commit is contained in:
parent
0bbe9489a7
commit
466c958d2b
6
makefile
6
makefile
@ -105,13 +105,13 @@ ifeq ($(platform),windows)
|
||||
endif
|
||||
|
||||
ifeq ($(mode),debug)
|
||||
cflags += -O0 -g3
|
||||
cflags += -O0 -g3 -DNDEBUG
|
||||
endif
|
||||
ifeq ($(mode),stress)
|
||||
cflags += -O0 -g3 -DVM_STRESS
|
||||
cflags += -O0 -g3 -DNDEBUG -DVM_STRESS
|
||||
endif
|
||||
ifeq ($(mode),stress-major)
|
||||
cflags += -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
|
||||
cflags += -O0 -g3 -DNDEBUG -DVM_STRESS -DVM_STRESS_MAJOR
|
||||
endif
|
||||
ifeq ($(mode),fast)
|
||||
cflags += -O3 -g3 -DNDEBUG
|
||||
|
@ -108,7 +108,7 @@ Java_java_lang_Object_clone(Thread* t, jclass, jobject o)
|
||||
// clear any object header flags:
|
||||
setObjectClass(t, *o, objectClass(t, *o));
|
||||
} else {
|
||||
clone = make(t, objectClass(t, *o));
|
||||
clone = make(t, class_);
|
||||
memcpy(reinterpret_cast<void**>(clone) + 1,
|
||||
reinterpret_cast<void**>(*o) + 1,
|
||||
size - BytesPerWord);
|
||||
|
@ -2749,8 +2749,8 @@ finish(MyThread* t, Compiler* c, object method, Buffer* objectPool,
|
||||
traceLog->get(i + BytesPerWord + 2 + 1 + 4, map, mapSize);
|
||||
|
||||
object node = makeTraceNode
|
||||
(t, reinterpret_cast<intptr_t>(start + offset->value()), 0, 0, method,
|
||||
target, virtualCall, mapSize / BytesPerWord, false);
|
||||
(t, reinterpret_cast<intptr_t>(start + offset->value()), 0, 0, 0,
|
||||
method, target, virtualCall, mapSize / BytesPerWord, false);
|
||||
|
||||
if (mapSize) {
|
||||
memcpy(&traceNodeMap(t, node, 0), map, mapSize);
|
||||
@ -3328,6 +3328,7 @@ class MyProcessor: public Processor {
|
||||
defaultCompiled(0),
|
||||
nativeCompiled(0),
|
||||
addressTree(0),
|
||||
addressTreeSentinal(0),
|
||||
indirectCaller(0)
|
||||
{ }
|
||||
|
||||
@ -3587,13 +3588,41 @@ class MyProcessor: public Processor {
|
||||
object defaultCompiled;
|
||||
object nativeCompiled;
|
||||
object addressTree;
|
||||
object addressTreeSentinal;
|
||||
void* indirectCaller;
|
||||
};
|
||||
|
||||
MyProcessor*
|
||||
processor(MyThread* t)
|
||||
{
|
||||
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
|
||||
if (p->addressTree == 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;
|
||||
|
||||
Compiler* c = makeCompiler(t->m->system, 0);
|
||||
|
||||
c->mov(c->base(), c->memory(c->thread(), difference(&(t->base), t)));
|
||||
c->mov(c->stack(), c->memory(c->thread(), difference(&(t->stack), t)));
|
||||
|
||||
c->jmp(c->indirectTarget());
|
||||
|
||||
p->indirectCaller = t->m->system->allocate(c->size());
|
||||
c->writeTo(p->indirectCaller);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
compile(MyThread* t, object method)
|
||||
{
|
||||
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
|
||||
MyProcessor* p = processor(t);
|
||||
|
||||
object stub = p->getDefaultCompiled(t);
|
||||
|
||||
@ -3603,18 +3632,6 @@ compile(MyThread* t, object method)
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
if (methodCompiled(t, method) == stub) {
|
||||
if (p->indirectCaller == 0) {
|
||||
Compiler* c = makeCompiler(t->m->system, 0);
|
||||
|
||||
c->mov(c->base(), c->memory(c->thread(), difference(&(t->base), t)));
|
||||
c->mov(c->stack(), c->memory(c->thread(), difference(&(t->stack), t)));
|
||||
|
||||
c->jmp(c->indirectTarget());
|
||||
|
||||
p->indirectCaller = t->m->system->allocate(c->size());
|
||||
c->writeTo(p->indirectCaller);
|
||||
}
|
||||
|
||||
PROTECT(t, method);
|
||||
|
||||
Compiler* c = makeCompiler(t->m->system, p->indirectCaller);
|
||||
@ -3630,15 +3647,17 @@ compile(MyThread* t, object method)
|
||||
object
|
||||
findTraceNode(MyThread* t, void* address)
|
||||
{
|
||||
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
|
||||
return treeQuery(t, p->addressTree, reinterpret_cast<intptr_t>(address));
|
||||
MyProcessor* p = processor(t);
|
||||
return treeQuery(t, p->addressTree, reinterpret_cast<intptr_t>(address),
|
||||
p->addressTreeSentinal);
|
||||
}
|
||||
|
||||
void
|
||||
insertTraceNode(MyThread* t, object node)
|
||||
{
|
||||
MyProcessor* p = static_cast<MyProcessor*>(t->m->processor);
|
||||
p->addressTree = treeInsert(t, p->addressTree, node);
|
||||
MyProcessor* p = processor(t);
|
||||
p->addressTree = treeInsert
|
||||
(t, p->addressTree, node, p->addressTreeSentinal);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -93,14 +93,21 @@
|
||||
|
||||
(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)
|
||||
(object method)
|
||||
(object target)
|
||||
(uint8_t virtualCall)
|
||||
(uintptr_t virtualCall)
|
||||
(array uintptr_t map))
|
||||
|
||||
(type array
|
||||
|
232
src/util.cpp
232
src/util.cpp
@ -1,5 +1,208 @@
|
||||
#include "util.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
object
|
||||
clone(Thread* t, object o)
|
||||
{
|
||||
object class_ = objectClass(t, o);
|
||||
unsigned size = baseSize(t, o, class_) * BytesPerWord;
|
||||
|
||||
object clone = make(t, class_);
|
||||
memcpy(reinterpret_cast<void**>(clone) + 1,
|
||||
reinterpret_cast<void**>(o) + 1,
|
||||
size - BytesPerWord);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
object
|
||||
treeFind(Thread* t, object oldRoot, object node, object sentinal)
|
||||
{
|
||||
object newRoot = clone(t, oldRoot);
|
||||
object ancestors = 0;
|
||||
|
||||
object old = oldRoot;
|
||||
object new_ = newRoot;
|
||||
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);
|
||||
object newRoot = treePathRoot(t, path);
|
||||
object ancestors = treePathAncestors(t, path);
|
||||
|
||||
// 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 {
|
||||
|
||||
object
|
||||
@ -249,4 +452,33 @@ 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
|
||||
|
@ -74,10 +74,10 @@ object
|
||||
vectorAppend(Thread* t, object vector, object value);
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, object tree, intptr_t key);
|
||||
treeQuery(Thread* t, object tree, intptr_t key, object sentinal);
|
||||
|
||||
object
|
||||
treeInsert(Thread* t, object tree, object node);
|
||||
treeInsert(Thread* t, object tree, object node, object sentinal);
|
||||
|
||||
} // vm
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user