46b30edc16ebbd2d946894f14fac295658df9936
[cacao.git] / src / native / vm / sun_misc_Unsafe.c
1 /* src/native/vm/sun_misc_Unsafe.c - sun/misc/Unsafe
2
3    Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: java_lang_VMObject.c 5153 2006-07-18 08:19:24Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <stdint.h>
33
34 #include "mm/memory.h"
35
36 #include "native/jni.h"
37 #include "native/llni.h"
38 #include "native/native.h"
39
40 #include "native/include/java_lang_Object.h"                  /* before c.l.C */
41 #include "native/include/java_lang_String.h"            /* required by j.l.CL */
42
43 #if defined(WITH_CLASSPATH_SUN)
44 # include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
45 #endif
46
47 #include "native/include/java_lang_ClassLoader.h"        /* required by j.l.C */
48 #include "native/include/java_lang_Class.h"
49 #include "native/include/java_lang_reflect_Field.h"
50 #include "native/include/java_lang_Thread.h"             /* required by s.m.U */
51 #include "native/include/java_lang_Throwable.h"
52
53 #include "native/include/java_security_ProtectionDomain.h" /* required by smU */
54
55 #include "native/include/sun_misc_Unsafe.h"
56
57 #include "vm/exceptions.h"
58 #include "vm/initialize.h"
59 #include "vm/stringlocal.h"
60
61 #include "vmcore/utf8.h"
62
63
64 /* native methods implemented by this file ************************************/
65
66 static JNINativeMethod methods[] = {
67         { "registerNatives",        "()V",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives                },
68         { "getInt",                 "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J   },
69         { "putInt",                 "(Ljava/lang/Object;JI)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI  },
70         { "getObject",              "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObject                      },
71         { "putObject",              "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject                      },
72         { "getBoolean",             "(Ljava/lang/Object;J)Z",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean                     },
73         { "putBoolean",             "(Ljava/lang/Object;JZ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean                     },
74         { "getByte",                "(Ljava/lang/Object;J)B",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J  },
75         { "putByte",                "(Ljava/lang/Object;JB)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB },
76         { "getChar",                "(Ljava/lang/Object;J)C",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J  },
77         { "putChar",                "(Ljava/lang/Object;JC)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC },
78         { "getByte",                "(J)B",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J                     },
79         { "getInt",                 "(J)I",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J                      },
80         { "getLong",                "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J                     },
81         { "putLong",                "(JJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ                    },
82         { "objectFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset              },
83         { "allocateMemory",         "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory                 },
84         { "freeMemory",             "(J)V",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory                     },
85         { "staticFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset              },
86         { "staticFieldBase",        "(Ljava/lang/reflect/Field;)Ljava/lang/Object;",              (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase                },
87         { "ensureClassInitialized", "(Ljava/lang/Class;)V",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized         },
88         { "arrayBaseOffset",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset                },
89         { "arrayIndexScale",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale                },
90         { "addressSize",            "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize                    },
91         { "defineClass",            "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (intptr_t) &Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2 },
92         { "throwException",         "(Ljava/lang/Throwable;)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException                 },
93         { "compareAndSwapObject",   "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject           },
94         { "compareAndSwapInt",      "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt              },
95         { "compareAndSwapLong",     "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong             },
96         { "getObjectVolatile",      "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile              },
97         { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
98         { "unpark",                 "(Ljava/lang/Object;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark                         },
99         { "park",                   "(ZJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_park                           },
100 };
101
102
103 /* _Jv_sun_misc_Unsafe_init ****************************************************
104
105    Register native functions.
106
107 *******************************************************************************/
108
109 void _Jv_sun_misc_Unsafe_init(void)
110 {
111         utf *u;
112
113         u = utf_new_char("sun/misc/Unsafe");
114
115         native_method_register(u, methods, NATIVE_METHODS_COUNT);
116 }
117
118
119 /*
120  * Class:     sun/misc/Unsafe
121  * Method:    registerNatives
122  * Signature: ()V
123  */
124 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
125 {
126         /* The native methods of this function are already registered in
127            _Jv_sun_misc_Unsafe_init() which is called during VM
128            startup. */
129 }
130
131
132 /*
133  * Class:     sun/misc/Unsafe
134  * Method:    getInt
135  * Signature: (Ljava/lang/Object;J)I
136  */
137 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
138 {
139         int32_t *p;
140         int32_t  value;
141
142         p = (int32_t *) (((uint8_t *) o) + offset);
143
144         value = *p;
145
146         return value;
147 }
148
149
150 /*
151  * Class:     sun/misc/Unsafe
152  * Method:    putInt
153  * Signature: (Ljava/lang/Object;JI)V
154  */
155 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
156 {
157         int32_t *p;
158
159         p = (int32_t *) (((uint8_t *) o) + offset);
160
161         *p = x;
162 }
163
164
165 /*
166  * Class:     sun/misc/Unsafe
167  * Method:    getObject
168  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
169  */
170 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
171 {
172         void **p;
173         void  *value;
174
175         p = (void **) (((uint8_t *) o) + offset);
176
177         value = *p;
178
179         return value;
180 }
181
182
183 /*
184  * Class:     sun/misc/Unsafe
185  * Method:    putObject
186  * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
187  */
188 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
189 {
190         void **p;
191
192         p = (void **) (((uint8_t *) o) + offset);
193
194         *p = (void *) x;
195 }
196
197
198 /*
199  * Class:     sun/misc/Unsafe
200  * Method:    getBoolean
201  * Signature: (Ljava/lang/Object;J)Z
202  */
203 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
204 {
205         int32_t *p;
206         int32_t  value;
207
208         p = (int32_t *) (((uint8_t *) o) + offset);
209
210         value = *p;
211
212         return value;
213 }
214
215
216 /*
217  * Class:     sun/misc/Unsafe
218  * Method:    putBoolean
219  * Signature: (Ljava/lang/Object;JZ)V
220  */
221 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
222 {
223         int32_t *p;
224
225         p = (int32_t *) (((uint8_t *) o) + offset);
226
227         *p = x;
228 }
229
230
231 /*
232  * Class:     sun/misc/Unsafe
233  * Method:    getByte
234  * Signature: (Ljava/lang/Object;J)B
235  */
236 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
237 {
238         int32_t *p;
239         int32_t  value;
240
241         p = (int32_t *) (((uint8_t *) o) + offset);
242
243         value = *p;
244
245         return value;
246 }
247
248
249 /*
250  * Class:     sun/misc/Unsafe
251  * Method:    putByte
252  * Signature: (Ljava/lang/Object;JB)V
253  */
254 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
255 {
256         int32_t *p;
257
258         p = (int32_t *) (((uint8_t *) o) + offset);
259
260         *p = x;
261 }
262
263
264 /*
265  * Class:     sun/misc/Unsafe
266  * Method:    getChar
267  * Signature: (Ljava/lang/Object;J)C
268  */
269 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
270 {
271         int32_t *p;
272         int32_t  value;
273
274         p = (int32_t *) (((uint8_t *) o) + offset);
275
276         value = *p;
277
278         return value;
279 }
280
281
282 /*
283  * Class:     sun/misc/Unsafe
284  * Method:    putChar
285  * Signature: (Ljava/lang/Object;JC)V
286  */
287 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
288 {
289         int32_t *p;
290
291         p = (int32_t *) (((uint8_t *) o) + offset);
292
293         *p = x;
294 }
295
296
297 /*
298  * Class:     sun/misc/Unsafe
299  * Method:    getByte
300  * Signature: (J)B
301  */
302 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
303 {
304         int8_t *p;
305         int8_t  value;
306
307         p = (int8_t *) (intptr_t) address;
308
309         value = *p;
310
311         return (int32_t) value;
312 }
313
314
315 /*
316  * Class:     sun/misc/Unsafe
317  * Method:    getInt
318  * Signature: (J)I
319  */
320 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
321 {
322         int32_t *p;
323         int32_t  value;
324
325         p = (int32_t *) (intptr_t) address;
326
327         value = *p;
328
329         return value;
330 }
331
332
333 /*
334  * Class:     sun/misc/Unsafe
335  * Method:    getLong
336  * Signature: (J)J
337  */
338 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
339 {
340         int64_t *p;
341         int64_t  value;
342
343         p = (int64_t *) (intptr_t) address;
344
345         value = *p;
346
347         return value;
348 }
349
350
351 /*
352  * Class:     sun/misc/Unsafe
353  * Method:    putLong
354  * Signature: (JJ)V
355  */
356 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
357 {
358         int64_t *p;
359
360         p = (int64_t *) (intptr_t) address;
361
362         *p = value;
363 }
364
365
366 /*
367  * Class:     sun/misc/Unsafe
368  * Method:    objectFieldOffset
369  * Signature: (Ljava/lang/reflect/Field;)J
370  */
371 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field)
372 {
373         classinfo *c;
374         fieldinfo *f;
375         int32_t    slot;
376
377         LLNI_field_get_cls(field, clazz, c);
378         LLNI_field_get_val(field, slot , slot);
379         f = &c->fields[slot];
380
381         return (int64_t) f->offset;
382 }
383
384
385 /*
386  * Class:     sun/misc/Unsafe
387  * Method:    allocateMemory
388  * Signature: (J)J
389  */
390 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
391 {
392         size_t  length;
393         void   *p;
394
395         length = (size_t) bytes;
396
397         if ((length != (uint64_t) bytes) || (bytes < 0)) {
398                 exceptions_throw_illegalargumentexception();
399                 return 0;
400         }
401
402         p = MNEW(uint8_t, length);
403
404         return (int64_t) (intptr_t) p;
405 }
406
407
408 /*
409  * Class:     sun/misc/Unsafe
410  * Method:    freeMemory
411  * Signature: (J)V
412  */
413 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
414 {
415         void *p;
416
417         p = (void *) (intptr_t) address;
418
419         if (p == NULL)
420                 return;
421
422         /* we pass length 1 to trick the free function */
423
424         MFREE(p, uint8_t, 1);
425 }
426
427
428 /*
429  * Class:     sun/misc/Unsafe
430  * Method:    staticFieldOffset
431  * Signature: (Ljava/lang/reflect/Field;)J
432  */
433 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
434 {
435         classinfo *c;
436         fieldinfo *f;
437         int32_t    slot;
438
439         LLNI_field_get_cls(field, clazz, c);
440         LLNI_field_get_val(field, slot , slot);
441         f = &(c->fields[slot]);
442
443         return (int64_t) (intptr_t) f->value;
444 }
445
446
447 /*
448  * Class:     sun/misc/Unsafe
449  * Method:    staticFieldBase
450  * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
451  */
452 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
453 {
454         /* In CACAO we return the absolute address in staticFieldOffset. */
455
456         return NULL;
457 }
458
459
460 /*
461  * Class:     sun/misc/Unsafe
462  * Method:    ensureClassInitialized
463  * Signature: (Ljava/lang/Class;)V
464  */
465 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
466 {
467         classinfo *c;
468
469         c = (classinfo *) class;
470
471         if (!(c->state & CLASS_INITIALIZED))
472                 initialize_class(c);
473 }
474
475
476 /*
477  * Class:     sun/misc/Unsafe
478  * Method:    arrayBaseOffset
479  * Signature: (Ljava/lang/Class;)I
480  */
481 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
482 {
483         classinfo       *c;
484         arraydescriptor *ad;
485
486         c  = (classinfo *) arrayClass;
487         ad = c->vftbl->arraydesc;
488
489         if (ad == NULL) {
490                 /* XXX does that exception exist? */
491                 exceptions_throw_internalerror("java/lang/InvalidClassException");
492                 return 0;
493         }
494
495         return ad->dataoffset;
496 }
497
498
499 /*
500  * Class:     sun/misc/Unsafe
501  * Method:    arrayIndexScale
502  * Signature: (Ljava/lang/Class;)I
503  */
504 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
505 {
506         classinfo       *c;
507         arraydescriptor *ad;
508
509         c  = (classinfo *) arrayClass;
510         ad = c->vftbl->arraydesc;
511
512         if (ad == NULL) {
513                 /* XXX does that exception exist? */
514                 exceptions_throw_internalerror("java/lang/InvalidClassException");
515                 return 0;
516         }
517
518         return ad->componentsize;
519 }
520
521
522 /*
523  * Class:     sun/misc/Unsafe
524  * Method:    addressSize
525  * Signature: ()I
526  */
527 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this)
528 {
529         return SIZEOF_VOID_P;
530 }
531
532
533 /*
534  * Class:     sun/misc/Unsafe
535  * Method:    defineClass
536  * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
537  */
538 JNIEXPORT java_lang_Class* JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(JNIEnv *env, sun_misc_Unsafe *this, java_lang_String *name, java_handle_bytearray_t *b, int32_t off, int32_t len, java_lang_ClassLoader *loader, java_security_ProtectionDomain *protectionDomain)
539 {
540         classloader     *cl;
541         utf             *utfname;
542         classinfo       *c;
543         java_lang_Class *o;
544
545         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
546
547         /* check if data was passed */
548
549         if (b == NULL) {
550                 exceptions_throw_nullpointerexception();
551                 return NULL;
552         }
553
554         /* check the indexes passed */
555
556         if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) {
557                 exceptions_throw_arrayindexoutofboundsexception();
558                 return NULL;
559         }
560
561         if (name != NULL) {
562                 /* convert '.' to '/' in java string */
563
564                 utfname = javastring_toutf((java_handle_t *) name, true);
565         } 
566         else {
567                 utfname = NULL;
568         }
569
570         /* define the class */
571
572         c = class_define(utfname, cl, len, (const uint8_t *) &LLNI_array_direct(b, off));
573
574         if (c == NULL)
575                 return NULL;
576
577         /* for convenience */
578
579         o = (java_lang_Class *) c;
580
581 #if defined(WITH_CLASSPATH_GNU)
582         /* set ProtectionDomain */
583
584         LLNI_field_set_ref(o, pd, protectionDomain);
585 #endif
586
587         return o;
588 }
589
590
591 /*
592  * Class:     sun/misc/Unsafe
593  * Method:    throwException
594  * Signature: (Ljava/lang/Throwable;)V
595  */
596 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
597 {
598         java_handle_t *o;
599
600         o = (java_handle_t *) ee;
601
602         exceptions_set_exception(o);
603 }
604
605
606 /*
607  * Class:     sun/misc/Unsafe
608  * Method:    compareAndSwapObject
609  * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
610  */
611 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *expected, java_lang_Object *x)
612 {
613         void **p;
614         void  *value;
615
616         p = (void **) (((uint8_t *) o) + offset);
617
618         /* XXX this should be atomic */
619
620         value = *p;
621
622         if (value == expected) {
623                 *p = x;
624
625                 return true;
626         }
627
628         return false;
629 }
630
631
632 /*
633  * Class:     sun/misc/Unsafe
634  * Method:    compareAndSwapInt
635  * Signature: (Ljava/lang/Object;JII)Z
636  */
637 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* obj, int64_t offset, int32_t expect, int32_t update)
638 {
639         int32_t *p;
640         int32_t  value;
641
642         p = (int32_t *) (((uint8_t *) obj) + offset);
643
644         /* XXX this should be atomic */
645
646         value = *p;
647
648         if (value == expect) {
649                 *p = update;
650
651                 return true;
652         }
653
654         return false;
655 }
656
657
658 /*
659  * Class:     sun/misc/Unsafe
660  * Method:    compareAndSwapLong
661  * Signature: (Ljava/lang/Object;JJJ)Z
662  */
663 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t expected, int64_t x)
664 {
665         int64_t *p;
666         int64_t  value;
667
668         p = (int64_t *) (((uint8_t *) o) + offset);
669
670         /* XXX this should be atomic */
671
672         value = *p;
673
674         if (value == expected) {
675                 *p = x;
676
677                 return true;
678         }
679
680         return false;
681 }
682
683
684 /*
685  * Class:     sun/misc/Unsafe
686  * Method:    getObjectVolatile
687  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
688  */
689 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
690 {
691         volatile void **p;
692         volatile void  *value;
693
694         p = (volatile void **) (((uint8_t *) o) + offset);
695
696         value = *p;
697
698         return (java_lang_Object *) value;
699 }
700
701
702 /*
703  * Class:     sun/misc/Unsafe
704  * Method:    getIntVolatile
705  * Signature: (Ljava/lang/Object;J)I
706  */
707 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
708 {
709         volatile int32_t *p;
710         volatile int32_t  value;
711
712         p = (volatile int32_t *) (((uint8_t *) o) + offset);
713
714         value = *p;
715
716         return value;
717 }
718
719
720 /*
721  * Class:     sun/misc/Unsafe
722  * Method:    unpark
723  * Signature: (Ljava/lang/Object;)V
724  */
725 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
726 {
727         /* XXX IMPLEMENT ME */
728 }
729
730
731 /*
732  * Class:     sun/misc/Unsafe
733  * Method:    park
734  * Signature: (ZJ)V
735  */
736 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
737 {
738         /* XXX IMPLEMENT ME */
739 }
740
741
742 /*
743  * These are local overrides for various environment variables in Emacs.
744  * Please do not remove this and leave it at the end of the file, where
745  * Emacs will automagically detect them.
746  * ---------------------------------------------------------------------
747  * Local variables:
748  * mode: c
749  * indent-tabs-mode: t
750  * c-basic-offset: 4
751  * tab-width: 4
752  * End:
753  */