1 // natUnsafe.cc - Implementation of sun.misc.Unsafe native methods.
4 Free Software Foundation
6 This file is part of libgcj.
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
13 #include <gcj/field.h>
14 #include <gcj/javaprims.h>
16 #include <sun/misc/Unsafe.h>
17 #include <java/lang/System.h>
18 #include <java/lang/InterruptedException.h>
20 #include <java/lang/Thread.h>
21 #include <java/lang/Long.h>
23 #include "sysdep/locks.h"
25 // Use a spinlock for multi-word accesses
28 static volatile obj_addr_t lock;
34 while (! compare_and_swap (&lock, 0, 1))
39 release_set (&lock, 0);
43 // This is a single lock that is used for all synchronized accesses if
44 // the compiler can't generate inline compare-and-swap operations. In
45 // most cases it'll never be used, but the i386 needs it for 64-bit
46 // locked accesses and so does PPC32. It's worth building libgcj with
47 // target=i486 (or above) to get the inlines.
48 volatile obj_addr_t spinlock::lock;
52 compareAndSwap (volatile jint *addr, jint old, jint new_val)
54 jboolean result = false;
56 if ((result = (*addr == old)))
62 compareAndSwap (volatile jlong *addr, jlong old, jlong new_val)
64 jboolean result = false;
66 if ((result = (*addr == old)))
72 compareAndSwap (volatile jobject *addr, jobject old, jobject new_val)
74 jboolean result = false;
76 if ((result = (*addr == old)))
83 sun::misc::Unsafe::objectFieldOffset (::java::lang::reflect::Field *field)
85 _Jv_Field *fld = _Jv_FromReflectedField (field);
86 // FIXME: what if it is not an instance field?
87 return fld->getOffset();
91 sun::misc::Unsafe::arrayBaseOffset (jclass arrayClass)
93 // FIXME: assert that arrayClass is array.
94 jclass eltClass = arrayClass->getComponentType();
95 return (jint)(jlong) _Jv_GetArrayElementFromElementType (NULL, eltClass);
99 sun::misc::Unsafe::arrayIndexScale (jclass arrayClass)
101 // FIXME: assert that arrayClass is array.
102 jclass eltClass = arrayClass->getComponentType();
103 if (eltClass->isPrimitive())
104 return eltClass->size();
105 return sizeof (void *);
108 // These methods are used when the compiler fails to generate inline
109 // versions of the compare-and-swap primitives.
112 sun::misc::Unsafe::compareAndSwapInt (jobject obj, jlong offset,
113 jint expect, jint update)
115 jint *addr = (jint *)((char *)obj + offset);
116 return compareAndSwap (addr, expect, update);
120 sun::misc::Unsafe::compareAndSwapLong (jobject obj, jlong offset,
121 jlong expect, jlong update)
123 volatile jlong *addr = (jlong*)((char *) obj + offset);
124 return compareAndSwap (addr, expect, update);
128 sun::misc::Unsafe::compareAndSwapObject (jobject obj, jlong offset,
129 jobject expect, jobject update)
131 jobject *addr = (jobject*)((char *) obj + offset);
132 return compareAndSwap (addr, expect, update);
136 sun::misc::Unsafe::putOrderedInt (jobject obj, jlong offset, jint value)
138 volatile jint *addr = (jint *) ((char *) obj + offset);
143 sun::misc::Unsafe::putOrderedLong (jobject obj, jlong offset, jlong value)
145 volatile jlong *addr = (jlong *) ((char *) obj + offset);
151 sun::misc::Unsafe::putOrderedObject (jobject obj, jlong offset, jobject value)
153 volatile jobject *addr = (jobject *) ((char *) obj + offset);
158 sun::misc::Unsafe::putIntVolatile (jobject obj, jlong offset, jint value)
161 volatile jint *addr = (jint *) ((char *) obj + offset);
166 sun::misc::Unsafe::putLongVolatile (jobject obj, jlong offset, jlong value)
168 volatile jlong *addr = (jlong *) ((char *) obj + offset);
174 sun::misc::Unsafe::putObjectVolatile (jobject obj, jlong offset, jobject value)
177 volatile jobject *addr = (jobject *) ((char *) obj + offset);
183 sun::misc::Unsafe::putInt (jobject obj, jlong offset, jint value)
185 jint *addr = (jint *) ((char *) obj + offset);
191 sun::misc::Unsafe::putLong (jobject obj, jlong offset, jlong value)
193 jlong *addr = (jlong *) ((char *) obj + offset);
199 sun::misc::Unsafe::putObject (jobject obj, jlong offset, jobject value)
201 jobject *addr = (jobject *) ((char *) obj + offset);
206 sun::misc::Unsafe::getIntVolatile (jobject obj, jlong offset)
208 volatile jint *addr = (jint *) ((char *) obj + offset);
215 sun::misc::Unsafe::getObjectVolatile (jobject obj, jlong offset)
217 volatile jobject *addr = (jobject *) ((char *) obj + offset);
218 jobject result = *addr;
224 sun::misc::Unsafe::getLong (jobject obj, jlong offset)
226 jlong *addr = (jlong *) ((char *) obj + offset);
232 sun::misc::Unsafe::getLongVolatile (jobject obj, jlong offset)
234 volatile jlong *addr = (jlong *) ((char *) obj + offset);
240 sun::misc::Unsafe::unpark (::java::lang::Thread *thread)
242 natThread *nt = (natThread *) thread->data;
243 nt->park_helper.unpark ();
247 sun::misc::Unsafe::park (jboolean isAbsolute, jlong time)
249 using namespace ::java::lang;
250 Thread *thread = Thread::currentThread();
251 natThread *nt = (natThread *) thread->data;
252 nt->park_helper.park (isAbsolute, time);