Permalink
Browse files

code rearrangment to improve state of Android libcore tests

This mainly moves several sun.misc.Unsafe method implementations from
classpath-openjdk.cpp to builtin.cpp so that the Avian and Android
builds can use them.

It also replaces FinalizerReference.finalizeAllEnqueued with a no-op,
since the real implementations assumes too much about how the VM
handles (or delegates) finalization.
  • Loading branch information...
dicej committed Apr 23, 2013
1 parent dfdd1f6 commit 4e12847858b7ddaaecdfd5e1ef2696b44a5d735e
@@ -406,6 +406,41 @@ public static int findMethod(VMClass vmClass, String name,
return -1;
}
+ public static int countMethods(VMClass vmClass, boolean publicOnly) {
+ int count = 0;
+ if (vmClass.methodTable != null) {
+ for (int i = 0; i < vmClass.methodTable.length; ++i) {
+ if (((! publicOnly)
+ || ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
+ != 0)
+ && (! toString(vmClass.methodTable[i].name).startsWith("<")))
+ {
+ ++ count;
+ }
+ }
+ }
+ return count;
+ }
+
+ public static Method[] getMethods(VMClass vmClass, boolean publicOnly) {
+ Method[] array = new Method[countMethods(vmClass, publicOnly)];
+ if (vmClass.methodTable != null) {
+ Classes.link(vmClass);
+
+ int ai = 0;
+ for (int i = 0; i < vmClass.methodTable.length; ++i) {
+ if ((((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
+ || (! publicOnly))
+ && ! toString(vmClass.methodTable[i].name).startsWith("<"))
+ {
+ array[ai++] = makeMethod(SystemClassLoader.getClass(vmClass), i);
+ }
+ }
+ }
+
+ return array;
+ }
+
public static Annotation getAnnotation(ClassLoader loader, Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
@@ -366,54 +366,12 @@ private static void getAllFields(VMClass vmClass, ArrayList<Field> fields) {
return fields.toArray(new Field[fields.size()]);
}
- private int countMethods(boolean publicOnly) {
- int count = 0;
- if (vmClass.methodTable != null) {
- for (int i = 0; i < vmClass.methodTable.length; ++i) {
- if (((! publicOnly)
- || ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
- != 0)
- && (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
- {
- ++ count;
- }
- }
- }
- return count;
- }
-
public Method[] getDeclaredMethods() {
- Method[] array = new Method[countMethods(false)];
- if (vmClass.methodTable != null) {
- Classes.link(vmClass);
-
- int ai = 0;
- for (int i = 0; i < vmClass.methodTable.length; ++i) {
- if (! Method.getName(vmClass.methodTable[i]).startsWith("<")) {
- array[ai++] = new Method(vmClass.methodTable[i]);
- }
- }
- }
-
- return array;
+ return Classes.getMethods(vmClass, false);
}
public Method[] getMethods() {
- Method[] array = new Method[countMethods(true)];
- if (vmClass.methodTable != null) {
- Classes.link(vmClass);
-
- int index = 0;
- for (int i = 0; i < vmClass.methodTable.length; ++i) {
- if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
- && (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
- {
- array[index++] = new Method(vmClass.methodTable[i]);
- }
- }
- }
-
- return array;
+ return Classes.getMethods(vmClass, true);
}
public Class[] getInterfaces() {
@@ -591,7 +549,7 @@ private int countAnnotations() {
}
public Annotation[] getAnnotations() {
- Annotation[] array = new Annotation[countMethods(true)];
+ Annotation[] array = new Annotation[countAnnotations()];
int i = 0;
for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) {
@@ -46,6 +46,14 @@ public static Unsafe getUnsafe() {
public native void putDouble(long address, double x);
+ public native void putIntVolatile(Object o, long offset, int x);
+
+ public native void putOrderedInt(Object o, long offset, int x);
+
+ public native Object getObject(Object o, long offset);
+
+ public native void putObject(Object o, long offset, Object x);
+
public native long getAddress(long address);
public native void putAddress(long address, long x);
@@ -54,13 +62,20 @@ public static Unsafe getUnsafe() {
public native long objectFieldOffset(Field field);
+ public native void park(boolean absolute, long time);
+
+ public native void unpark(Object target);
+
public native void copyMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long count);
public native boolean compareAndSwapInt(Object o, long offset, int old,
int new_);
+ public native boolean compareAndSwapObject(Object o, long offset, Object old,
+ Object new_);
+
public void copyMemory(long src, long dst, long count) {
copyMemory(null, src, null, dst, count);
}
View
@@ -3942,6 +3942,18 @@ lineNumberLine(uint64_t ln)
return ln & 0xFFFFFFFF;
}
+object
+interruptLock(Thread* t, object thread);
+
+void
+clearInterrupted(Thread* t);
+
+void
+threadInterrupt(Thread* t, object thread);
+
+bool
+threadIsInterrupted(Thread* t, object thread, bool clear);
+
inline FILE*
errorLog(Thread* t)
{
View
@@ -604,6 +604,46 @@ Avian_java_nio_FixedArrayByteBuffer_allocateFixed
return reinterpret_cast<intptr_t>(array);
}
+extern "C" JNIEXPORT int64_t JNICALL
+Avian_sun_misc_Unsafe_getObject
+(Thread*, object, uintptr_t* arguments)
+{
+ object o = reinterpret_cast<object>(arguments[1]);
+ int64_t offset; memcpy(&offset, arguments + 2, 8);
+
+ return fieldAtOffset<uintptr_t>(o, offset);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Avian_sun_misc_Unsafe_putObject
+(Thread* t, object, uintptr_t* arguments)
+{
+ object o = reinterpret_cast<object>(arguments[1]);
+ int64_t offset; memcpy(&offset, arguments + 2, 8);
+ uintptr_t value = arguments[4];
+
+ set(t, o, offset, reinterpret_cast<object>(value));
+}
+
+extern "C" JNIEXPORT int64_t JNICALL
+Avian_sun_misc_Unsafe_compareAndSwapObject
+(Thread* t, object, uintptr_t* arguments)
+{
+ object target = reinterpret_cast<object>(arguments[1]);
+ int64_t offset; memcpy(&offset, arguments + 2, 8);
+ uintptr_t expect = arguments[4];
+ uintptr_t update = arguments[5];
+
+ bool success = atomicCompareAndSwap
+ (&fieldAtOffset<uintptr_t>(target, offset), expect, update);
+
+ if (success) {
+ mark(t, target, offset);
+ }
+
+ return success;
+}
+
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_compareAndSwapInt
(Thread*, object, uintptr_t* arguments)
@@ -617,6 +657,77 @@ Avian_sun_misc_Unsafe_compareAndSwapInt
(&fieldAtOffset<uint32_t>(target, offset), expect, update);
}
+extern "C" JNIEXPORT void JNICALL
+Avian_sun_misc_Unsafe_unpark
+(Thread* t, object, uintptr_t* arguments)
+{
+ object thread = reinterpret_cast<object>(arguments[1]);
+
+ monitorAcquire(t, interruptLock(t, thread));
+ threadUnparked(t, thread) = true;
+ monitorNotify(t, interruptLock(t, thread));
+ monitorRelease(t, interruptLock(t, thread));
+}
+
+extern "C" JNIEXPORT void JNICALL
+Avian_sun_misc_Unsafe_park
+(Thread* t, object, uintptr_t* arguments)
+{
+ bool absolute = arguments[1];
+ int64_t time; memcpy(&time, arguments + 2, 8);
+
+ int64_t then = t->m->system->now();
+
+ if (absolute) {
+ time -= then;
+ if (time <= 0) {
+ return;
+ }
+ } else if (time) {
+ // if not absolute, interpret time as nanoseconds, but make sure
+ // it doesn't become zero when we convert to milliseconds, since
+ // zero is interpreted as infinity below
+ time = (time / (1000 * 1000)) + 1;
+ }
+
+ monitorAcquire(t, interruptLock(t, t->javaThread));
+ while (time >= 0
+ and (not (threadUnparked(t, t->javaThread)
+ or monitorWait
+ (t, interruptLock(t, t->javaThread), time))))
+ {
+ int64_t now = t->m->system->now();
+ time -= now - then;
+ then = now;
+
+ if (time == 0) {
+ break;
+ }
+ }
+ threadUnparked(t, t->javaThread) = false;
+ monitorRelease(t, interruptLock(t, t->javaThread));
+}
+
+extern "C" JNIEXPORT void JNICALL
+Avian_sun_misc_Unsafe_putIntVolatile
+(Thread*, object, uintptr_t* arguments)
+{
+ object o = reinterpret_cast<object>(arguments[1]);
+ int64_t offset; memcpy(&offset, arguments + 2, 8);
+ int32_t value = arguments[4];
+
+ storeStoreMemoryBarrier();
+ fieldAtOffset<int32_t>(o, offset) = value;
+ storeLoadMemoryBarrier();
+}
+
+extern "C" JNIEXPORT void JNICALL
+Avian_sun_misc_Unsafe_putOrderedInt
+(Thread* t, object method, uintptr_t* arguments)
+{
+ Avian_sun_misc_Unsafe_putIntVolatile(t, method, arguments);
+}
+
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_primitiveClass
(Thread* t, object, uintptr_t* arguments)
View
@@ -48,6 +48,12 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
loadLibrary(t, "", RUNTIME_ARRAY_BODY(n), true, true);
}
+void JNICALL
+finalizeAllEnqueued(Thread*, object, uintptr_t*)
+{
+ // ignore
+}
+
int64_t JNICALL
appLoader(Thread* t, object, uintptr_t*)
{
@@ -150,6 +156,11 @@ initVmThread(Thread* t, object thread)
set(t, thread, fieldOffset(t, field), instance);
}
+
+ if (threadGroup(t, thread) == 0) {
+ set(t, thread, ThreadGroup, threadGroup(t, t->javaThread));
+ expect(t, threadGroup(t, thread));
+ }
}
object
@@ -352,6 +363,18 @@ class MyClasspath : public Classpath {
}
}
+ { object c = resolveClass
+ (t, root(t, Machine::BootLoader), "java/lang/ref/FinalizerReference",
+ false);
+
+ if (c) {
+ PROTECT(t, c);
+
+ intercept(t, c, "finalizeAllEnqueued", "()V",
+ voidPointer(finalizeAllEnqueued), updateRuntimeData);
+ }
+ }
+
{ object c = resolveClass
(t, root(t, Machine::BootLoader), "java/lang/ClassLoader", false);
@@ -1071,7 +1094,7 @@ Avian_java_lang_VMThread_getStatus
(Thread*, object, uintptr_t*)
{
// todo
- return -1;
+ return 1;
}
extern "C" JNIEXPORT int64_t JNICALL
@@ -1381,6 +1404,23 @@ Avian_java_lang_Class_isInstance
}
}
+extern "C" JNIEXPORT int64_t JNICALL
+Avian_java_lang_Class_getDeclaredMethods
+(Thread* t, object, uintptr_t* arguments)
+{
+ object c = reinterpret_cast<object>(arguments[0]);
+ PROTECT(t, c);
+
+ bool publicOnly = arguments[1];
+
+ object get = resolveMethod
+ (t, root(t, Machine::BootLoader), "avian/Classes", "getMethods",
+ "(Lavian/VMClass;Z)[Ljava/lang/reflect/Method;");
+
+ return reinterpret_cast<uintptr_t>
+ (t->m->processor->invoke(t, get, 0, jclassVmClass(t, c), publicOnly));
+}
+
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_invokeNative
(Thread* t, object, uintptr_t* arguments)
View
@@ -661,7 +661,7 @@ Avian_java_lang_Thread_interrupt
{
int64_t peer; memcpy(&peer, arguments, 8);
- interrupt(t, reinterpret_cast<Thread*>(peer));
+ threadInterrupt(t, reinterpret_cast<Thread*>(peer)->javaThread);
}
extern "C" JNIEXPORT int64_t JNICALL
@@ -670,7 +670,8 @@ Avian_java_lang_Thread_interrupted
{
int64_t peer; memcpy(&peer, arguments, 8);
- return getAndClearInterrupted(t, reinterpret_cast<Thread*>(peer));
+ return threadIsInterrupted
+ (t, reinterpret_cast<Thread*>(peer)->javaThread, true);
}
extern "C" JNIEXPORT int64_t JNICALL
Oops, something went wrong.

0 comments on commit 4e12847

Please sign in to comment.