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