mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge branch 'master' into compiler
Conflicts: src/compile.cpp src/compiler.cpp src/compiler.h
This commit is contained in:
commit
9f8d77a2a9
@ -27,6 +27,34 @@ public class StackTraceElement {
|
|||||||
this.line = line;
|
this.line = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return class_.hashCode() ^ method.hashCode() ^ line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o instanceof StackTraceElement) {
|
||||||
|
StackTraceElement e = (StackTraceElement) o;
|
||||||
|
return class_.equals(e.class_)
|
||||||
|
&& method.equals(e.method)
|
||||||
|
&& line == e.line;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(class_).append(".").append(method);
|
||||||
|
|
||||||
|
if (line == NativeLine) {
|
||||||
|
sb.append(" (native)");
|
||||||
|
} else if (line >= 0) {
|
||||||
|
sb.append(" (line ").append(line).append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public String getClassName() {
|
public String getClassName() {
|
||||||
return class_;
|
return class_;
|
||||||
}
|
}
|
||||||
|
@ -101,21 +101,7 @@ public class Throwable {
|
|||||||
|
|
||||||
StackTraceElement[] trace = resolveTrace();
|
StackTraceElement[] trace = resolveTrace();
|
||||||
for (int i = 0; i < trace.length; ++i) {
|
for (int i = 0; i < trace.length; ++i) {
|
||||||
sb.append(" at ")
|
sb.append(" at ").append(trace[i].toString()).append(nl);
|
||||||
.append(trace[i].getClassName())
|
|
||||||
.append(".")
|
|
||||||
.append(trace[i].getMethodName());
|
|
||||||
|
|
||||||
if (trace[i].isNativeMethod()) {
|
|
||||||
sb.append(" (native)");
|
|
||||||
} else {
|
|
||||||
int line = trace[i].getLineNumber();
|
|
||||||
if (line >= 0) {
|
|
||||||
sb.append(" (line ").append(line).append(")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(nl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
|
@ -53,6 +53,7 @@ enumerateThreads(Thread* t, Thread* x, object array, unsigned* index,
|
|||||||
{
|
{
|
||||||
if (*index < limit) {
|
if (*index < limit) {
|
||||||
set(t, array, ArrayBody + (*index * BytesPerWord), x->javaThread);
|
set(t, array, ArrayBody + (*index * BytesPerWord), x->javaThread);
|
||||||
|
++ (*index);
|
||||||
|
|
||||||
if (x->peer) enumerateThreads(t, x->peer, array, index, limit);
|
if (x->peer) enumerateThreads(t, x->peer, array, index, limit);
|
||||||
|
|
||||||
@ -711,7 +712,7 @@ Java_java_lang_Thread_interrupt(Thread* t, jclass, jlong peer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jobject JNICALL
|
extern "C" JNIEXPORT jobject JNICALL
|
||||||
Java_java_lang_Thread_getTrace(Thread* t, jclass, jlong peer)
|
Java_java_lang_Thread_getStackTrace(Thread* t, jclass, jlong peer)
|
||||||
{
|
{
|
||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
|
@ -29,11 +29,12 @@
|
|||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
# define LD "d"
|
# define LD "d"
|
||||||
# define LX "x"
|
|
||||||
# define LLD "lld"
|
# define LLD "lld"
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define ULD "lu"
|
# define ULD "lu"
|
||||||
|
# define LX "lx"
|
||||||
#else
|
#else
|
||||||
|
# define LX "x"
|
||||||
# define ULD "u"
|
# define ULD "u"
|
||||||
#endif
|
#endif
|
||||||
#elif defined __x86_64__
|
#elif defined __x86_64__
|
||||||
|
401
src/compile.cpp
401
src/compile.cpp
@ -41,14 +41,12 @@ class MyThread: public Thread {
|
|||||||
public:
|
public:
|
||||||
CallTrace(MyThread* t):
|
CallTrace(MyThread* t):
|
||||||
t(t),
|
t(t),
|
||||||
ip(t->ip),
|
|
||||||
base(t->base),
|
base(t->base),
|
||||||
stack(t->stack),
|
stack(t->stack),
|
||||||
nativeMethod(0),
|
nativeMethod(0),
|
||||||
next(t->trace)
|
next(t->trace)
|
||||||
{
|
{
|
||||||
t->trace = this;
|
t->trace = this;
|
||||||
t->ip = 0;
|
|
||||||
t->base = 0;
|
t->base = 0;
|
||||||
t->stack = 0;
|
t->stack = 0;
|
||||||
}
|
}
|
||||||
@ -56,7 +54,6 @@ class MyThread: public Thread {
|
|||||||
~CallTrace() {
|
~CallTrace() {
|
||||||
t->stack = stack;
|
t->stack = stack;
|
||||||
t->base = base;
|
t->base = base;
|
||||||
t->ip = ip;
|
|
||||||
t->trace = next;
|
t->trace = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +150,14 @@ methodForIp(MyThread* t, void* ip)
|
|||||||
|
|
||||||
class MyStackWalker: public Processor::StackWalker {
|
class MyStackWalker: public Processor::StackWalker {
|
||||||
public:
|
public:
|
||||||
|
enum State {
|
||||||
|
Start,
|
||||||
|
Next,
|
||||||
|
Method,
|
||||||
|
NativeMethod,
|
||||||
|
Finish
|
||||||
|
};
|
||||||
|
|
||||||
class MyProtector: public Thread::Protector {
|
class MyProtector: public Thread::Protector {
|
||||||
public:
|
public:
|
||||||
MyProtector(MyStackWalker* walker):
|
MyProtector(MyStackWalker* walker):
|
||||||
@ -161,7 +166,6 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
|
|
||||||
virtual void visit(Heap::Visitor* v) {
|
virtual void visit(Heap::Visitor* v) {
|
||||||
v->visit(&(walker->method_));
|
v->visit(&(walker->method_));
|
||||||
v->visit(&(walker->nativeMethod));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MyStackWalker* walker;
|
MyStackWalker* walker;
|
||||||
@ -169,109 +173,156 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
|
|
||||||
MyStackWalker(MyThread* t):
|
MyStackWalker(MyThread* t):
|
||||||
t(t),
|
t(t),
|
||||||
ip_(t->ip ? t->ip : (t->stack ? *static_cast<void**>(t->stack) : 0)),
|
state(Start),
|
||||||
|
ip_(t->ip),
|
||||||
base(t->base),
|
base(t->base),
|
||||||
stack(t->stack),
|
stack(t->stack),
|
||||||
trace(t->trace),
|
trace(t->trace),
|
||||||
nativeMethod(trace->nativeMethod),
|
method_(0),
|
||||||
method_(ip_ ? methodForIp(t, ip_) : 0),
|
|
||||||
protector(this)
|
protector(this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
MyStackWalker(MyStackWalker* w):
|
MyStackWalker(MyStackWalker* w):
|
||||||
t(w->t),
|
t(w->t),
|
||||||
|
state(w->state),
|
||||||
ip_(w->ip_),
|
ip_(w->ip_),
|
||||||
base(w->base),
|
base(w->base),
|
||||||
stack(w->stack),
|
stack(w->stack),
|
||||||
trace(w->trace),
|
trace(w->trace),
|
||||||
nativeMethod(w->nativeMethod),
|
|
||||||
method_(w->method_),
|
method_(w->method_),
|
||||||
protector(this)
|
protector(this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void walk(Processor::StackVisitor* v) {
|
virtual void walk(Processor::StackVisitor* v) {
|
||||||
if (stack == 0) {
|
for (MyStackWalker it(this); it.valid();) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not v->visit(this)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MyStackWalker it(this); it.next();) {
|
|
||||||
MyStackWalker walker(it);
|
MyStackWalker walker(it);
|
||||||
if (not v->visit(&walker)) {
|
if (not v->visit(&walker)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
it.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool next() {
|
bool valid() {
|
||||||
if (nativeMethod) {
|
while (true) {
|
||||||
nativeMethod = 0;
|
// fprintf(stderr, "state: %d\n", state);
|
||||||
} else {
|
switch (state) {
|
||||||
stack = static_cast<void**>(base) + 1;
|
case Start:
|
||||||
base = *static_cast<void**>(base);
|
if (ip_ == 0 and stack) {
|
||||||
ip_ = *static_cast<void**>(stack);
|
|
||||||
method_ = methodForIp(t, *static_cast<void**>(stack));
|
|
||||||
if (method_ == 0) {
|
|
||||||
if (trace and trace->stack) {
|
|
||||||
base = trace->base;
|
|
||||||
stack = static_cast<void**>(trace->stack);
|
|
||||||
ip_ = *static_cast<void**>(stack);
|
ip_ = *static_cast<void**>(stack);
|
||||||
method_ = methodForIp(t, *static_cast<void**>(stack));
|
|
||||||
nativeMethod = trace->nativeMethod;
|
|
||||||
trace = trace->next;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trace and trace->nativeMethod) {
|
||||||
|
method_ = trace->nativeMethod;
|
||||||
|
state = NativeMethod;
|
||||||
|
} else if (ip_) {
|
||||||
|
state = Next;
|
||||||
|
} else {
|
||||||
|
state = Finish;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Next:
|
||||||
|
if (stack) {
|
||||||
|
method_ = methodForIp(t, ip_);
|
||||||
|
if (method_) {
|
||||||
|
state = Method;
|
||||||
|
} else if (trace) {
|
||||||
|
base = trace->base;
|
||||||
|
stack = static_cast<void**>(trace->stack);
|
||||||
|
ip_ = (stack ? *static_cast<void**>(stack) : 0);
|
||||||
|
|
||||||
|
if (trace->nativeMethod) {
|
||||||
|
method_ = trace->nativeMethod;
|
||||||
|
state = NativeMethod;
|
||||||
|
} else {
|
||||||
|
trace = trace->next;
|
||||||
|
state = Next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state = Finish;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state = Finish;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Method:
|
||||||
|
case NativeMethod:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Finish:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
void next() {
|
||||||
|
switch (state) {
|
||||||
|
case Method:
|
||||||
|
stack = static_cast<void**>(base) + 1;
|
||||||
|
ip_ = (stack ? *static_cast<void**>(stack) : 0);
|
||||||
|
base = *static_cast<void**>(base);
|
||||||
|
state = Next;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NativeMethod:
|
||||||
|
trace = trace->next;
|
||||||
|
state = Next;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object method() {
|
virtual object method() {
|
||||||
if (nativeMethod) {
|
switch (state) {
|
||||||
return nativeMethod;
|
case Method:
|
||||||
} else {
|
|
||||||
return method_;
|
return method_;
|
||||||
|
|
||||||
|
case NativeMethod:
|
||||||
|
return trace->nativeMethod;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int ip() {
|
virtual int ip() {
|
||||||
if (nativeMethod) {
|
switch (state) {
|
||||||
return 0;
|
case Method:
|
||||||
} else {
|
|
||||||
return reinterpret_cast<intptr_t>(ip_) - reinterpret_cast<intptr_t>
|
return reinterpret_cast<intptr_t>(ip_) - reinterpret_cast<intptr_t>
|
||||||
(&singletonValue(t, methodCompiled(t, method_), 0));
|
(&singletonValue(t, methodCompiled(t, method_), 0));
|
||||||
|
|
||||||
|
case NativeMethod:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned count() {
|
virtual unsigned count() {
|
||||||
class Visitor: public Processor::StackVisitor {
|
unsigned count = 0;
|
||||||
public:
|
|
||||||
Visitor(): count(0) { }
|
|
||||||
|
|
||||||
virtual bool visit(Processor::StackWalker*) {
|
for (MyStackWalker walker(this); walker.valid();) {
|
||||||
++ count;
|
walker.next();
|
||||||
return true;
|
++ count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned count;
|
|
||||||
} v;
|
|
||||||
|
|
||||||
MyStackWalker walker(this);
|
|
||||||
walker.walk(&v);
|
|
||||||
|
|
||||||
return v.count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
MyThread* t;
|
MyThread* t;
|
||||||
|
State state;
|
||||||
void* ip_;
|
void* ip_;
|
||||||
void* base;
|
void* base;
|
||||||
void* stack;
|
void* stack;
|
||||||
MyThread::CallTrace* trace;
|
MyThread::CallTrace* trace;
|
||||||
object nativeMethod;
|
|
||||||
object method_;
|
object method_;
|
||||||
MyProtector protector;
|
MyProtector protector;
|
||||||
};
|
};
|
||||||
@ -1012,14 +1063,9 @@ findCallNode(MyThread* t, void* address);
|
|||||||
void
|
void
|
||||||
insertCallNode(MyThread* t, object node);
|
insertCallNode(MyThread* t, object node);
|
||||||
|
|
||||||
void
|
|
||||||
removeCallNode(MyThread* t, object node);
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
findExceptionHandler(Thread* t, object method, void* ip)
|
findExceptionHandler(Thread* t, object method, void* ip)
|
||||||
{
|
{
|
||||||
PROTECT(t, method);
|
|
||||||
|
|
||||||
object table = codeExceptionHandlerTable(t, methodCode(t, method));
|
object table = codeExceptionHandlerTable(t, methodCode(t, method));
|
||||||
if (table) {
|
if (table) {
|
||||||
object index = arrayBody(t, table, 0);
|
object index = arrayBody(t, table, 0);
|
||||||
@ -1033,25 +1079,7 @@ findExceptionHandler(Thread* t, object method, void* ip)
|
|||||||
unsigned key = difference(ip, compiled) - 1;
|
unsigned key = difference(ip, compiled) - 1;
|
||||||
|
|
||||||
if (key >= start and key < end) {
|
if (key >= start and key < end) {
|
||||||
object catchType = 0;
|
object catchType = arrayBody(t, table, i + 1);
|
||||||
if (arrayBody(t, table, i + 1)) {
|
|
||||||
object e = t->exception;
|
|
||||||
t->exception = 0;
|
|
||||||
PROTECT(t, e);
|
|
||||||
|
|
||||||
PROTECT(t, table);
|
|
||||||
PROTECT(t, index);
|
|
||||||
|
|
||||||
catchType = resolveClassInObject
|
|
||||||
(t, table, ArrayBody + ((i + 1) * BytesPerWord));
|
|
||||||
|
|
||||||
if (catchType) {
|
|
||||||
t->exception = e;
|
|
||||||
} else {
|
|
||||||
// can't find what we're supposed to catch - move on.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
||||||
return compiled + intArrayBody(t, index, (i * 3) + 2);
|
return compiled + intArrayBody(t, index, (i * 3) + 2);
|
||||||
@ -1070,9 +1098,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
|||||||
void* ip = t->ip;
|
void* ip = t->ip;
|
||||||
void* base = t->base;
|
void* base = t->base;
|
||||||
void** stack = static_cast<void**>(t->stack);
|
void** stack = static_cast<void**>(t->stack);
|
||||||
if (ip) {
|
if (ip == 0) {
|
||||||
t->ip = 0;
|
|
||||||
} else {
|
|
||||||
ip = *stack;
|
ip = *stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2091,21 +2117,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(doubleToFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(doubleToFloat)),
|
||||||
0, 0, 0, 4, 1, frame->popLong()));
|
context->indirection, 0, 0, 4, 1, frame->popLong()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2i: {
|
case d2i: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(doubleToInt)),
|
(c->constant(reinterpret_cast<intptr_t>(doubleToInt)),
|
||||||
0, 0, 0, 4, 1, frame->popLong()));
|
context->indirection, 0, 0, 4, 1, frame->popLong()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2l: {
|
case d2l: {
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(doubleToLong)),
|
(c->constant(reinterpret_cast<intptr_t>(doubleToLong)),
|
||||||
0, 0, 0, 8, 1, frame->popLong()));
|
context->indirection, 0, 0, 8, 1, frame->popLong()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dadd: {
|
case dadd: {
|
||||||
@ -2115,7 +2141,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(addDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(addDouble)),
|
||||||
0, 0, 0, 8, 2, a, b));
|
context->indirection, 0, 0, 8, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dcmpg: {
|
case dcmpg: {
|
||||||
@ -2125,7 +2151,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareDoublesG)),
|
(c->constant(reinterpret_cast<intptr_t>(compareDoublesG)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dcmpl: {
|
case dcmpl: {
|
||||||
@ -2135,7 +2161,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareDoublesL)),
|
(c->constant(reinterpret_cast<intptr_t>(compareDoublesL)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dconst_0:
|
case dconst_0:
|
||||||
@ -2153,7 +2179,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(divideDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(divideDouble)),
|
||||||
0, 0, 0, 8, 2, a, b));
|
context->indirection, 0, 0, 8, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dmul: {
|
case dmul: {
|
||||||
@ -2163,14 +2189,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(multiplyDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(multiplyDouble)),
|
||||||
0, 0, 0, 8, 2, a, b));
|
context->indirection, 0, 0, 8, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dneg: {
|
case dneg: {
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(negateDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(negateDouble)),
|
||||||
0, 0, 0, 8, 1, frame->popLong()));
|
context->indirection, 0, 0, 8, 1, frame->popLong()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case vm::drem: {
|
case vm::drem: {
|
||||||
@ -2180,7 +2206,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(moduloDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(moduloDouble)),
|
||||||
0, 0, 0, 8, 2, a, b));
|
context->indirection, 0, 0, 8, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dsub: {
|
case dsub: {
|
||||||
@ -2190,7 +2216,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(subtractDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(subtractDouble)),
|
||||||
0, 0, 0, 8, 2, a, b));
|
context->indirection, 0, 0, 8, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dup:
|
case dup:
|
||||||
@ -2221,21 +2247,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(floatToDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(floatToDouble)),
|
||||||
0, 0, 0, 8, 1, frame->popInt()));
|
context->indirection, 0, 0, 8, 1, frame->popInt()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case f2i: {
|
case f2i: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(floatToInt)),
|
(c->constant(reinterpret_cast<intptr_t>(floatToInt)),
|
||||||
0, 0, 0, 4, 1, frame->popInt()));
|
context->indirection, 0, 0, 4, 1, frame->popInt()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case f2l: {
|
case f2l: {
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(floatToLong)),
|
(c->constant(reinterpret_cast<intptr_t>(floatToLong)),
|
||||||
0, 0, 0, 8, 1, frame->popInt()));
|
context->indirection, 0, 0, 8, 1, frame->popInt()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fadd: {
|
case fadd: {
|
||||||
@ -2245,7 +2271,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(addFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(addFloat)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fcmpg: {
|
case fcmpg: {
|
||||||
@ -2255,7 +2281,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareFloatsG)),
|
(c->constant(reinterpret_cast<intptr_t>(compareFloatsG)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fcmpl: {
|
case fcmpl: {
|
||||||
@ -2265,7 +2291,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(compareFloatsL)),
|
(c->constant(reinterpret_cast<intptr_t>(compareFloatsL)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fconst_0:
|
case fconst_0:
|
||||||
@ -2287,7 +2313,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(divideFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(divideFloat)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fmul: {
|
case fmul: {
|
||||||
@ -2297,14 +2323,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(multiplyFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(multiplyFloat)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fneg: {
|
case fneg: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(negateFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(negateFloat)),
|
||||||
0, 0, 0, 4, 1, frame->popInt()));
|
context->indirection, 0, 0, 4, 1, frame->popInt()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case vm::frem: {
|
case vm::frem: {
|
||||||
@ -2314,7 +2340,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(moduloFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(moduloFloat)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fsub: {
|
case fsub: {
|
||||||
@ -2324,7 +2350,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(subtractFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(subtractFloat)),
|
||||||
0, 0, 0, 4, 2, a, b));
|
context->indirection, 0, 0, 4, 2, a, b));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case getfield:
|
case getfield:
|
||||||
@ -2422,14 +2448,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(intToDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(intToDouble)),
|
||||||
0, 0, 0, 8, 1, frame->popInt()));
|
context->indirection, 0, 0, 8, 1, frame->popInt()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2f: {
|
case i2f: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(intToFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(intToFloat)),
|
||||||
0, 0, 0, 4, 1, frame->popInt()));
|
context->indirection, 0, 0, 4, 1, frame->popInt()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2l:
|
case i2l:
|
||||||
@ -2656,7 +2682,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(instanceOf)),
|
(c->constant(reinterpret_cast<intptr_t>(instanceOf)),
|
||||||
0, 0, 0, 4,
|
context->indirection, 0, 0, 4,
|
||||||
3, c->thread(), frame->append(class_), frame->popObject()));
|
3, c->thread(), frame->append(class_), frame->popObject()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -2852,14 +2878,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(longToDouble)),
|
(c->constant(reinterpret_cast<intptr_t>(longToDouble)),
|
||||||
0, 0, 0, 8, 1, frame->popLong()));
|
context->indirection, 0, 0, 8, 1, frame->popLong()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2f: {
|
case l2f: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(longToFloat)),
|
(c->constant(reinterpret_cast<intptr_t>(longToFloat)),
|
||||||
0, 0, 0, 4, 1, frame->popLong()));
|
context->indirection, 0, 0, 4, 1, frame->popLong()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2i:
|
case l2i:
|
||||||
@ -3029,7 +3055,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
c->jmp
|
c->jmp
|
||||||
(c->call
|
(c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(lookUpAddress)),
|
(c->constant(reinterpret_cast<intptr_t>(lookUpAddress)),
|
||||||
0, 0, 0, BytesPerWord,
|
context->indirection, 0, 0, BytesPerWord,
|
||||||
4, key, start, c->constant(pairCount), default_));
|
4, key, start, c->constant(pairCount), default_));
|
||||||
|
|
||||||
for (int32_t i = 0; i < pairCount; ++i) {
|
for (int32_t i = 0; i < pairCount; ++i) {
|
||||||
@ -3327,7 +3353,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} else {
|
} else {
|
||||||
c->call
|
c->call
|
||||||
(c->constant(reinterpret_cast<intptr_t>(set)),
|
(c->constant(reinterpret_cast<intptr_t>(set)),
|
||||||
0, 0, 0, 0,
|
context->indirection, 0, 0, 0,
|
||||||
4, c->thread(), table, c->constant(fieldOffset(t, field)), value);
|
4, c->thread(), table, c->constant(fieldOffset(t, field)), value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3484,6 +3510,8 @@ translateExceptionHandlerTable(MyThread* t, Compiler* c, object code,
|
|||||||
PROTECT(t, newIndex);
|
PROTECT(t, newIndex);
|
||||||
|
|
||||||
object newTable = makeArray(t, length + 1, false);
|
object newTable = makeArray(t, length + 1, false);
|
||||||
|
PROTECT(t, newTable);
|
||||||
|
|
||||||
set(t, newTable, ArrayBody, newIndex);
|
set(t, newTable, ArrayBody, newIndex);
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; ++i) {
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
@ -3499,10 +3527,14 @@ translateExceptionHandlerTable(MyThread* t, Compiler* c, object code,
|
|||||||
intArrayBody(t, newIndex, (i * 3) + 2)
|
intArrayBody(t, newIndex, (i * 3) + 2)
|
||||||
= c->machineIp(exceptionHandlerIp(oldHandler))->value() - start;
|
= c->machineIp(exceptionHandlerIp(oldHandler))->value() - start;
|
||||||
|
|
||||||
object type =
|
object type;
|
||||||
(exceptionHandlerCatchType(oldHandler) ?
|
if (exceptionHandlerCatchType(oldHandler)) {
|
||||||
singletonObject(t, codePool(t, code),
|
type = resolveClassInPool
|
||||||
exceptionHandlerCatchType(oldHandler) - 1) : 0);
|
(t, codePool(t, code), exceptionHandlerCatchType(oldHandler) - 1);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
} else {
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
set(t, newTable, ArrayBody + ((i + 1) * BytesPerWord), type);
|
set(t, newTable, ArrayBody + ((i + 1) * BytesPerWord), type);
|
||||||
}
|
}
|
||||||
@ -3739,6 +3771,7 @@ finish(MyThread* t, Context* context)
|
|||||||
|
|
||||||
translateExceptionHandlerTable(t, c, methodCode(t, context->method),
|
translateExceptionHandlerTable(t, c, methodCode(t, context->method),
|
||||||
reinterpret_cast<intptr_t>(start));
|
reinterpret_cast<intptr_t>(start));
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
translateLineNumberTable(t, c, methodCode(t, context->method),
|
translateLineNumberTable(t, c, methodCode(t, context->method),
|
||||||
reinterpret_cast<intptr_t>(start));
|
reinterpret_cast<intptr_t>(start));
|
||||||
@ -3980,14 +4013,6 @@ compileMethod2(MyThread* t)
|
|||||||
(t, resolveThisPointer(t, t->stack, target)), methodOffset(t, target))
|
(t, resolveThisPointer(t, t->stack, target)), methodOffset(t, target))
|
||||||
= &singletonValue(t, methodCompiled(t, target), 0);
|
= &singletonValue(t, methodCompiled(t, target), 0);
|
||||||
} else {
|
} else {
|
||||||
#ifndef VM_STRESS
|
|
||||||
// valgrind doesn't like this, since the effect of updateCall
|
|
||||||
// below does not propagate to valgrind's interpreter:
|
|
||||||
{ ACQUIRE(t, t->m->classLock);
|
|
||||||
removeCallNode(t, node);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Context context(t);
|
Context context(t);
|
||||||
context.assembler->updateCall
|
context.assembler->updateCall
|
||||||
(reinterpret_cast<void*>(callNodeAddress(t, node)),
|
(reinterpret_cast<void*>(callNodeAddress(t, node)),
|
||||||
@ -4196,11 +4221,11 @@ invokeNative(MyThread* t)
|
|||||||
{
|
{
|
||||||
if (t->trace->nativeMethod == 0) {
|
if (t->trace->nativeMethod == 0) {
|
||||||
object node = findCallNode(t, *static_cast<void**>(t->stack));
|
object node = findCallNode(t, *static_cast<void**>(t->stack));
|
||||||
t->trace->nativeMethod = callNodeTarget(t, node);
|
object target = callNodeTarget(t, node);
|
||||||
if (callNodeVirtualCall(t, node)) {
|
if (callNodeVirtualCall(t, node)) {
|
||||||
t->trace->nativeMethod = resolveTarget
|
target = resolveTarget(t, t->stack, target);
|
||||||
(t, t->stack, t->trace->nativeMethod);
|
|
||||||
}
|
}
|
||||||
|
t->trace->nativeMethod = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t result = 0;
|
uint64_t result = 0;
|
||||||
@ -4535,6 +4560,13 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
|||||||
arguments->position, returnType);
|
arguments->position, returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t->exception) {
|
||||||
|
if (t->backupHeap) {
|
||||||
|
collect(t, Heap::MinorCollection);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
object r;
|
object r;
|
||||||
switch (returnCode) {
|
switch (returnCode) {
|
||||||
case ByteField:
|
case ByteField:
|
||||||
@ -4571,16 +4603,15 @@ traceSize(Thread* t)
|
|||||||
{
|
{
|
||||||
class Counter: public Processor::StackVisitor {
|
class Counter: public Processor::StackVisitor {
|
||||||
public:
|
public:
|
||||||
Counter(Thread* t): t(t), count(0) { }
|
Counter(): count(0) { }
|
||||||
|
|
||||||
virtual bool visit(Processor::StackWalker*) {
|
virtual bool visit(Processor::StackWalker*) {
|
||||||
++ count;
|
++ count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread* t;
|
|
||||||
unsigned count;
|
unsigned count;
|
||||||
} counter(t);
|
} counter;
|
||||||
|
|
||||||
t->m->processor->walkStack(t, &counter);
|
t->m->processor->walkStack(t, &counter);
|
||||||
|
|
||||||
@ -4599,15 +4630,26 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
if (t->state == Thread::ActiveState) {
|
if (t->state == Thread::ActiveState) {
|
||||||
object node = methodForIp(t, *ip);
|
object node = methodForIp(t, *ip);
|
||||||
if (node) {
|
if (node) {
|
||||||
|
void* oldIp = t->ip;
|
||||||
|
void* oldBase = t->base;
|
||||||
|
void* oldStack = t->stack;
|
||||||
|
|
||||||
t->ip = *ip;
|
t->ip = *ip;
|
||||||
t->base = *base;
|
t->base = *base;
|
||||||
t->stack = *stack;
|
t->stack = *stack;
|
||||||
|
|
||||||
ensure(t, FixedSizeOfNullPointerException + traceSize(t));
|
ensure(t, FixedSizeOfNullPointerException + traceSize(t));
|
||||||
|
|
||||||
|
t->tracing = true;
|
||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
|
t->tracing = false;
|
||||||
|
|
||||||
findUnwindTarget(t, ip, base, stack);
|
findUnwindTarget(t, ip, base, stack);
|
||||||
|
|
||||||
|
t->ip = oldIp;
|
||||||
|
t->base = oldBase;
|
||||||
|
t->stack = oldStack;
|
||||||
|
|
||||||
*thread = t;
|
*thread = t;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4618,6 +4660,11 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
Machine* m;
|
Machine* m;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MyProcessor;
|
||||||
|
|
||||||
|
MyProcessor*
|
||||||
|
processor(MyThread* t);
|
||||||
|
|
||||||
class MyProcessor: public Processor {
|
class MyProcessor: public Processor {
|
||||||
public:
|
public:
|
||||||
class CodeAllocator: public Allocator {
|
class CodeAllocator: public Allocator {
|
||||||
@ -4929,22 +4976,54 @@ class MyProcessor: public Processor {
|
|||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
MyThread* target = static_cast<MyThread*>(vmTarget);
|
MyThread* target = static_cast<MyThread*>(vmTarget);
|
||||||
|
|
||||||
|
processor(t)->getDefaultCompiled(t);
|
||||||
|
processor(t)->getNativeCompiled(t);
|
||||||
|
|
||||||
class Visitor: public System::ThreadVisitor {
|
class Visitor: public System::ThreadVisitor {
|
||||||
public:
|
public:
|
||||||
Visitor(MyThread* t, MyThread* target): t(t), target(target) { }
|
Visitor(MyThread* t, MyThread* target): t(t), target(target) { }
|
||||||
|
|
||||||
virtual void visit(void* ip, void* base, void* stack) {
|
virtual void visit(void* ip, void* base, void* stack) {
|
||||||
ensure(t, traceSize(t));
|
|
||||||
|
|
||||||
void* oldIp = target->ip;
|
void* oldIp = target->ip;
|
||||||
void* oldBase = target->ip;
|
void* oldBase = target->base;
|
||||||
void* oldStack = target->stack;
|
void* oldStack = target->stack;
|
||||||
|
|
||||||
target->ip = ip;
|
if (methodForIp(t, ip)) {
|
||||||
target->base = base;
|
target->ip = ip;
|
||||||
target->stack = stack;
|
target->base = base;
|
||||||
|
target->stack = stack;
|
||||||
|
} else {
|
||||||
|
MyProcessor* p = processor(t);
|
||||||
|
|
||||||
|
uint8_t* default_ = reinterpret_cast<uint8_t*>
|
||||||
|
(&singletonValue(t, p->defaultCompiled, 0));
|
||||||
|
unsigned defaultSize = singletonLength(t, p->defaultCompiled);
|
||||||
|
|
||||||
|
uint8_t* native = reinterpret_cast<uint8_t*>
|
||||||
|
(&singletonValue(t, p->nativeCompiled, 0));
|
||||||
|
unsigned nativeSize = singletonLength(t, p->nativeCompiled);
|
||||||
|
|
||||||
|
if ((static_cast<uint8_t*>(ip) >= p->indirectCaller
|
||||||
|
and static_cast<uint8_t*>(ip)
|
||||||
|
< p->indirectCaller + p->indirectCallerSize)
|
||||||
|
|
||||||
|
or (static_cast<uint8_t*>(ip) >= default_
|
||||||
|
and static_cast<uint8_t*>(ip) < default_ + defaultSize)
|
||||||
|
|
||||||
|
or (static_cast<uint8_t*>(ip) >= native
|
||||||
|
and static_cast<uint8_t*>(ip) < native + nativeSize))
|
||||||
|
{
|
||||||
|
target->ip = *static_cast<void**>(stack);
|
||||||
|
target->base = base;
|
||||||
|
target->stack = stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure(t, traceSize(target));
|
||||||
|
|
||||||
|
t->tracing = true;
|
||||||
trace = makeTrace(t, target);
|
trace = makeTrace(t, target);
|
||||||
|
t->tracing = false;
|
||||||
|
|
||||||
target->ip = oldIp;
|
target->ip = oldIp;
|
||||||
target->base = oldBase;
|
target->base = oldBase;
|
||||||
@ -4956,6 +5035,8 @@ class MyProcessor: public Processor {
|
|||||||
object trace;
|
object trace;
|
||||||
} visitor(t, target);
|
} visitor(t, target);
|
||||||
|
|
||||||
|
t->m->system->visit(t->systemThread, target->systemThread, &visitor);
|
||||||
|
|
||||||
if (t->backupHeap) {
|
if (t->backupHeap) {
|
||||||
PROTECT(t, visitor.trace);
|
PROTECT(t, visitor.trace);
|
||||||
|
|
||||||
@ -5082,7 +5163,7 @@ object
|
|||||||
findCallNode(MyThread* t, void* address)
|
findCallNode(MyThread* t, void* address)
|
||||||
{
|
{
|
||||||
if (DebugCallTable) {
|
if (DebugCallTable) {
|
||||||
fprintf(stderr, "find trace node %p\n", address);
|
fprintf(stderr, "find call node %p\n", address);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyProcessor* p = processor(t);
|
MyProcessor* p = processor(t);
|
||||||
@ -5142,7 +5223,7 @@ void
|
|||||||
insertCallNode(MyThread* t, object node)
|
insertCallNode(MyThread* t, object node)
|
||||||
{
|
{
|
||||||
if (DebugCallTable) {
|
if (DebugCallTable) {
|
||||||
fprintf(stderr, "insert trace node %p\n",
|
fprintf(stderr, "insert call node %p\n",
|
||||||
reinterpret_cast<void*>(callNodeAddress(t, node)));
|
reinterpret_cast<void*>(callNodeAddress(t, node)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5164,50 +5245,6 @@ insertCallNode(MyThread* t, object node)
|
|||||||
set(t, p->callTable, ArrayBody + (index * BytesPerWord), node);
|
set(t, p->callTable, ArrayBody + (index * BytesPerWord), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
removeCallNode(MyThread* t, object node)
|
|
||||||
{
|
|
||||||
if (DebugCallTable) {
|
|
||||||
fprintf(stderr, "remove call node %p\n",
|
|
||||||
reinterpret_cast<void*>(callNodeAddress(t, node)));
|
|
||||||
}
|
|
||||||
|
|
||||||
MyProcessor* p = processor(t);
|
|
||||||
PROTECT(t, node);
|
|
||||||
|
|
||||||
object oldNode = 0;
|
|
||||||
PROTECT(t, oldNode);
|
|
||||||
|
|
||||||
object newNode = 0;
|
|
||||||
PROTECT(t, newNode);
|
|
||||||
|
|
||||||
intptr_t key = callNodeAddress(t, node);
|
|
||||||
unsigned index = static_cast<uintptr_t>(key)
|
|
||||||
& (arrayLength(t, p->callTable) - 1);
|
|
||||||
|
|
||||||
for (oldNode = arrayBody(t, p->callTable, index);
|
|
||||||
oldNode;
|
|
||||||
oldNode = callNodeNext(t, oldNode))
|
|
||||||
{
|
|
||||||
if (oldNode != node) {
|
|
||||||
newNode = makeCallNode
|
|
||||||
(t, callNodeAddress(t, oldNode),
|
|
||||||
callNodeTarget(t, oldNode),
|
|
||||||
callNodeVirtualCall(t, oldNode),
|
|
||||||
newNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set(t, p->callTable, ArrayBody + (index * BytesPerWord), newNode);
|
|
||||||
|
|
||||||
-- p->callTableSize;
|
|
||||||
|
|
||||||
if (p->callTableSize <= arrayLength(t, p->callTable) / 3) {
|
|
||||||
p->callTable = resizeTable
|
|
||||||
(t, p->callTable, arrayLength(t, p->callTable) / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object&
|
object&
|
||||||
methodTree(MyThread* t)
|
methodTree(MyThread* t)
|
||||||
{
|
{
|
||||||
|
@ -1709,6 +1709,11 @@ class MyHeap: public Heap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool needsMark(void* p, unsigned offset) {
|
||||||
|
return needsMark(p) and targetNeedsMark
|
||||||
|
(mask(*(static_cast<void**>(p) + offset)));
|
||||||
|
}
|
||||||
|
|
||||||
bool targetNeedsMark(void* target) {
|
bool targetNeedsMark(void* target) {
|
||||||
return target
|
return target
|
||||||
and not c.gen2.contains(target)
|
and not c.gen2.contains(target)
|
||||||
|
@ -62,6 +62,7 @@ class Heap: public Allocator {
|
|||||||
virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords,
|
virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords,
|
||||||
bool objectMask, unsigned* totalInBytes) = 0;
|
bool objectMask, unsigned* totalInBytes) = 0;
|
||||||
virtual bool needsMark(void* p) = 0;
|
virtual bool needsMark(void* p) = 0;
|
||||||
|
virtual bool needsMark(void* p, unsigned offset) = 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;
|
||||||
virtual void* follow(void* p) = 0;
|
virtual void* follow(void* p) = 0;
|
||||||
|
@ -490,6 +490,7 @@ postCollect(Thread* t)
|
|||||||
if (t->backupHeap) {
|
if (t->backupHeap) {
|
||||||
t->m->heap->free
|
t->m->heap->free
|
||||||
(t->backupHeap, t->backupHeapSizeInWords * BytesPerWord);
|
(t->backupHeap, t->backupHeapSizeInWords * BytesPerWord);
|
||||||
|
t->backupHeap = 0;
|
||||||
t->backupHeapIndex = 0;
|
t->backupHeapIndex = 0;
|
||||||
t->backupHeapSizeInWords = 0;
|
t->backupHeapSizeInWords = 0;
|
||||||
}
|
}
|
||||||
@ -1735,7 +1736,8 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
heap(defaultHeap),
|
heap(defaultHeap),
|
||||||
backupHeap(0),
|
backupHeap(0),
|
||||||
backupHeapIndex(0),
|
backupHeapIndex(0),
|
||||||
backupHeapSizeInWords(0)
|
backupHeapSizeInWords(0),
|
||||||
|
tracing(false)
|
||||||
#ifdef VM_STRESS
|
#ifdef VM_STRESS
|
||||||
, stress(false)
|
, stress(false)
|
||||||
#endif // VM_STRESS
|
#endif // VM_STRESS
|
||||||
@ -2046,6 +2048,10 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
|||||||
t->backupHeapIndex += ceiling(sizeInBytes, BytesPerWord);
|
t->backupHeapIndex += ceiling(sizeInBytes, BytesPerWord);
|
||||||
cast<object>(o, 0) = 0;
|
cast<object>(o, 0) = 0;
|
||||||
return o;
|
return o;
|
||||||
|
} else if (t->tracing) {
|
||||||
|
expect(t, t->heapIndex + ceiling(sizeInBytes, BytesPerWord)
|
||||||
|
<= Thread::HeapSizeInWords);
|
||||||
|
return allocateSmall(t, sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
ACQUIRE_RAW(t, t->m->stateLock);
|
ACQUIRE_RAW(t, t->m->stateLock);
|
||||||
@ -2826,6 +2832,7 @@ makeTrace(Thread* t, Processor::StackWalker* walker)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object e = makeTraceElement(t, walker->method(), walker->ip());
|
object e = makeTraceElement(t, walker->method(), walker->ip());
|
||||||
|
assert(t, index < arrayLength(t, trace));
|
||||||
set(t, trace, ArrayBody + (index * BytesPerWord), e);
|
set(t, trace, ArrayBody + (index * BytesPerWord), e);
|
||||||
++ index;
|
++ index;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1291,6 +1291,7 @@ class Thread {
|
|||||||
uintptr_t* backupHeap;
|
uintptr_t* backupHeap;
|
||||||
unsigned backupHeapIndex;
|
unsigned backupHeapIndex;
|
||||||
unsigned backupHeapSizeInWords;
|
unsigned backupHeapSizeInWords;
|
||||||
|
bool tracing;
|
||||||
#ifdef VM_STRESS
|
#ifdef VM_STRESS
|
||||||
bool stress;
|
bool stress;
|
||||||
#endif // VM_STRESS
|
#endif // VM_STRESS
|
||||||
@ -1486,7 +1487,10 @@ mark(Thread* t, object o, unsigned offset, unsigned count)
|
|||||||
inline void
|
inline void
|
||||||
mark(Thread* t, object o, unsigned offset)
|
mark(Thread* t, object o, unsigned offset)
|
||||||
{
|
{
|
||||||
mark(t, o, offset, 1);
|
if (t->m->heap->needsMark(o, offset / BytesPerWord)) {
|
||||||
|
ACQUIRE_RAW(t, t->m->heapLock);
|
||||||
|
t->m->heap->mark(o, offset / BytesPerWord, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -793,6 +793,8 @@ handleSignal(int signal, siginfo_t* info, void* context)
|
|||||||
|
|
||||||
System::Thread* t = system->visitTarget;
|
System::Thread* t = system->visitTarget;
|
||||||
system->visitTarget = 0;
|
system->visitTarget = 0;
|
||||||
|
|
||||||
|
ACQUIRE_MONITOR(t, system->visitLock);
|
||||||
system->visitLock->notifyAll(t);
|
system->visitLock->notifyAll(t);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -830,7 +832,13 @@ handleSignal(int signal, siginfo_t* info, void* context)
|
|||||||
} else if (system->oldHandlers[index].sa_handler) {
|
} else if (system->oldHandlers[index].sa_handler) {
|
||||||
system->oldHandlers[index].sa_handler(signal);
|
system->oldHandlers[index].sa_handler(signal);
|
||||||
} else {
|
} else {
|
||||||
abort();
|
switch (signal) {
|
||||||
|
case VisitSignal:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,11 @@ findLineNumber(Thread* t, object method, unsigned ip)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(t);
|
if (top < lineNumberTableLength(t, lnt)) {
|
||||||
|
return lineNumberLine(lineNumberTableBody(t, lnt, top));
|
||||||
|
} else {
|
||||||
|
return UnknownLine;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return UnknownLine;
|
return UnknownLine;
|
||||||
}
|
}
|
||||||
|
@ -1793,11 +1793,14 @@ writeSizes(Output* out, Object* declarations)
|
|||||||
out->write(typeFixedSize(o));
|
out->write(typeFixedSize(o));
|
||||||
out->write(";\n\n");
|
out->write(";\n\n");
|
||||||
|
|
||||||
out->write("const unsigned ArrayElementSizeOf");
|
int aes = typeArrayElementSize(o);
|
||||||
out->write(capitalize(typeName(o)));
|
if (aes) {
|
||||||
out->write(" = ");
|
out->write("const unsigned ArrayElementSizeOf");
|
||||||
out->write(typeArrayElementSize(o));
|
out->write(capitalize(typeName(o)));
|
||||||
out->write(";\n\n");
|
out->write(" = ");
|
||||||
|
out->write(aes);
|
||||||
|
out->write(";\n\n");
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
|
37
src/x86.S
37
src/x86.S
@ -17,13 +17,14 @@
|
|||||||
.globl vmNativeCall
|
.globl vmNativeCall
|
||||||
vmNativeCall:
|
vmNativeCall:
|
||||||
pushq %rbp
|
pushq %rbp
|
||||||
|
movq %rsp,%rbp
|
||||||
|
|
||||||
// %rdi aka 0(%rbp): function
|
// %rdi aka -48(%rbp): function
|
||||||
// %rsi aka 8(%rbp): stack
|
// %rsi aka -40(%rbp): stack
|
||||||
// %rdx aka 16(%rbp): stackSize
|
// %rdx aka -32(%rbp): stackSize
|
||||||
// %rcx aka 24(%rbp): gprTable
|
// %rcx aka -24(%rbp): gprTable
|
||||||
// %r8 aka 32(%rbp): sseTable
|
// %r8 aka -16(%rbp): sseTable
|
||||||
// %r9 aka 40(%rbp): returnType
|
// %r9 aka -8(%rbp): returnType
|
||||||
|
|
||||||
// save our argument registers so we can clobber them
|
// save our argument registers so we can clobber them
|
||||||
pushq %r9
|
pushq %r9
|
||||||
@ -32,8 +33,6 @@ vmNativeCall:
|
|||||||
pushq %rdx
|
pushq %rdx
|
||||||
pushq %rsi
|
pushq %rsi
|
||||||
pushq %rdi
|
pushq %rdi
|
||||||
|
|
||||||
movq %rsp,%rbp
|
|
||||||
|
|
||||||
// reserve space for arguments passed via memory
|
// reserve space for arguments passed via memory
|
||||||
subq %rdx,%rsp
|
subq %rdx,%rsp
|
||||||
@ -49,21 +48,21 @@ loop:
|
|||||||
movq %rcx,%rax
|
movq %rcx,%rax
|
||||||
movq %rcx,%rdx
|
movq %rcx,%rdx
|
||||||
addq %rsp,%rdx
|
addq %rsp,%rdx
|
||||||
addq 8(%rbp),%rax
|
addq -40(%rbp),%rax
|
||||||
movq (%rax),%rax
|
movq (%rax),%rax
|
||||||
movq %rax,(%rdx)
|
movq %rax,(%rdx)
|
||||||
addq $8,%rcx
|
addq $8,%rcx
|
||||||
|
|
||||||
test:
|
test:
|
||||||
cmpq 16(%rbp),%rcx
|
cmpq -32(%rbp),%rcx
|
||||||
jb loop
|
jb loop
|
||||||
|
|
||||||
// do we need to load the general-purpose registers?
|
// do we need to load the general-purpose registers?
|
||||||
cmpq $0,24(%rbp)
|
cmpq $0,-24(%rbp)
|
||||||
je sse
|
je sse
|
||||||
|
|
||||||
// yes, we do
|
// yes, we do
|
||||||
movq 24(%rbp),%rax
|
movq -24(%rbp),%rax
|
||||||
movq 0(%rax),%rdi
|
movq 0(%rax),%rdi
|
||||||
movq 8(%rax),%rsi
|
movq 8(%rax),%rsi
|
||||||
movq 16(%rax),%rdx
|
movq 16(%rax),%rdx
|
||||||
@ -73,11 +72,11 @@ test:
|
|||||||
|
|
||||||
sse:
|
sse:
|
||||||
// do we need to load the SSE registers?
|
// do we need to load the SSE registers?
|
||||||
cmpq $0,32(%rbp)
|
cmpq $0,-16(%rbp)
|
||||||
je call
|
je call
|
||||||
|
|
||||||
// yes, we do
|
// yes, we do
|
||||||
movq 32(%rbp),%rax
|
movq -16(%rbp),%rax
|
||||||
movq 0(%rax),%xmm0
|
movq 0(%rax),%xmm0
|
||||||
movq 8(%rax),%xmm1
|
movq 8(%rax),%xmm1
|
||||||
movq 16(%rax),%xmm2
|
movq 16(%rax),%xmm2
|
||||||
@ -88,10 +87,10 @@ sse:
|
|||||||
movq 64(%rax),%xmm7
|
movq 64(%rax),%xmm7
|
||||||
|
|
||||||
call:
|
call:
|
||||||
call *0(%rbp)
|
call *-48(%rbp)
|
||||||
|
|
||||||
// handle return value based on expected type
|
// handle return value based on expected type
|
||||||
movq 40(%rbp),%rcx
|
movq -8(%rbp),%rcx
|
||||||
|
|
||||||
void:
|
void:
|
||||||
cmpq $VOID_TYPE,%rcx
|
cmpq $VOID_TYPE,%rcx
|
||||||
@ -109,10 +108,6 @@ copy:
|
|||||||
|
|
||||||
exit:
|
exit:
|
||||||
movq %rbp,%rsp
|
movq %rbp,%rsp
|
||||||
|
|
||||||
// pop our argument registers
|
|
||||||
addq $48,%rsp
|
|
||||||
|
|
||||||
popq %rbp
|
popq %rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user