* Merged with default branch at rev 16f3633aaa5a.
[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 */
26
27
28 #include "config.h"
29
30 #include <stdint.h>
31 #include <unistd.h>
32
33 #include "mm/memory.h"
34
35 #include "native/jni.h"
36 #include "native/llni.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/builtin.h"
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         { "putShort",               "(Ljava/lang/Object;JS)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS },
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         { "getLong",                "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J  },
80         { "getFloat",               "(Ljava/lang/Object;J)F",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J },
81         { "putFloat",               "(Ljava/lang/Object;JF)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF },
82         { "getByte",                "(J)B",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J                     },
83         { "putByte",                "(JB)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__JB                    },
84         { "getShort",               "(J)S",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__J                    },
85         { "putShort",               "(JS)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__JS                   },
86         { "getInt",                 "(J)I",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J                      },
87         { "putInt",                 "(JI)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__JI                     },
88         { "getLong",                "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J                     },
89         { "putLong",                "(JJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ                    },
90         { "getFloat",               "(J)F",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__J                    },
91         { "objectFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset              },
92         { "allocateMemory",         "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory                 },
93         { "setMemory",              "(Ljava/lang/Object;JJB)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_setMemory                      },
94         { "freeMemory",             "(J)V",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory                     },
95         { "staticFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset              },
96         { "staticFieldBase",        "(Ljava/lang/reflect/Field;)Ljava/lang/Object;",              (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase                },
97         { "ensureClassInitialized", "(Ljava/lang/Class;)V",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized         },
98         { "arrayBaseOffset",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset                },
99         { "arrayIndexScale",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale                },
100         { "addressSize",            "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize                    },
101         { "pageSize",               "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_pageSize                       },
102         { "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 },
103         { "allocateInstance",       "(Ljava/lang/Class;)Ljava/lang/Object;",                      (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateInstance               },
104         { "throwException",         "(Ljava/lang/Throwable;)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException                 },
105         { "compareAndSwapObject",   "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject           },
106         { "compareAndSwapInt",      "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt              },
107         { "compareAndSwapLong",     "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong             },
108         { "getObjectVolatile",      "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile              },
109         { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
110         { "getLongVolatile",        "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile                },
111         { "unpark",                 "(Ljava/lang/Object;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark                         },
112         { "park",                   "(ZJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_park                           },
113 };
114
115
116 /* _Jv_sun_misc_Unsafe_init ****************************************************
117
118    Register native functions.
119
120 *******************************************************************************/
121
122 void _Jv_sun_misc_Unsafe_init(void)
123 {
124         utf *u;
125
126         u = utf_new_char("sun/misc/Unsafe");
127
128         native_method_register(u, methods, NATIVE_METHODS_COUNT);
129 }
130
131
132 /*
133  * Class:     sun/misc/Unsafe
134  * Method:    registerNatives
135  * Signature: ()V
136  */
137 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
138 {
139         /* The native methods of this function are already registered in
140            _Jv_sun_misc_Unsafe_init() which is called during VM
141            startup. */
142 }
143
144
145 /*
146  * Class:     sun/misc/Unsafe
147  * Method:    getInt
148  * Signature: (Ljava/lang/Object;J)I
149  */
150 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)
151 {
152         int32_t *p;
153         int32_t  value;
154
155         p = (int32_t *) (((uint8_t *) o) + offset);
156
157         value = *p;
158
159         return value;
160 }
161
162
163 /*
164  * Class:     sun/misc/Unsafe
165  * Method:    putInt
166  * Signature: (Ljava/lang/Object;JI)V
167  */
168 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)
169 {
170         int32_t *p;
171
172         p = (int32_t *) (((uint8_t *) o) + offset);
173
174         *p = x;
175 }
176
177
178 /*
179  * Class:     sun/misc/Unsafe
180  * Method:    getObject
181  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
182  */
183 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
184 {
185         void **p;
186         void  *value;
187
188         p = (void **) (((uint8_t *) o) + offset);
189
190         value = *p;
191
192         return value;
193 }
194
195
196 /*
197  * Class:     sun/misc/Unsafe
198  * Method:    putObject
199  * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
200  */
201 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)
202 {
203         void **p;
204
205         p = (void **) (((uint8_t *) o) + offset);
206
207         *p = (void *) x;
208 }
209
210
211 /*
212  * Class:     sun/misc/Unsafe
213  * Method:    getBoolean
214  * Signature: (Ljava/lang/Object;J)Z
215  */
216 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
217 {
218         int32_t *p;
219         int32_t  value;
220
221         p = (int32_t *) (((uint8_t *) o) + offset);
222
223         value = *p;
224
225         return value;
226 }
227
228
229 /*
230  * Class:     sun/misc/Unsafe
231  * Method:    putBoolean
232  * Signature: (Ljava/lang/Object;JZ)V
233  */
234 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
235 {
236         int32_t *p;
237
238         p = (int32_t *) (((uint8_t *) o) + offset);
239
240         *p = x;
241 }
242
243
244 /*
245  * Class:     sun/misc/Unsafe
246  * Method:    getByte
247  * Signature: (Ljava/lang/Object;J)B
248  */
249 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)
250 {
251         int32_t *p;
252         int32_t  value;
253
254         p = (int32_t *) (((uint8_t *) o) + offset);
255
256         value = *p;
257
258         return value;
259 }
260
261
262 /*
263  * Class:     sun/misc/Unsafe
264  * Method:    putByte
265  * Signature: (Ljava/lang/Object;JB)V
266  */
267 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)
268 {
269         int32_t *p;
270
271         p = (int32_t *) (((uint8_t *) o) + offset);
272
273         *p = x;
274 }
275
276
277 /*
278  * Class:     sun/misc/Unsafe
279  * Method:    putShort
280  * Signature: (Ljava/lang/Object;JS)V
281  */
282 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
283 {
284         int32_t *p;
285
286         p = (int32_t *) (((uint8_t *) o) + offset);
287
288         *p = x;
289 }
290
291
292 /*
293  * Class:     sun/misc/Unsafe
294  * Method:    getChar
295  * Signature: (Ljava/lang/Object;J)C
296  */
297 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)
298 {
299         int32_t *p;
300         int32_t  value;
301
302         p = (int32_t *) (((uint8_t *) o) + offset);
303
304         value = *p;
305
306         return value;
307 }
308
309
310 /*
311  * Class:     sun/misc/Unsafe
312  * Method:    putChar
313  * Signature: (Ljava/lang/Object;JC)V
314  */
315 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)
316 {
317         int32_t *p;
318
319         p = (int32_t *) (((uint8_t *) o) + offset);
320
321         *p = x;
322 }
323
324
325 /*
326  * Class:     sun/misc/Unsafe
327  * Method:    getLong
328  * Signature: (Ljava/lang/Object;J)J
329  */
330 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
331 {
332         int64_t *p;
333         int64_t  value;
334
335         p = (int64_t *) (((uint8_t *) o) + offset);
336
337         value = *p;
338
339         return value;
340 }
341
342
343 /*
344  * Class:     sun/misc/Unsafe
345  * Method:    getFloat
346  * Signature: (Ljava/lang/Object;J)F
347  */
348 JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
349 {
350         float *p;
351         float  value;
352
353         p = (float *) (((uint8_t *) o) + offset);
354
355         value = *p;
356
357         return value;
358 }
359
360
361 /*
362  * Class:     sun/misc/Unsafe
363  * Method:    putFloat
364  * Signature: (Ljava/lang/Object;JF)V
365  */
366 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, float x)
367 {
368         float *p;
369
370         p = (float *) (((uint8_t *) o) + offset);
371
372         *p = x;
373 }
374
375
376 /*
377  * Class:     sun/misc/Unsafe
378  * Method:    getByte
379  * Signature: (J)B
380  */
381 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
382 {
383         int8_t *p;
384         int8_t  value;
385
386         p = (int8_t *) (intptr_t) address;
387
388         value = *p;
389
390         return (int32_t) value;
391 }
392
393
394 /*
395  * Class:     sun/misc/Unsafe
396  * Method:    putByte
397  * Signature: (JB)V
398  */
399 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__JB(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
400 {
401         int8_t *p;
402
403         p = (int8_t *) (intptr_t) address;
404
405         *p = (int8_t) value;
406 }
407
408
409 /*
410  * Class:     sun/misc/Unsafe
411  * Method:    getShort
412  * Signature: (J)S
413  */
414 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
415 {
416         int16_t *p;
417         int16_t  value;
418
419         p = (int16_t *) (intptr_t) address;
420
421         value = *p;
422
423         return (int32_t) value;
424 }
425
426
427 /*
428  * Class:     sun/misc/Unsafe
429  * Method:    putShort
430  * Signature: (JS)V
431  */
432 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__JS(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
433 {
434         int16_t *p;
435
436         p = (int16_t *) (intptr_t) address;
437
438         *p = (int16_t) value;
439 }
440
441
442 /*
443  * Class:     sun/misc/Unsafe
444  * Method:    getInt
445  * Signature: (J)I
446  */
447 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
448 {
449         int32_t *p;
450         int32_t  value;
451
452         p = (int32_t *) (intptr_t) address;
453
454         value = *p;
455
456         return value;
457 }
458
459
460 /*
461  * Class:     sun/misc/Unsafe
462  * Method:    putInt
463  * Signature: (JI)V
464  */
465 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__JI(JNIEnv *env, struct sun_misc_Unsafe* this, int64_t address, int32_t value)
466 {
467         int32_t *p;
468
469         p = (int32_t *) (intptr_t) address;
470
471         *p = value;
472 }
473
474
475 /*
476  * Class:     sun/misc/Unsafe
477  * Method:    getLong
478  * Signature: (J)J
479  */
480 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
481 {
482         int64_t *p;
483         int64_t  value;
484
485         p = (int64_t *) (intptr_t) address;
486
487         value = *p;
488
489         return value;
490 }
491
492
493 /*
494  * Class:     sun/misc/Unsafe
495  * Method:    putLong
496  * Signature: (JJ)V
497  */
498 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
499 {
500         int64_t *p;
501
502         p = (int64_t *) (intptr_t) address;
503
504         *p = value;
505 }
506
507
508 /*
509  * Class:     sun/misc/Unsafe
510  * Method:    getFloat
511  * Signature: (J)F
512  */
513 JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
514 {
515         float *p;
516         float  value;
517
518         p = (float *) (intptr_t) address;
519
520         value = *p;
521
522         return value;
523 }
524
525
526 /*
527  * Class:     sun/misc/Unsafe
528  * Method:    objectFieldOffset
529  * Signature: (Ljava/lang/reflect/Field;)J
530  */
531 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
532 {
533         classinfo *c;
534         fieldinfo *f;
535         int32_t    slot;
536
537         LLNI_field_get_cls(field, clazz, c);
538         LLNI_field_get_val(field, slot , slot);
539
540         f = &c->fields[slot];
541
542         return (int64_t) f->offset;
543 }
544
545
546 /*
547  * Class:     sun/misc/Unsafe
548  * Method:    allocateMemory
549  * Signature: (J)J
550  */
551 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
552 {
553         size_t  length;
554         void   *p;
555
556         length = (size_t) bytes;
557
558         if ((length != (uint64_t) bytes) || (bytes < 0)) {
559                 exceptions_throw_illegalargumentexception();
560                 return 0;
561         }
562
563         p = MNEW(uint8_t, length);
564
565         return (int64_t) (intptr_t) p;
566 }
567
568
569 /*
570  * Class:     sun/misc/Unsafe
571  * Method:    setMemory
572  * Signature: (Ljava/lang/Object;JJB)V
573  */
574 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t bytes, int32_t value)
575 {
576         size_t  length;
577         void   *p;
578
579         length = (size_t) bytes;
580
581         if ((length != (uint64_t) bytes) || (bytes < 0)) {
582                 exceptions_throw_illegalargumentexception();
583                 return;
584         }
585
586         /* XXX Missing LLNI: we need to unwrap this object. */
587
588         p = (void *) (((uint8_t *) o) + offset);
589
590         /* XXX Not sure this is correct. */
591
592         MSET(p, value, uint8_t, length);
593 }
594
595
596 /*
597  * Class:     sun/misc/Unsafe
598  * Method:    freeMemory
599  * Signature: (J)V
600  */
601 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
602 {
603         void *p;
604
605         p = (void *) (intptr_t) address;
606
607         if (p == NULL)
608                 return;
609
610         /* we pass length 1 to trick the free function */
611
612         MFREE(p, uint8_t, 1);
613 }
614
615
616 /*
617  * Class:     sun/misc/Unsafe
618  * Method:    staticFieldOffset
619  * Signature: (Ljava/lang/reflect/Field;)J
620  */
621 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
622 {
623         classinfo *c;
624         fieldinfo *f;
625         int32_t    slot;
626
627         LLNI_field_get_cls(field, clazz, c);
628         LLNI_field_get_val(field, slot , slot);
629         f = &(c->fields[slot]);
630
631         return (int64_t) (intptr_t) f->value;
632 }
633
634
635 /*
636  * Class:     sun/misc/Unsafe
637  * Method:    staticFieldBase
638  * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
639  */
640 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
641 {
642         /* In CACAO we return the absolute address in staticFieldOffset. */
643
644         return NULL;
645 }
646
647
648 /*
649  * Class:     sun/misc/Unsafe
650  * Method:    ensureClassInitialized
651  * Signature: (Ljava/lang/Class;)V
652  */
653 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
654 {
655         classinfo *c;
656
657         c = LLNI_classinfo_unwrap(class);
658
659         if (!(c->state & CLASS_INITIALIZED))
660                 initialize_class(c);
661 }
662
663
664 /*
665  * Class:     sun/misc/Unsafe
666  * Method:    arrayBaseOffset
667  * Signature: (Ljava/lang/Class;)I
668  */
669 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
670 {
671         classinfo       *c;
672         arraydescriptor *ad;
673
674         c  = LLNI_classinfo_unwrap(arrayClass);
675         ad = c->vftbl->arraydesc;
676
677         if (ad == NULL) {
678                 /* XXX does that exception exist? */
679                 exceptions_throw_internalerror("java/lang/InvalidClassException");
680                 return 0;
681         }
682
683         return ad->dataoffset;
684 }
685
686
687 /*
688  * Class:     sun/misc/Unsafe
689  * Method:    arrayIndexScale
690  * Signature: (Ljava/lang/Class;)I
691  */
692 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
693 {
694         classinfo       *c;
695         arraydescriptor *ad;
696
697         c  = LLNI_classinfo_unwrap(arrayClass);
698         ad = c->vftbl->arraydesc;
699
700         if (ad == NULL) {
701                 /* XXX does that exception exist? */
702                 exceptions_throw_internalerror("java/lang/InvalidClassException");
703                 return 0;
704         }
705
706         return ad->componentsize;
707 }
708
709
710 /*
711  * Class:     sun/misc/Unsafe
712  * Method:    addressSize
713  * Signature: ()I
714  */
715 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this)
716 {
717         return SIZEOF_VOID_P;
718 }
719
720
721 /*
722  * Class:     sun/misc/Unsafe
723  * Method:    pageSize
724  * Signature: ()I
725  */
726 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_pageSize(JNIEnv *env, sun_misc_Unsafe *this)
727 {
728         int sz;
729
730         sz = getpagesize();
731
732         return sz;
733 }
734
735
736 /*
737  * Class:     sun/misc/Unsafe
738  * Method:    defineClass
739  * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
740  */
741 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)
742 {
743         classloader     *cl;
744         utf             *utfname;
745         classinfo       *c;
746         java_lang_Class *o;
747
748         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
749
750         /* check if data was passed */
751
752         if (b == NULL) {
753                 exceptions_throw_nullpointerexception();
754                 return NULL;
755         }
756
757         /* check the indexes passed */
758
759         if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) {
760                 exceptions_throw_arrayindexoutofboundsexception();
761                 return NULL;
762         }
763
764         if (name != NULL) {
765                 /* convert '.' to '/' in java string */
766
767                 utfname = javastring_toutf((java_handle_t *) name, true);
768         } 
769         else {
770                 utfname = NULL;
771         }
772
773         /* define the class */
774
775         c = class_define(utfname, cl, len, (const uint8_t *) &b->data[off],
776                                          protectionDomain);
777
778         if (c == NULL)
779                 return NULL;
780
781         /* for convenience */
782
783         o = LLNI_classinfo_wrap(c);
784
785 #if defined(WITH_CLASSPATH_GNU)
786         /* set ProtectionDomain */
787
788         LLNI_field_set_ref(o, pd, protectionDomain);
789 #endif
790
791         return o;
792 }
793
794
795 /*
796  * Class:     sun/misc/Unsafe
797  * Method:    allocateInstance
798  * Signature: (Ljava/lang/Class;)Ljava/lang/Object;
799  */
800 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_allocateInstance(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *cls)
801 {
802         classinfo     *c;
803         java_object_t *o;
804
805         c = LLNI_classinfo_unwrap(cls);
806
807         o = builtin_new(c);
808
809         return (java_lang_Object *) o;
810 }
811
812
813 /*
814  * Class:     sun/misc/Unsafe
815  * Method:    throwException
816  * Signature: (Ljava/lang/Throwable;)V
817  */
818 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
819 {
820         java_handle_t *o;
821
822         o = (java_handle_t *) ee;
823
824         exceptions_set_exception(o);
825 }
826
827
828 /*
829  * Class:     sun/misc/Unsafe
830  * Method:    compareAndSwapObject
831  * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
832  */
833 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)
834 {
835         void **p;
836         void  *value;
837
838         p = (void **) (((uint8_t *) o) + offset);
839
840         /* XXX this should be atomic */
841
842         value = *p;
843
844         if (value == expected) {
845                 *p = x;
846
847                 return true;
848         }
849
850         return false;
851 }
852
853
854 /*
855  * Class:     sun/misc/Unsafe
856  * Method:    compareAndSwapInt
857  * Signature: (Ljava/lang/Object;JII)Z
858  */
859 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)
860 {
861         int32_t *p;
862         int32_t  value;
863
864         p = (int32_t *) (((uint8_t *) obj) + offset);
865
866         /* XXX this should be atomic */
867
868         value = *p;
869
870         if (value == expect) {
871                 *p = update;
872
873                 return true;
874         }
875
876         return false;
877 }
878
879
880 /*
881  * Class:     sun/misc/Unsafe
882  * Method:    compareAndSwapLong
883  * Signature: (Ljava/lang/Object;JJJ)Z
884  */
885 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)
886 {
887         int64_t *p;
888         int64_t  value;
889
890         p = (int64_t *) (((uint8_t *) o) + offset);
891
892         /* XXX this should be atomic */
893
894         value = *p;
895
896         if (value == expected) {
897                 *p = x;
898
899                 return true;
900         }
901
902         return false;
903 }
904
905
906 /*
907  * Class:     sun/misc/Unsafe
908  * Method:    getObjectVolatile
909  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
910  */
911 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
912 {
913         volatile void **p;
914         volatile void  *value;
915
916         p = (volatile void **) (((uint8_t *) o) + offset);
917
918         value = *p;
919
920         return (java_lang_Object *) value;
921 }
922
923
924 /*
925  * Class:     sun/misc/Unsafe
926  * Method:    getIntVolatile
927  * Signature: (Ljava/lang/Object;J)I
928  */
929 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
930 {
931         volatile int32_t *p;
932         volatile int32_t  value;
933
934         p = (volatile int32_t *) (((uint8_t *) o) + offset);
935
936         value = *p;
937
938         return value;
939 }
940
941
942 /*
943  * Class:     sun/misc/Unsafe
944  * Method:    getLongVolatile
945  * Signature: (Ljava/lang/Object;J)J
946  */
947 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
948 {
949         volatile int64_t *p;
950         volatile int64_t  value;
951
952         p = (volatile int64_t *) (((uint8_t *) o) + offset);
953
954         value = *p;
955
956         return value;
957 }
958
959
960 /*
961  * Class:     sun/misc/Unsafe
962  * Method:    unpark
963  * Signature: (Ljava/lang/Object;)V
964  */
965 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
966 {
967         /* XXX IMPLEMENT ME */
968 }
969
970
971 /*
972  * Class:     sun/misc/Unsafe
973  * Method:    park
974  * Signature: (ZJ)V
975  */
976 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
977 {
978         /* XXX IMPLEMENT ME */
979 }
980
981
982 /*
983  * These are local overrides for various environment variables in Emacs.
984  * Please do not remove this and leave it at the end of the file, where
985  * Emacs will automagically detect them.
986  * ---------------------------------------------------------------------
987  * Local variables:
988  * mode: c
989  * indent-tabs-mode: t
990  * c-basic-offset: 4
991  * tab-width: 4
992  * End:
993  */