mirror of
https://github.com/corda/corda.git
synced 2025-06-12 04:08:26 +00:00
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.
This commit is contained in:
@ -406,6 +406,41 @@ public class Classes {
|
|||||||
return -1;
|
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) {
|
public static Annotation getAnnotation(ClassLoader loader, Object[] a) {
|
||||||
if (a[0] == null) {
|
if (a[0] == null) {
|
||||||
a[0] = Proxy.newProxyInstance
|
a[0] = Proxy.newProxyInstance
|
||||||
|
@ -366,54 +366,12 @@ public final class Class <T> implements Type, AnnotatedElement {
|
|||||||
return fields.toArray(new Field[fields.size()]);
|
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() {
|
public Method[] getDeclaredMethods() {
|
||||||
Method[] array = new Method[countMethods(false)];
|
return Classes.getMethods(vmClass, 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method[] getMethods() {
|
public Method[] getMethods() {
|
||||||
Method[] array = new Method[countMethods(true)];
|
return Classes.getMethods(vmClass, 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getInterfaces() {
|
public Class[] getInterfaces() {
|
||||||
@ -591,7 +549,7 @@ public final class Class <T> implements Type, AnnotatedElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Annotation[] getAnnotations() {
|
public Annotation[] getAnnotations() {
|
||||||
Annotation[] array = new Annotation[countMethods(true)];
|
Annotation[] array = new Annotation[countAnnotations()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (VMClass c = vmClass; c != null; c = c.super_) {
|
for (VMClass c = vmClass; c != null; c = c.super_) {
|
||||||
if (c.addendum != null && c.addendum.annotationTable != null) {
|
if (c.addendum != null && c.addendum.annotationTable != null) {
|
||||||
|
@ -46,6 +46,14 @@ public final class Unsafe {
|
|||||||
|
|
||||||
public native void putDouble(long address, double x);
|
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 long getAddress(long address);
|
||||||
|
|
||||||
public native void putAddress(long address, long x);
|
public native void putAddress(long address, long x);
|
||||||
@ -54,6 +62,10 @@ public final class Unsafe {
|
|||||||
|
|
||||||
public native long objectFieldOffset(Field field);
|
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,
|
public native void copyMemory(Object srcBase, long srcOffset,
|
||||||
Object destBase, long destOffset,
|
Object destBase, long destOffset,
|
||||||
long count);
|
long count);
|
||||||
@ -61,6 +73,9 @@ public final class Unsafe {
|
|||||||
public native boolean compareAndSwapInt(Object o, long offset, int old,
|
public native boolean compareAndSwapInt(Object o, long offset, int old,
|
||||||
int new_);
|
int new_);
|
||||||
|
|
||||||
|
public native boolean compareAndSwapObject(Object o, long offset, Object old,
|
||||||
|
Object new_);
|
||||||
|
|
||||||
public void copyMemory(long src, long dst, long count) {
|
public void copyMemory(long src, long dst, long count) {
|
||||||
copyMemory(null, src, null, dst, count);
|
copyMemory(null, src, null, dst, count);
|
||||||
}
|
}
|
||||||
|
@ -3942,6 +3942,18 @@ lineNumberLine(uint64_t ln)
|
|||||||
return ln & 0xFFFFFFFF;
|
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*
|
inline FILE*
|
||||||
errorLog(Thread* t)
|
errorLog(Thread* t)
|
||||||
{
|
{
|
||||||
|
111
src/builtin.cpp
111
src/builtin.cpp
@ -604,6 +604,46 @@ Avian_java_nio_FixedArrayByteBuffer_allocateFixed
|
|||||||
return reinterpret_cast<intptr_t>(array);
|
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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_sun_misc_Unsafe_compareAndSwapInt
|
Avian_sun_misc_Unsafe_compareAndSwapInt
|
||||||
(Thread*, object, uintptr_t* arguments)
|
(Thread*, object, uintptr_t* arguments)
|
||||||
@ -617,6 +657,77 @@ Avian_sun_misc_Unsafe_compareAndSwapInt
|
|||||||
(&fieldAtOffset<uint32_t>(target, offset), expect, update);
|
(&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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_avian_Classes_primitiveClass
|
Avian_avian_Classes_primitiveClass
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
@ -48,6 +48,12 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
|
|||||||
loadLibrary(t, "", RUNTIME_ARRAY_BODY(n), true, true);
|
loadLibrary(t, "", RUNTIME_ARRAY_BODY(n), true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JNICALL
|
||||||
|
finalizeAllEnqueued(Thread*, object, uintptr_t*)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
int64_t JNICALL
|
int64_t JNICALL
|
||||||
appLoader(Thread* t, object, uintptr_t*)
|
appLoader(Thread* t, object, uintptr_t*)
|
||||||
{
|
{
|
||||||
@ -150,6 +156,11 @@ initVmThread(Thread* t, object thread)
|
|||||||
|
|
||||||
set(t, thread, fieldOffset(t, field), instance);
|
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
|
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
|
{ object c = resolveClass
|
||||||
(t, root(t, Machine::BootLoader), "java/lang/ClassLoader", false);
|
(t, root(t, Machine::BootLoader), "java/lang/ClassLoader", false);
|
||||||
|
|
||||||
@ -1071,7 +1094,7 @@ Avian_java_lang_VMThread_getStatus
|
|||||||
(Thread*, object, uintptr_t*)
|
(Thread*, object, uintptr_t*)
|
||||||
{
|
{
|
||||||
// todo
|
// todo
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_java_lang_reflect_Method_invokeNative
|
Avian_java_lang_reflect_Method_invokeNative
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
@ -661,7 +661,7 @@ Avian_java_lang_Thread_interrupt
|
|||||||
{
|
{
|
||||||
int64_t peer; memcpy(&peer, arguments, 8);
|
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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
@ -670,7 +670,8 @@ Avian_java_lang_Thread_interrupted
|
|||||||
{
|
{
|
||||||
int64_t peer; memcpy(&peer, arguments, 8);
|
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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
@ -2461,38 +2461,6 @@ setProperty(Thread* t, object method, object properties,
|
|||||||
t->m->processor->invoke(t, method, properties, n, v);
|
t->m->processor->invoke(t, method, properties, n, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
|
||||||
interruptLock(Thread* t, object thread)
|
|
||||||
{
|
|
||||||
object lock = threadInterruptLock(t, thread);
|
|
||||||
|
|
||||||
loadMemoryBarrier();
|
|
||||||
|
|
||||||
if (lock == 0) {
|
|
||||||
PROTECT(t, thread);
|
|
||||||
ACQUIRE(t, t->m->referenceLock);
|
|
||||||
|
|
||||||
if (threadInterruptLock(t, thread) == 0) {
|
|
||||||
object head = makeMonitorNode(t, 0, 0);
|
|
||||||
object lock = makeMonitor(t, 0, 0, 0, head, head, 0);
|
|
||||||
|
|
||||||
storeStoreMemoryBarrier();
|
|
||||||
|
|
||||||
set(t, thread, ThreadInterruptLock, lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return threadInterruptLock(t, thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clearInterrupted(Thread* t)
|
|
||||||
{
|
|
||||||
monitorAcquire(t, local::interruptLock(t, t->javaThread));
|
|
||||||
threadInterrupted(t, t->javaThread) = false;
|
|
||||||
monitorRelease(t, local::interruptLock(t, t->javaThread));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pipeAvailable(int fd, int* available)
|
pipeAvailable(int fd, int* available)
|
||||||
{
|
{
|
||||||
@ -2724,27 +2692,6 @@ Avian_sun_misc_Unsafe_objectFieldOffset
|
|||||||
(t, jclassVmClass(t, jfieldClazz(t, jfield))), jfieldSlot(t, jfield)));
|
(t, jclassVmClass(t, jfieldClazz(t, jfield))), jfieldSlot(t, jfield)));
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J
|
Avian_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J
|
||||||
(Thread*, object, uintptr_t* arguments)
|
(Thread*, object, uintptr_t* arguments)
|
||||||
@ -2959,25 +2906,6 @@ Avian_sun_misc_Unsafe_putOrderedObject
|
|||||||
Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments);
|
Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_sun_misc_Unsafe_compareAndSwapLong
|
Avian_sun_misc_Unsafe_compareAndSwapLong
|
||||||
(Thread* t UNUSED, object, uintptr_t* arguments)
|
(Thread* t UNUSED, object, uintptr_t* arguments)
|
||||||
@ -3015,57 +2943,6 @@ Avian_sun_misc_Unsafe_ensureClassInitialized
|
|||||||
initClass(t, jclassVmClass(t, reinterpret_cast<object>(arguments[1])));
|
initClass(t, jclassVmClass(t, reinterpret_cast<object>(arguments[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
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, local::interruptLock(t, thread));
|
|
||||||
threadUnparked(t, thread) = true;
|
|
||||||
monitorNotify(t, local::interruptLock(t, thread));
|
|
||||||
monitorRelease(t, local::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, local::interruptLock(t, t->javaThread));
|
|
||||||
while (time >= 0
|
|
||||||
and (not (threadUnparked(t, t->javaThread)
|
|
||||||
or monitorWait
|
|
||||||
(t, local::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, local::interruptLock(t, t->javaThread));
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Avian_sun_misc_Unsafe_monitorEnter
|
Avian_sun_misc_Unsafe_monitorEnter
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
@ -3635,15 +3512,7 @@ EXPORT(JVM_CountStackFrames)(Thread*, jobject) { abort(); }
|
|||||||
uint64_t
|
uint64_t
|
||||||
jvmInterrupt(Thread* t, uintptr_t* arguments)
|
jvmInterrupt(Thread* t, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
jobject thread = reinterpret_cast<jobject>(arguments[0]);
|
threadInterrupt(t, *reinterpret_cast<jobject>(arguments[0]));
|
||||||
|
|
||||||
monitorAcquire(t, local::interruptLock(t, *thread));
|
|
||||||
Thread* p = reinterpret_cast<Thread*>(threadPeer(t, *thread));
|
|
||||||
if (p) {
|
|
||||||
interrupt(t, p);
|
|
||||||
}
|
|
||||||
threadInterrupted(t, *thread) = true;
|
|
||||||
monitorRelease(t, local::interruptLock(t, *thread));
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3662,14 +3531,7 @@ jvmIsInterrupted(Thread* t, uintptr_t* arguments)
|
|||||||
jobject thread = reinterpret_cast<jobject>(arguments[0]);
|
jobject thread = reinterpret_cast<jobject>(arguments[0]);
|
||||||
jboolean clear = arguments[1];
|
jboolean clear = arguments[1];
|
||||||
|
|
||||||
monitorAcquire(t, local::interruptLock(t, *thread));
|
return threadIsInterrupted(t, *thread, clear);
|
||||||
bool v = threadInterrupted(t, *thread);
|
|
||||||
if (clear) {
|
|
||||||
threadInterrupted(t, *thread) = false;
|
|
||||||
}
|
|
||||||
monitorRelease(t, local::interruptLock(t, *thread));
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
|
@ -5186,6 +5186,67 @@ populateMultiArray(Thread* t, object array, int32_t* counts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
interruptLock(Thread* t, object thread)
|
||||||
|
{
|
||||||
|
object lock = threadInterruptLock(t, thread);
|
||||||
|
|
||||||
|
loadMemoryBarrier();
|
||||||
|
|
||||||
|
if (lock == 0) {
|
||||||
|
PROTECT(t, thread);
|
||||||
|
ACQUIRE(t, t->m->referenceLock);
|
||||||
|
|
||||||
|
if (threadInterruptLock(t, thread) == 0) {
|
||||||
|
object head = makeMonitorNode(t, 0, 0);
|
||||||
|
object lock = makeMonitor(t, 0, 0, 0, head, head, 0);
|
||||||
|
|
||||||
|
storeStoreMemoryBarrier();
|
||||||
|
|
||||||
|
set(t, thread, ThreadInterruptLock, lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return threadInterruptLock(t, thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearInterrupted(Thread* t)
|
||||||
|
{
|
||||||
|
monitorAcquire(t, interruptLock(t, t->javaThread));
|
||||||
|
threadInterrupted(t, t->javaThread) = false;
|
||||||
|
monitorRelease(t, interruptLock(t, t->javaThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
threadInterrupt(Thread* t, object thread)
|
||||||
|
{
|
||||||
|
PROTECT(t, thread);
|
||||||
|
|
||||||
|
monitorAcquire(t, interruptLock(t, thread));
|
||||||
|
Thread* p = reinterpret_cast<Thread*>(threadPeer(t, thread));
|
||||||
|
if (p) {
|
||||||
|
interrupt(t, p);
|
||||||
|
}
|
||||||
|
threadInterrupted(t, thread) = true;
|
||||||
|
monitorRelease(t, interruptLock(t, thread));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
threadIsInterrupted(Thread* t, object thread, bool clear)
|
||||||
|
{
|
||||||
|
PROTECT(t, thread);
|
||||||
|
|
||||||
|
monitorAcquire(t, interruptLock(t, thread));
|
||||||
|
bool v = threadInterrupted(t, thread);
|
||||||
|
if (clear) {
|
||||||
|
threadInterrupted(t, thread) = false;
|
||||||
|
}
|
||||||
|
monitorRelease(t, interruptLock(t, thread));
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
noop()
|
noop()
|
||||||
{ }
|
{ }
|
||||||
|
Reference in New Issue
Block a user