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