diff --git a/makefile b/makefile index 2a149fda60..5cd3d5d06d 100644 --- a/makefile +++ b/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 diff --git a/src/builtin.cpp b/src/builtin.cpp index 6ce717ba02..c96218d64c 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -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(clone) + 1, reinterpret_cast(*o) + 1, size - BytesPerWord); diff --git a/src/compile2.cpp b/src/compile2.cpp index ffb87c1e34..0892c380ea 100644 --- a/src/compile2.cpp +++ b/src/compile2.cpp @@ -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(start + offset->value()), 0, 0, method, - target, virtualCall, mapSize / BytesPerWord, false); + (t, reinterpret_cast(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(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(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(t->m->processor); - return treeQuery(t, p->addressTree, reinterpret_cast(address)); + MyProcessor* p = processor(t); + return treeQuery(t, p->addressTree, reinterpret_cast(address), + p->addressTreeSentinal); } void insertTraceNode(MyThread* t, object node) { - MyProcessor* p = static_cast(t->m->processor); - p->addressTree = treeInsert(t, p->addressTree, node); + MyProcessor* p = processor(t); + p->addressTree = treeInsert + (t, p->addressTree, node, p->addressTreeSentinal); } } // namespace diff --git a/src/types.def b/src/types.def index 831c5deab8..f982b33044 100644 --- a/src/types.def +++ b/src/types.def @@ -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 diff --git a/src/util.cpp b/src/util.cpp index a1d932344d..dd40d3e7b5 100644 --- a/src/util.cpp +++ b/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(clone) + 1, + reinterpret_cast(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(new_) + treeNodeSize, + reinterpret_cast(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 diff --git a/src/util.h b/src/util.h index c9a37d8911..ef217b70dc 100644 --- a/src/util.h +++ b/src/util.h @@ -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