diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index 96930813af..35d50c5965 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -19,6 +19,6 @@ public final class Class { private Class() { } public String getName() { - return new String(name, 0, name.length, false); + return new String(name, 0, name.length - 1, false); } } diff --git a/classpath/java/lang/Throwable.java b/classpath/java/lang/Throwable.java index cc1464e275..f81486d93c 100644 --- a/classpath/java/lang/Throwable.java +++ b/classpath/java/lang/Throwable.java @@ -51,6 +51,7 @@ public class Throwable { for (int i = 0; i < trace.length; ++i) { sb.append(" at ") .append(trace[i].getClassName()) + .append(".") .append(trace[i].getMethodName()); if (trace[i].isNativeMethod()) { diff --git a/src/builtin.cpp b/src/builtin.cpp index 1f92bd848a..68327980a3 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -130,9 +130,37 @@ trace(Thread* t, jint skipCount) } jarray -resolveTrace(Thread* t, object trace) +resolveTrace(Thread* t, jobject trace) { - // todo + unsigned length = arrayLength(t, *trace); + object array = makeObjectArray + (t, arrayBody(t, t->vm->types, Machine::StackTraceElementType), + length, true); + PROTECT(t, array); + + object e = 0; + PROTECT(t, e); + + object class_ = 0; + PROTECT(t, class_); + + for (unsigned i = 0; i < length; ++i) { + e = arrayBody(t, *trace, i); + + class_ = className(t, methodClass(t, traceElementMethod(t, e))); + class_ = makeString(t, class_, 0, byteArrayLength(t, class_) - 1, 0); + + object method = methodName(t, traceElementMethod(t, e)); + method = makeString(t, method, 0, byteArrayLength(t, method) - 1, 0); + + unsigned line = lineNumber + (t, traceElementMethod(t, e), traceElementIp(t, e)); + + object ste = makeStackTraceElement(t, class_, method, 0, line); + set(t, objectArrayBody(t, array, i), ste); + } + + return pushReference(t, array); } void @@ -202,6 +230,8 @@ populate(Thread* t, object map) reinterpret_cast(arraycopy) }, { "Java_java_lang_Throwable_trace", reinterpret_cast(trace) }, + { "Java_java_lang_Throwable_resolveTrace", + reinterpret_cast(resolveTrace) }, { "Java_java_lang_Thread_start", reinterpret_cast(start) }, { 0, 0 } diff --git a/src/machine.cpp b/src/machine.cpp index 075246c537..882f26d15a 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1374,8 +1374,13 @@ makeArrayClass(Thread* t, object spec) } } - object elementClass = resolveClass(t, elementSpec); - if (UNLIKELY(t->exception)) return 0; + object elementClass = hashMapFind + (t, t->vm->bootstrapClassMap, elementSpec, byteArrayHash, byteArrayEqual); + + if (elementClass == 0) { + elementClass = resolveClass(t, elementSpec); + if (UNLIKELY(t->exception)) return 0; + } return makeArrayClass(t, dimensions, spec, elementClass); } @@ -1886,7 +1891,7 @@ makeTrace(Thread* t, int frame) unsigned index = 0; for (int f = frame; f >= 0; f = frameNext(t, f)) { - object e = makeStackTraceElement(t, frameMethod(t, f), frameIp(t, f)); + object e = makeTraceElement(t, frameMethod(t, f), frameIp(t, f)); set(t, arrayBody(t, trace, index++), e); } @@ -2121,6 +2126,30 @@ makeObjectArray(Thread* t, object elementClass, unsigned count, bool clear) return array; } +int +lineNumber(Thread* t, object method, unsigned ip) +{ + if (methodFlags(t, method) & ACC_NATIVE) { + return NativeLine; + } + + object table = codeLineNumberTable(t, methodCode(t, method)); + if (table) { + // todo: do a binary search: + int last = UnknownLine; + for (unsigned i = 0; i < lineNumberTableLength(t, table); ++i) { + if (ip <= lineNumberIp(lineNumberTableBody(t, table, i))) { + return last; + } else { + last = lineNumberLine(lineNumberTableBody(t, table, i)); + } + } + return last; + } else { + return UnknownLine; + } +} + void addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)) { diff --git a/src/machine.h b/src/machine.h index d9efcef815..32326c1636 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1868,9 +1868,12 @@ objectArrayBody(Thread* t, object array, unsigned index) assert(t, classObjectMask(t, objectClass(t, array)) == classObjectMask(t, arrayBody (t, t->vm->types, Machine::ArrayType))); - return cast(array, (1 + index) * BytesPerWord); + return cast(array, (2 + index) * BytesPerWord); } +int +lineNumber(Thread* t, object method, unsigned ip); + void addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)); diff --git a/src/run.cpp b/src/run.cpp index feae106f07..789a275833 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -199,30 +199,6 @@ findMethodInClass(Thread* t, object class_, object reference) methodSpec); } -int -lineNumber(Thread* t, object method, unsigned ip) -{ - if (methodFlags(t, method) & ACC_NATIVE) { - return NativeLine; - } - - object table = codeLineNumberTable(t, methodCode(t, method)); - if (table) { - // todo: do a binary search: - int last = UnknownLine; - for (unsigned i = 0; i < lineNumberTableLength(t, table); ++i) { - if (ip <= lineNumberIp(lineNumberTableBody(t, table, i))) { - return last; - } else { - last = lineNumberLine(lineNumberTableBody(t, table, i)); - } - } - return last; - } else { - return UnknownLine; - } -} - inline object resolveClass(Thread* t, object pool, unsigned index) { @@ -2216,11 +2192,10 @@ run(Thread* t) for (unsigned i = 0; i < arrayLength(t, trace); ++i) { object e = arrayBody(t, trace, i); const int8_t* class_ = &byteArrayBody - (t, className(t, methodClass(t, stackTraceElementMethod(t, e))), 0); + (t, className(t, methodClass(t, traceElementMethod(t, e))), 0); const int8_t* method = &byteArrayBody - (t, methodName(t, stackTraceElementMethod(t, e)), 0); - int line = lineNumber - (t, stackTraceElementMethod(t, e), stackTraceElementIp(t, e)); + (t, methodName(t, traceElementMethod(t, e)), 0); + int line = lineNumber(t, traceElementMethod(t, e), traceElementIp(t, e)); fprintf(stderr, " at %s.%s ", class_, method); diff --git a/src/types.def b/src/types.def index b79ae047c0..acc5a834b6 100644 --- a/src/types.def +++ b/src/types.def @@ -103,7 +103,7 @@ (object front) (object rear)) -(type stackTraceElement +(type traceElement (object method) (int32_t ip)) @@ -122,6 +122,13 @@ (object task) (int64_t peer)) +(type stackTraceElement java/lang/StackTraceElement + (extends jobject) + (object class) + (object method) + (object file) + (int32_t line)) + (type throwable java/lang/Throwable (extends jobject) (object message)