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));
38 release_set (&lock
, 0);
42 // This is a single lock that is used for all synchronized accesses if
43 // the compiler can't generate inline compare-and-swap operations. In
44 // most cases it'll never be used, but the i386 needs it for 64-bit
45 // locked accesses and so does PPC32. It's worth building libgcj with
46 // target=i486 (or above) to get the inlines.
47 volatile obj_addr_t
spinlock::lock
;
51 compareAndSwap (volatile jint
*addr
, jint old
, jint new_val
)
53 jboolean result
= false;
55 if ((result
= (*addr
== old
)))
61 compareAndSwap (volatile jlong
*addr
, jlong old
, jlong new_val
)
63 jboolean result
= false;
65 if ((result
= (*addr
== old
)))
71 compareAndSwap (volatile jobject
*addr
, jobject old
, jobject new_val
)
73 jboolean result
= false;
75 if ((result
= (*addr
== old
)))
82 sun::misc::Unsafe::objectFieldOffset (::java::lang::reflect::Field
*field
)
84 _Jv_Field
*fld
= _Jv_FromReflectedField (field
);
85 // FIXME: what if it is not an instance field?
86 return fld
->getOffset();
90 sun::misc::Unsafe::arrayBaseOffset (jclass arrayClass
)
92 // FIXME: assert that arrayClass is array.
93 jclass eltClass
= arrayClass
->getComponentType();
94 return (jint
)(jlong
) _Jv_GetArrayElementFromElementType (NULL
, eltClass
);
98 sun::misc::Unsafe::arrayIndexScale (jclass arrayClass
)
100 // FIXME: assert that arrayClass is array.
101 jclass eltClass
= arrayClass
->getComponentType();
102 if (eltClass
->isPrimitive())
103 return eltClass
->size();
104 return sizeof (void *);
107 // These methods are used when the compiler fails to generate inline
108 // versions of the compare-and-swap primitives.
111 sun::misc::Unsafe::compareAndSwapInt (jobject obj
, jlong offset
,
112 jint expect
, jint update
)
114 jint
*addr
= (jint
*)((char *)obj
+ offset
);
115 return compareAndSwap (addr
, expect
, update
);
119 sun::misc::Unsafe::compareAndSwapLong (jobject obj
, jlong offset
,
120 jlong expect
, jlong update
)
122 volatile jlong
*addr
= (jlong
*)((char *) obj
+ offset
);
123 return compareAndSwap (addr
, expect
, update
);
127 sun::misc::Unsafe::compareAndSwapObject (jobject obj
, jlong offset
,
128 jobject expect
, jobject update
)
130 jobject
*addr
= (jobject
*)((char *) obj
+ offset
);
131 return compareAndSwap (addr
, expect
, update
);
135 sun::misc::Unsafe::putOrderedInt (jobject obj
, jlong offset
, jint value
)
137 volatile jint
*addr
= (jint
*) ((char *) obj
+ offset
);
142 sun::misc::Unsafe::putOrderedLong (jobject obj
, jlong offset
, jlong value
)
144 volatile jlong
*addr
= (jlong
*) ((char *) obj
+ offset
);
150 sun::misc::Unsafe::putOrderedObject (jobject obj
, jlong offset
, jobject value
)
152 volatile jobject
*addr
= (jobject
*) ((char *) obj
+ offset
);
157 sun::misc::Unsafe::putIntVolatile (jobject obj
, jlong offset
, jint value
)
160 volatile jint
*addr
= (jint
*) ((char *) obj
+ offset
);
165 sun::misc::Unsafe::putLongVolatile (jobject obj
, jlong offset
, jlong value
)
167 volatile jlong
*addr
= (jlong
*) ((char *) obj
+ offset
);
173 sun::misc::Unsafe::putObjectVolatile (jobject obj
, jlong offset
, jobject value
)
176 volatile jobject
*addr
= (jobject
*) ((char *) obj
+ offset
);
182 sun::misc::Unsafe::putInt (jobject obj
, jlong offset
, jint value
)
184 jint
*addr
= (jint
*) ((char *) obj
+ offset
);
190 sun::misc::Unsafe::putLong (jobject obj
, jlong offset
, jlong value
)
192 jlong
*addr
= (jlong
*) ((char *) obj
+ offset
);
198 sun::misc::Unsafe::putObject (jobject obj
, jlong offset
, jobject value
)
200 jobject
*addr
= (jobject
*) ((char *) obj
+ offset
);
205 sun::misc::Unsafe::getIntVolatile (jobject obj
, jlong offset
)
207 volatile jint
*addr
= (jint
*) ((char *) obj
+ offset
);
214 sun::misc::Unsafe::getObjectVolatile (jobject obj
, jlong offset
)
216 volatile jobject
*addr
= (jobject
*) ((char *) obj
+ offset
);
217 jobject result
= *addr
;
223 sun::misc::Unsafe::getLong (jobject obj
, jlong offset
)
225 jlong
*addr
= (jlong
*) ((char *) obj
+ offset
);
231 sun::misc::Unsafe::getLongVolatile (jobject obj
, jlong offset
)
233 volatile jlong
*addr
= (jlong
*) ((char *) obj
+ offset
);
239 sun::misc::Unsafe::unpark (::java::lang::Thread
*thread
)
241 natThread
*nt
= (natThread
*) thread
->data
;
242 nt
->park_helper
.unpark ();
246 sun::misc::Unsafe::park (jboolean isAbsolute
, jlong time
)
248 using namespace ::java::lang
;
249 Thread
*thread
= Thread::currentThread();
250 natThread
*nt
= (natThread
*) thread
->data
;
251 nt
->park_helper
.park (isAbsolute
, time
);