mirror of
https://github.com/corda/corda.git
synced 2025-01-01 10:46:46 +00:00
misc. bugfixes and tweaks
This commit is contained in:
parent
363801af1c
commit
41bee5829e
@ -1,3 +1,6 @@
|
|||||||
|
#include "sys/time.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include "time.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
@ -19,3 +22,12 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring key)
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
|
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
|
||||||
|
{
|
||||||
|
timeval tv = { 0, 0 };
|
||||||
|
gettimeofday(&tv, 0);
|
||||||
|
return (static_cast<jlong>(tv.tv_sec) * 1000) +
|
||||||
|
(static_cast<jlong>(tv.tv_usec) / 1000);
|
||||||
|
}
|
||||||
|
@ -19,7 +19,6 @@ public final class Class <T> {
|
|||||||
private Field[] fieldTable;
|
private Field[] fieldTable;
|
||||||
private Method[] methodTable;
|
private Method[] methodTable;
|
||||||
private Object[] staticTable;
|
private Object[] staticTable;
|
||||||
private Method initializer;
|
|
||||||
|
|
||||||
private Class() { }
|
private Class() { }
|
||||||
|
|
||||||
@ -32,11 +31,13 @@ public final class Class <T> {
|
|||||||
public native boolean isAssignableFrom(Class c);
|
public native boolean isAssignableFrom(Class c);
|
||||||
|
|
||||||
private Field findField(String name) {
|
private Field findField(String name) {
|
||||||
|
if (fieldTable != null) {
|
||||||
for (int i = 0; i < fieldTable.length; ++i) {
|
for (int i = 0; i < fieldTable.length; ++i) {
|
||||||
if (fieldTable[i].getName().equals(name)) {
|
if (fieldTable[i].getName().equals(name)) {
|
||||||
return fieldTable[i];
|
return fieldTable[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +74,7 @@ public final class Class <T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Method findMethod(String name, Class[] parameterTypes) {
|
private Method findMethod(String name, Class[] parameterTypes) {
|
||||||
|
if (methodTable != null) {
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (methodTable[i].getName().equals(name)
|
if (methodTable[i].getName().equals(name)
|
||||||
&& match(parameterTypes, methodTable[i].getParameterTypes()))
|
&& match(parameterTypes, methodTable[i].getParameterTypes()))
|
||||||
@ -80,6 +82,7 @@ public final class Class <T> {
|
|||||||
return methodTable[i];
|
return methodTable[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +128,7 @@ public final class Class <T> {
|
|||||||
|
|
||||||
private int countConstructors(boolean publicOnly) {
|
private int countConstructors(boolean publicOnly) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
if (methodTable != null) {
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (((! publicOnly)
|
if (((! publicOnly)
|
||||||
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0)
|
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0)
|
||||||
@ -133,23 +137,27 @@ public final class Class <T> {
|
|||||||
++ count;
|
++ count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Constructor[] getDeclaredConstructors() {
|
public Constructor[] getDeclaredConstructors() {
|
||||||
Constructor[] array = new Constructor[countConstructors(false)];
|
Constructor[] array = new Constructor[countConstructors(false)];
|
||||||
|
if (methodTable != null) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (methodTable[i].getName().equals("<init>")) {
|
if (methodTable[i].getName().equals("<init>")) {
|
||||||
array[index++] = new Constructor(methodTable[i]);
|
array[index++] = new Constructor(methodTable[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Constructor[] getConstructors() {
|
public Constructor[] getConstructors() {
|
||||||
Constructor[] array = new Constructor[countConstructors(true)];
|
Constructor[] array = new Constructor[countConstructors(true)];
|
||||||
|
if (methodTable != null) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
||||||
@ -158,33 +166,42 @@ public final class Class <T> {
|
|||||||
array[index++] = new Constructor(methodTable[i]);
|
array[index++] = new Constructor(methodTable[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field[] getDeclaredFields() {
|
public Field[] getDeclaredFields() {
|
||||||
|
if (fieldTable != null) {
|
||||||
Field[] array = new Field[fieldTable.length];
|
Field[] array = new Field[fieldTable.length];
|
||||||
System.arraycopy(fieldTable, 0, array, 0, fieldTable.length);
|
System.arraycopy(fieldTable, 0, array, 0, fieldTable.length);
|
||||||
return array;
|
return array;
|
||||||
|
} else {
|
||||||
|
return new Field[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int countPublicFields() {
|
private int countPublicFields() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
if (fieldTable != null) {
|
||||||
for (int i = 0; i < fieldTable.length; ++i) {
|
for (int i = 0; i < fieldTable.length; ++i) {
|
||||||
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
||||||
++ count;
|
++ count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field[] getFields() {
|
public Field[] getFields() {
|
||||||
Field[] array = new Field[countPublicFields()];
|
Field[] array = new Field[countPublicFields()];
|
||||||
|
if (fieldTable != null) {
|
||||||
for (int i = 0; i < fieldTable.length; ++i) {
|
for (int i = 0; i < fieldTable.length; ++i) {
|
||||||
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
||||||
array[i] = fieldTable[i];
|
array[i] = fieldTable[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,18 +220,21 @@ public final class Class <T> {
|
|||||||
|
|
||||||
public Method[] getDeclaredMethods() {
|
public Method[] getDeclaredMethods() {
|
||||||
Method[] array = new Method[countMethods(false)];
|
Method[] array = new Method[countMethods(false)];
|
||||||
|
if (methodTable != null) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (! methodTable[i].getName().startsWith("<")) {
|
if (! methodTable[i].getName().startsWith("<")) {
|
||||||
array[index++] = methodTable[i];
|
array[index++] = methodTable[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method[] getMethods() {
|
public Method[] getMethods() {
|
||||||
Method[] array = new Method[countMethods(true)];
|
Method[] array = new Method[countMethods(true)];
|
||||||
|
if (methodTable != null) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
||||||
@ -223,16 +243,21 @@ public final class Class <T> {
|
|||||||
array[index++] = methodTable[i];
|
array[index++] = methodTable[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getInterfaces() {
|
public Class[] getInterfaces() {
|
||||||
|
if (interfaceTable != null) {
|
||||||
Class[] array = new Class[interfaceTable.length / 2];
|
Class[] array = new Class[interfaceTable.length / 2];
|
||||||
for (int i = 0; i < array.length; ++i) {
|
for (int i = 0; i < array.length; ++i) {
|
||||||
array[i] = (Class) interfaceTable[i * 2];
|
array[i] = (Class) interfaceTable[i * 2];
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
|
} else {
|
||||||
|
return new Class[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
|
@ -6,6 +6,7 @@ import java.util.WeakHashMap;
|
|||||||
public class Thread implements Runnable {
|
public class Thread implements Runnable {
|
||||||
private final Runnable task;
|
private final Runnable task;
|
||||||
private Map<ThreadLocal, Object> locals;
|
private Map<ThreadLocal, Object> locals;
|
||||||
|
private Object sleepLock;
|
||||||
private long peer;
|
private long peer;
|
||||||
|
|
||||||
public Thread(Runnable task) {
|
public Thread(Runnable task) {
|
||||||
@ -17,7 +18,8 @@ public class Thread implements Runnable {
|
|||||||
if (map != null) {
|
if (map != null) {
|
||||||
for (Map.Entry<ThreadLocal, Object> e: map.entrySet()) {
|
for (Map.Entry<ThreadLocal, Object> e: map.entrySet()) {
|
||||||
if (e.getKey() instanceof InheritableThreadLocal) {
|
if (e.getKey() instanceof InheritableThreadLocal) {
|
||||||
locals().put(e.getKey(), e.getValue());
|
InheritableThreadLocal itl = (InheritableThreadLocal) e.getKey();
|
||||||
|
locals().put(itl, itl.childValue(e.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,6 +44,13 @@ public class Thread implements Runnable {
|
|||||||
|
|
||||||
public static native Thread currentThread();
|
public static native Thread currentThread();
|
||||||
|
|
||||||
public static native void sleep(long milliseconds)
|
public static void sleep(long milliseconds) throws InterruptedException {
|
||||||
throws InterruptedException;
|
Thread t = currentThread();
|
||||||
|
if (t.sleepLock == null) {
|
||||||
|
t.sleepLock = new Object();
|
||||||
|
}
|
||||||
|
synchronized (t.sleepLock) {
|
||||||
|
t.sleepLock.wait(milliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
makefile
2
makefile
@ -16,7 +16,7 @@ src = src
|
|||||||
classpath = classpath
|
classpath = classpath
|
||||||
test = test
|
test = test
|
||||||
|
|
||||||
input = $(cls)/Reflection.class
|
input = $(cls)/Threads.class
|
||||||
|
|
||||||
cxx = g++
|
cxx = g++
|
||||||
cc = gcc
|
cc = gcc
|
||||||
|
@ -73,12 +73,11 @@ Class_forName(Thread* t, jclass, jstring name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
object clinit = classInitializer(t, c);
|
if (classVmFlags(t, c) & NeedInitFlag) {
|
||||||
if (clinit) {
|
|
||||||
PROTECT(t, c);
|
PROTECT(t, c);
|
||||||
|
|
||||||
set(t, classInitializer(t, c), 0);
|
classVmFlags(t, c) &= ~NeedInitFlag;
|
||||||
run(t, clinit, 0);
|
run(t, classInitializer(t, c), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pushReference(t, c);
|
return pushReference(t, c);
|
||||||
@ -105,9 +104,36 @@ Field_get(Thread* t, jobject this_, jobject instancep)
|
|||||||
object field = *this_;
|
object field = *this_;
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_STATIC) {
|
if (fieldFlags(t, field) & ACC_STATIC) {
|
||||||
return pushReference
|
object v = arrayBody(t, classStaticTable(t, fieldClass(t, field)),
|
||||||
(t, arrayBody(t, classStaticTable(t, fieldClass(t, field)),
|
fieldOffset(t, field));
|
||||||
fieldOffset(t, field)));
|
|
||||||
|
switch (fieldCode(t, field)) {
|
||||||
|
case ByteField:
|
||||||
|
return pushReference(t, makeByte(t, intValue(t, v)));
|
||||||
|
|
||||||
|
case BooleanField:
|
||||||
|
return pushReference(t, makeBoolean(t, intValue(t, v)));
|
||||||
|
|
||||||
|
case CharField:
|
||||||
|
return pushReference(t, makeChar(t, intValue(t, v)));
|
||||||
|
|
||||||
|
case ShortField:
|
||||||
|
return pushReference(t, makeShort(t, intValue(t, v)));
|
||||||
|
|
||||||
|
case FloatField:
|
||||||
|
return pushReference(t, makeFloat(t, intValue(t, v)));
|
||||||
|
|
||||||
|
case DoubleField:
|
||||||
|
return pushReference(t, makeDouble(t, longValue(t, v)));
|
||||||
|
|
||||||
|
case IntField:
|
||||||
|
case LongField:
|
||||||
|
case ObjectField:
|
||||||
|
return pushReference(t, v);
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
} else if (instancep) {
|
} else if (instancep) {
|
||||||
object instance = *instancep;
|
object instance = *instancep;
|
||||||
|
|
||||||
@ -169,9 +195,44 @@ Field_set(Thread* t, jobject this_, jobject instancep, jobject value)
|
|||||||
object v = (value ? *value : 0);
|
object v = (value ? *value : 0);
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_STATIC) {
|
if (fieldFlags(t, field) & ACC_STATIC) {
|
||||||
|
object* p = &arrayBody(t, classStaticTable(t, fieldClass(t, field)),
|
||||||
|
fieldOffset(t, field));
|
||||||
|
|
||||||
if (fieldCode(t, field) == ObjectField or v) {
|
if (fieldCode(t, field) == ObjectField or v) {
|
||||||
set(t, arrayBody(t, classStaticTable(t, fieldClass(t, field)),
|
switch (fieldCode(t, field)) {
|
||||||
fieldOffset(t, field)), v);
|
case ByteField:
|
||||||
|
set(t, *p, makeInt(t, byteValue(t, v)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BooleanField:
|
||||||
|
set(t, *p, makeInt(t, booleanValue(t, v)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CharField:
|
||||||
|
set(t, *p, makeInt(t, charValue(t, v)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShortField:
|
||||||
|
set(t, *p, makeInt(t, shortValue(t, v)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FloatField:
|
||||||
|
set(t, *p, makeInt(t, floatValue(t, v)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DoubleField:
|
||||||
|
set(t, *p, makeLong(t, longValue(t, v)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IntField:
|
||||||
|
case LongField:
|
||||||
|
case ObjectField:
|
||||||
|
set(t, *p, v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
}
|
}
|
||||||
@ -398,12 +459,6 @@ System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst,
|
|||||||
t->exception = makeArrayStoreException(t);
|
t->exception = makeArrayStoreException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong
|
|
||||||
System_currentTimeMillis(Thread* t, jclass)
|
|
||||||
{
|
|
||||||
return t->vm->system->now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Runtime_loadLibrary(Thread* t, jobject, jstring name)
|
Runtime_loadLibrary(Thread* t, jobject, jstring name)
|
||||||
{
|
{
|
||||||
@ -516,15 +571,6 @@ Thread_currentThread(Thread* t, jclass)
|
|||||||
return pushReference(t, t->javaThread);
|
return pushReference(t, t->javaThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Thread_sleep(Thread* t, jclass, jlong milliseconds)
|
|
||||||
{
|
|
||||||
if (milliseconds == 0) milliseconds = INT64_MAX;
|
|
||||||
|
|
||||||
ENTER(t, Thread::IdleState);
|
|
||||||
|
|
||||||
t->vm->system->sleep(milliseconds);
|
|
||||||
}
|
|
||||||
void
|
void
|
||||||
Thread_start(Thread* t, jobject this_)
|
Thread_start(Thread* t, jobject this_)
|
||||||
{
|
{
|
||||||
@ -589,8 +635,6 @@ populateBuiltinMap(Thread* t, object map)
|
|||||||
|
|
||||||
{ "Java_java_lang_System_arraycopy",
|
{ "Java_java_lang_System_arraycopy",
|
||||||
reinterpret_cast<void*>(::System_arraycopy) },
|
reinterpret_cast<void*>(::System_arraycopy) },
|
||||||
{ "Java_java_lang_System_currentTimeMillis",
|
|
||||||
reinterpret_cast<void*>(::System_currentTimeMillis) },
|
|
||||||
|
|
||||||
{ "Java_java_lang_Runtime_loadLibrary",
|
{ "Java_java_lang_Runtime_loadLibrary",
|
||||||
reinterpret_cast<void*>(::Runtime_loadLibrary) },
|
reinterpret_cast<void*>(::Runtime_loadLibrary) },
|
||||||
@ -603,8 +647,6 @@ populateBuiltinMap(Thread* t, object map)
|
|||||||
reinterpret_cast<void*>(::Thread_start) },
|
reinterpret_cast<void*>(::Thread_start) },
|
||||||
{ "Java_java_lang_Thread_currentThread",
|
{ "Java_java_lang_Thread_currentThread",
|
||||||
reinterpret_cast<void*>(::Thread_currentThread) },
|
reinterpret_cast<void*>(::Thread_currentThread) },
|
||||||
{ "Java_java_lang_Thread_sleep",
|
|
||||||
reinterpret_cast<void*>(::Thread_sleep) },
|
|
||||||
|
|
||||||
{ "Java_java_lang_Throwable_resolveTrace",
|
{ "Java_java_lang_Throwable_resolveTrace",
|
||||||
reinterpret_cast<void*>(::Throwable_resolveTrace) },
|
reinterpret_cast<void*>(::Throwable_resolveTrace) },
|
||||||
|
@ -939,7 +939,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
|
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
|
||||||
&byteArrayBody(t, methodName(t, method), 0)) == 0)
|
&byteArrayBody(t, methodName(t, method), 0)) == 0)
|
||||||
{
|
{
|
||||||
set(t, classInitializer(t, class_), method);
|
classVmFlags(t, class_) |= NeedInitFlag;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
++ declaredVirtualCount;
|
++ declaredVirtualCount;
|
||||||
@ -1096,8 +1096,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
0, // vtable
|
0, // vtable
|
||||||
0, // fields
|
0, // fields
|
||||||
0, // methods
|
0, // methods
|
||||||
0, // static table
|
0); // static table
|
||||||
0); // initializer
|
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
unsigned super = s.read2();
|
unsigned super = s.read2();
|
||||||
@ -1107,7 +1106,8 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
|
|||||||
|
|
||||||
set(t, classSuper(t, class_), sc);
|
set(t, classSuper(t, class_), sc);
|
||||||
|
|
||||||
classVmFlags(t, class_) |= classVmFlags(t, sc);
|
classVmFlags(t, class_)
|
||||||
|
|= (classVmFlags(t, sc) & (ReferenceFlag | WeakReferenceFlag));
|
||||||
}
|
}
|
||||||
|
|
||||||
parseInterfaceTable(t, s, class_, pool);
|
parseInterfaceTable(t, s, class_, pool);
|
||||||
@ -1143,6 +1143,7 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
|||||||
ENTER(t, Thread::ExclusiveState);
|
ENTER(t, Thread::ExclusiveState);
|
||||||
|
|
||||||
classFlags(t, bootstrapClass) = classFlags(t, class_);
|
classFlags(t, bootstrapClass) = classFlags(t, class_);
|
||||||
|
classVmFlags(t, bootstrapClass) |= classVmFlags(t, class_);
|
||||||
|
|
||||||
set(t, classSuper(t, bootstrapClass), classSuper(t, class_));
|
set(t, classSuper(t, bootstrapClass), classSuper(t, class_));
|
||||||
set(t, classInterfaceTable(t, bootstrapClass),
|
set(t, classInterfaceTable(t, bootstrapClass),
|
||||||
@ -1151,7 +1152,6 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
|||||||
set(t, classFieldTable(t, bootstrapClass), classFieldTable(t, class_));
|
set(t, classFieldTable(t, bootstrapClass), classFieldTable(t, class_));
|
||||||
set(t, classMethodTable(t, bootstrapClass), classMethodTable(t, class_));
|
set(t, classMethodTable(t, bootstrapClass), classMethodTable(t, class_));
|
||||||
set(t, classStaticTable(t, bootstrapClass), classStaticTable(t, class_));
|
set(t, classStaticTable(t, bootstrapClass), classStaticTable(t, class_));
|
||||||
set(t, classInitializer(t, bootstrapClass), classInitializer(t, class_));
|
|
||||||
|
|
||||||
object fieldTable = classFieldTable(t, class_);
|
object fieldTable = classFieldTable(t, class_);
|
||||||
if (fieldTable) {
|
if (fieldTable) {
|
||||||
@ -1186,7 +1186,6 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec,
|
|||||||
classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)),
|
classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1376,7 +1375,7 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
|
|
||||||
populateBuiltinMap(t, m->builtinMap);
|
populateBuiltinMap(t, m->builtinMap);
|
||||||
|
|
||||||
t->javaThread = makeThread(t, 0, 0, reinterpret_cast<int64_t>(t));
|
t->javaThread = makeThread(t, 0, 0, 0, reinterpret_cast<int64_t>(t));
|
||||||
} else {
|
} else {
|
||||||
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
|
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
|
||||||
parent->child = this;
|
parent->child = this;
|
||||||
@ -1680,6 +1679,21 @@ instanceOf(Thread* t, object class_, object o)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
classInitializer(Thread* t, object class_)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, class_)); ++i) {
|
||||||
|
object o = arrayBody(t, classMethodTable(t, class_), i);
|
||||||
|
|
||||||
|
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
|
||||||
|
&byteArrayBody(t, methodName(t, o), 0)) == 0)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
parameterFootprint(const char* s)
|
parameterFootprint(const char* s)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ namespace vm {
|
|||||||
const bool Verbose = false;
|
const bool Verbose = false;
|
||||||
const bool DebugRun = false;
|
const bool DebugRun = false;
|
||||||
const bool DebugStack = false;
|
const bool DebugStack = false;
|
||||||
const bool DebugMonitors = false;
|
const bool DebugMonitors = true;
|
||||||
|
|
||||||
const uintptr_t HashTakenMark = 1;
|
const uintptr_t HashTakenMark = 1;
|
||||||
const uintptr_t ExtendedMark = 2;
|
const uintptr_t ExtendedMark = 2;
|
||||||
@ -61,6 +61,7 @@ const int UnknownLine = -2;
|
|||||||
|
|
||||||
const unsigned ReferenceFlag = 1 << 0;
|
const unsigned ReferenceFlag = 1 << 0;
|
||||||
const unsigned WeakReferenceFlag = 1 << 1;
|
const unsigned WeakReferenceFlag = 1 << 1;
|
||||||
|
const unsigned NeedInitFlag = 1 << 2;
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
@ -1487,6 +1488,9 @@ isAssignableFrom(Thread* t, object a, object b);
|
|||||||
bool
|
bool
|
||||||
instanceOf(Thread* t, object class_, object o);
|
instanceOf(Thread* t, object class_, object o);
|
||||||
|
|
||||||
|
object
|
||||||
|
classInitializer(Thread* t, object class_);
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
pushObject(Thread* t, object o)
|
pushObject(Thread* t, object o)
|
||||||
{
|
{
|
||||||
|
49
src/run.cpp
49
src/run.cpp
@ -76,13 +76,6 @@ popFrame(Thread* t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
|
||||||
setStatic(Thread* t, object field, object value)
|
|
||||||
{
|
|
||||||
set(t, arrayBody(t, classStaticTable(t, fieldClass(t, field)),
|
|
||||||
fieldOffset(t, field)), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
object
|
object
|
||||||
findInterfaceMethod(Thread* t, object method, object o)
|
findInterfaceMethod(Thread* t, object method, object o)
|
||||||
{
|
{
|
||||||
@ -908,10 +901,9 @@ run(Thread* t)
|
|||||||
object field = resolveField(t, codePool(t, code), index - 1);
|
object field = resolveField(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, fieldClass(t, field));
|
if (classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) {
|
||||||
if (clinit) {
|
classVmFlags(t, fieldClass(t, field)) &= ~NeedInitFlag;
|
||||||
set(t, classInitializer(t, fieldClass(t, field)), 0);
|
code = classInitializer(t, fieldClass(t, field));
|
||||||
code = clinit;
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
goto invoke;
|
goto invoke;
|
||||||
}
|
}
|
||||||
@ -1332,10 +1324,9 @@ run(Thread* t)
|
|||||||
resolveClass(t, className(t, class_));
|
resolveClass(t, className(t, class_));
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, class_);
|
if (classVmFlags(t, class_) & NeedInitFlag) {
|
||||||
if (clinit) {
|
classVmFlags(t, class_) &= ~NeedInitFlag;
|
||||||
set(t, classInitializer(t, methodClass(t, method)), 0);
|
code = classInitializer(t, class_);
|
||||||
code = clinit;
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
goto invoke;
|
goto invoke;
|
||||||
}
|
}
|
||||||
@ -1361,10 +1352,9 @@ run(Thread* t)
|
|||||||
object method = resolveMethod(t, codePool(t, code), index - 1);
|
object method = resolveMethod(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, methodClass(t, method));
|
if (classVmFlags(t, methodClass(t, method)) & NeedInitFlag) {
|
||||||
if (clinit) {
|
classVmFlags(t, methodClass(t, method)) &= ~NeedInitFlag;
|
||||||
set(t, classInitializer(t, methodClass(t, method)), 0);
|
code = classInitializer(t, methodClass(t, method));
|
||||||
code = clinit;
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
goto invoke;
|
goto invoke;
|
||||||
}
|
}
|
||||||
@ -1390,10 +1380,9 @@ run(Thread* t)
|
|||||||
resolveClass(t, className(t, class_));
|
resolveClass(t, className(t, class_));
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, class_);
|
if (classVmFlags(t, class_) & NeedInitFlag) {
|
||||||
if (clinit) {
|
classVmFlags(t, class_) &= ~NeedInitFlag;
|
||||||
set(t, classInitializer(t, methodClass(t, method)), 0);
|
code = classInitializer(t, class_);
|
||||||
code = clinit;
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
goto invoke;
|
goto invoke;
|
||||||
}
|
}
|
||||||
@ -1774,10 +1763,9 @@ run(Thread* t)
|
|||||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, class_);
|
if (classVmFlags(t, class_) & NeedInitFlag) {
|
||||||
if (clinit) {
|
classVmFlags(t, class_) &= ~NeedInitFlag;
|
||||||
set(t, classInitializer(t, class_), 0);
|
code = classInitializer(t, class_);
|
||||||
code = clinit;
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
goto invoke;
|
goto invoke;
|
||||||
}
|
}
|
||||||
@ -1922,10 +1910,9 @@ run(Thread* t)
|
|||||||
object field = resolveField(t, codePool(t, code), index - 1);
|
object field = resolveField(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
object clinit = classInitializer(t, fieldClass(t, field));
|
if (classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) {
|
||||||
if (clinit) {
|
classVmFlags(t, fieldClass(t, field)) &= ~NeedInitFlag;
|
||||||
set(t, classInitializer(t, fieldClass(t, field)), 0);
|
code = classInitializer(t, fieldClass(t, field));
|
||||||
code = clinit;
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
goto invoke;
|
goto invoke;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,15 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
now()
|
||||||
|
{
|
||||||
|
timeval tv = { 0, 0 };
|
||||||
|
gettimeofday(&tv, 0);
|
||||||
|
return (static_cast<int64_t>(tv.tv_sec) * 1000) +
|
||||||
|
(static_cast<int64_t>(tv.tv_usec) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
run(void* t)
|
run(void* t)
|
||||||
{
|
{
|
||||||
@ -174,10 +183,10 @@ class MySystem: public System {
|
|||||||
this->depth = 0;
|
this->depth = 0;
|
||||||
this->context = 0;
|
this->context = 0;
|
||||||
if (time) {
|
if (time) {
|
||||||
int64_t then = s->now() + time;
|
int64_t then = now() + time;
|
||||||
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 };
|
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 };
|
||||||
int rv = pthread_cond_timedwait(&condition, &mutex, &ts);
|
int rv = pthread_cond_timedwait(&condition, &mutex, &ts);
|
||||||
assert(s, rv == 0);
|
assert(s, rv == 0 or rv == ETIMEDOUT);
|
||||||
} else {
|
} else {
|
||||||
int rv = pthread_cond_wait(&condition, &mutex);
|
int rv = pthread_cond_wait(&condition, &mutex);
|
||||||
assert(s, rv == 0);
|
assert(s, rv == 0);
|
||||||
@ -342,19 +351,6 @@ class MySystem: public System {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void sleep(int64_t milliseconds) {
|
|
||||||
timespec ts = { milliseconds / 1000, (milliseconds % 1000) * 1000 * 1000 };
|
|
||||||
|
|
||||||
nanosleep(&ts, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int64_t now() {
|
|
||||||
timeval tv = { 0, 0 };
|
|
||||||
gettimeofday(&tv, 0);
|
|
||||||
return (static_cast<int64_t>(tv.tv_sec) * 1000) +
|
|
||||||
(static_cast<int64_t>(tv.tv_usec) / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
||||||
unsigned count, unsigned size, unsigned returnType)
|
unsigned count, unsigned size, unsigned returnType)
|
||||||
{
|
{
|
||||||
|
@ -60,8 +60,6 @@ class System: public Allocator {
|
|||||||
virtual Status attach(Thread**) = 0;
|
virtual Status attach(Thread**) = 0;
|
||||||
virtual Status start(Runnable*) = 0;
|
virtual Status start(Runnable*) = 0;
|
||||||
virtual Status make(Monitor**) = 0;
|
virtual Status make(Monitor**) = 0;
|
||||||
virtual void sleep(int64_t milliseconds) = 0;
|
|
||||||
virtual int64_t now() = 0;
|
|
||||||
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
||||||
unsigned count, unsigned size,
|
unsigned count, unsigned size,
|
||||||
unsigned returnType) = 0;
|
unsigned returnType) = 0;
|
||||||
|
@ -1488,7 +1488,7 @@ writeInitialization(Output* out, Object* type)
|
|||||||
out->write(typeFixedSize(type));
|
out->write(typeFixedSize(type));
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(typeArrayElementSize(type));
|
out->write(typeArrayElementSize(type));
|
||||||
out->write(", mask, 0, super, 0, 0, 0, 0, 0, 0);\n");
|
out->write(", mask, 0, super, 0, 0, 0, 0, 0);\n");
|
||||||
|
|
||||||
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write(capitalize(typeName(type)));
|
out->write(capitalize(typeName(type)));
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
(object virtualTable)
|
(object virtualTable)
|
||||||
(object fieldTable)
|
(object fieldTable)
|
||||||
(object methodTable)
|
(object methodTable)
|
||||||
(object staticTable)
|
(object staticTable))
|
||||||
(object initializer))
|
|
||||||
|
|
||||||
(type accessibleObject java/lang/reflect/AccessibleObject
|
(type accessibleObject java/lang/reflect/AccessibleObject
|
||||||
(extends jobject))
|
(extends jobject))
|
||||||
@ -128,6 +127,7 @@
|
|||||||
(extends jobject)
|
(extends jobject)
|
||||||
(object task)
|
(object task)
|
||||||
(object locals)
|
(object locals)
|
||||||
|
(object sleepLock)
|
||||||
(int64_t peer))
|
(int64_t peer))
|
||||||
|
|
||||||
(type stackTraceElement java/lang/StackTraceElement
|
(type stackTraceElement java/lang/StackTraceElement
|
||||||
|
Loading…
Reference in New Issue
Block a user