Merge -> trunk
[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, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <stdint.h>
29 #include <unistd.h>
30
31 #include "mm/memory.h"
32
33 #include "native/jni.h"
34 #include "native/llni.h"
35 #include "native/native.h"
36
37 #include "native/include/java_lang_Object.h"                  /* before c.l.C */
38 #include "native/include/java_lang_String.h"            /* required by j.l.CL */
39
40 #if defined(WITH_CLASSPATH_SUN)
41 # include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
42 #endif
43
44 #include "native/include/java_lang_ClassLoader.h"        /* required by j.l.C */
45 #include "native/include/java_lang_Class.h"
46 #include "native/include/java_lang_reflect_Field.h"
47 #include "native/include/java_lang_Thread.h"             /* required by s.m.U */
48 #include "native/include/java_lang_Throwable.h"
49
50 #include "native/include/java_security_ProtectionDomain.h" /* required by smU */
51
52 #include "native/include/sun_misc_Unsafe.h"
53
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/initialize.h"
57 #include "vm/stringlocal.h"
58
59 #include "vmcore/utf8.h"
60
61
62 /* native methods implemented by this file ************************************/
63
64 static JNINativeMethod methods[] = {
65         { "registerNatives",        "()V",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives                },
66         { "getInt",                 "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J   },
67         { "putInt",                 "(Ljava/lang/Object;JI)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI  },
68         { "getObject",              "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObject                      },
69         { "putObject",              "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject                      },
70         { "getBoolean",             "(Ljava/lang/Object;J)Z",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean                     },
71         { "putBoolean",             "(Ljava/lang/Object;JZ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean                     },
72         { "getByte",                "(Ljava/lang/Object;J)B",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J  },
73         { "putByte",                "(Ljava/lang/Object;JB)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB },
74         { "getShort",               "(Ljava/lang/Object;J)S",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J },
75         { "putShort",               "(Ljava/lang/Object;JS)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS },
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         { "getLong",                "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J  },
79         { "putLong",                "(Ljava/lang/Object;JJ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ },
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         { "getDouble",              "(Ljava/lang/Object;J)D",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J },
83         { "putDouble",              "(Ljava/lang/Object;JD)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD },
84         { "getByte",                "(J)B",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J                     },
85         { "putByte",                "(JB)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__JB                    },
86         { "getShort",               "(J)S",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__J                    },
87         { "putShort",               "(JS)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__JS                   },
88         { "getChar",                "(J)C",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__J                     },
89         { "putChar",                "(JC)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__JC                    },
90         { "getInt",                 "(J)I",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J                      },
91         { "putInt",                 "(JI)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__JI                     },
92         { "getLong",                "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J                     },
93         { "putLong",                "(JJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ                    },
94         { "getFloat",               "(J)F",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__J                    },
95         { "objectFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset              },
96         { "allocateMemory",         "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory                 },
97         { "setMemory",              "(Ljava/lang/Object;JJB)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_setMemory                      },
98         { "copyMemory",             "(Ljava/lang/Object;JLjava/lang/Object;JJ)V",                 (void *) (intptr_t) &Java_sun_misc_Unsafe_copyMemory                     },
99         { "freeMemory",             "(J)V",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory                     },
100         { "staticFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset              },
101         { "staticFieldBase",        "(Ljava/lang/reflect/Field;)Ljava/lang/Object;",              (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase                },
102         { "ensureClassInitialized", "(Ljava/lang/Class;)V",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized         },
103         { "arrayBaseOffset",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset                },
104         { "arrayIndexScale",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale                },
105         { "addressSize",            "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize                    },
106         { "pageSize",               "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_pageSize                       },
107         { "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 },
108         { "allocateInstance",       "(Ljava/lang/Class;)Ljava/lang/Object;",                      (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateInstance               },
109         { "throwException",         "(Ljava/lang/Throwable;)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException                 },
110         { "compareAndSwapObject",   "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject           },
111         { "compareAndSwapInt",      "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt              },
112         { "compareAndSwapLong",     "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong             },
113         { "getObjectVolatile",      "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile              },
114         { "putObjectVolatile",      "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObjectVolatile              },
115         { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
116         { "getLongVolatile",        "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile                },
117         { "unpark",                 "(Ljava/lang/Object;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark                         },
118         { "park",                   "(ZJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_park                           },
119 };
120
121
122 /* _Jv_sun_misc_Unsafe_init ****************************************************
123
124    Register native functions.
125
126 *******************************************************************************/
127
128 void _Jv_sun_misc_Unsafe_init(void)
129 {
130         utf *u;
131
132         u = utf_new_char("sun/misc/Unsafe");
133
134         native_method_register(u, methods, NATIVE_METHODS_COUNT);
135 }
136
137
138 /*
139  * Class:     sun/misc/Unsafe
140  * Method:    registerNatives
141  * Signature: ()V
142  */
143 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
144 {
145         /* The native methods of this function are already registered in
146            _Jv_sun_misc_Unsafe_init() which is called during VM
147            startup. */
148 }
149
150
151 /*
152  * Class:     sun/misc/Unsafe
153  * Method:    getInt
154  * Signature: (Ljava/lang/Object;J)I
155  */
156 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)
157 {
158         int32_t *p;
159         int32_t  value;
160
161         p = (int32_t *) (((uint8_t *) o) + offset);
162
163         value = *p;
164
165         return value;
166 }
167
168
169 /*
170  * Class:     sun/misc/Unsafe
171  * Method:    putInt
172  * Signature: (Ljava/lang/Object;JI)V
173  */
174 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)
175 {
176         int32_t *p;
177
178         p = (int32_t *) (((uint8_t *) o) + offset);
179
180         *p = x;
181 }
182
183
184 /*
185  * Class:     sun/misc/Unsafe
186  * Method:    getObject
187  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
188  */
189 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
190 {
191         void **p;
192         void  *value;
193
194         p = (void **) (((uint8_t *) o) + offset);
195
196         value = *p;
197
198         return value;
199 }
200
201
202 /*
203  * Class:     sun/misc/Unsafe
204  * Method:    putObject
205  * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
206  */
207 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)
208 {
209         void **p;
210
211         p = (void **) (((uint8_t *) o) + offset);
212
213         *p = (void *) x;
214 }
215
216
217 /*
218  * Class:     sun/misc/Unsafe
219  * Method:    getBoolean
220  * Signature: (Ljava/lang/Object;J)Z
221  */
222 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
223 {
224         int32_t *p;
225         int32_t  value;
226
227         p = (int32_t *) (((uint8_t *) o) + offset);
228
229         value = *p;
230
231         return value;
232 }
233
234
235 /*
236  * Class:     sun/misc/Unsafe
237  * Method:    putBoolean
238  * Signature: (Ljava/lang/Object;JZ)V
239  */
240 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
241 {
242         int32_t *p;
243
244         p = (int32_t *) (((uint8_t *) o) + offset);
245
246         *p = x;
247 }
248
249
250 /*
251  * Class:     sun/misc/Unsafe
252  * Method:    getByte
253  * Signature: (Ljava/lang/Object;J)B
254  */
255 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)
256 {
257         int32_t *p;
258         int32_t  value;
259
260         p = (int32_t *) (((uint8_t *) o) + offset);
261
262         value = *p;
263
264         return value;
265 }
266
267
268 /*
269  * Class:     sun/misc/Unsafe
270  * Method:    putByte
271  * Signature: (Ljava/lang/Object;JB)V
272  */
273 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)
274 {
275         int32_t *p;
276
277         p = (int32_t *) (((uint8_t *) o) + offset);
278
279         *p = x;
280 }
281
282
283 /*
284  * Class:     sun/misc/Unsafe
285  * Method:    getShort
286  * Signature: (Ljava/lang/Object;J)S
287  */
288 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
289 {
290         int32_t *p;
291         int32_t  value;
292
293         p = (int32_t *) (((uint8_t *) o) + offset);
294
295         value = *p;
296
297         return value;
298 }
299
300
301 /*
302  * Class:     sun/misc/Unsafe
303  * Method:    putShort
304  * Signature: (Ljava/lang/Object;JS)V
305  */
306 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)
307 {
308         int32_t *p;
309
310         p = (int32_t *) (((uint8_t *) o) + offset);
311
312         *p = x;
313 }
314
315
316 /*
317  * Class:     sun/misc/Unsafe
318  * Method:    getChar
319  * Signature: (Ljava/lang/Object;J)C
320  */
321 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)
322 {
323         int32_t *p;
324         int32_t  value;
325
326         p = (int32_t *) (((uint8_t *) o) + offset);
327
328         value = *p;
329
330         return value;
331 }
332
333
334 /*
335  * Class:     sun/misc/Unsafe
336  * Method:    putChar
337  * Signature: (Ljava/lang/Object;JC)V
338  */
339 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)
340 {
341         int32_t *p;
342
343         p = (int32_t *) (((uint8_t *) o) + offset);
344
345         *p = x;
346 }
347
348
349 /*
350  * Class:     sun/misc/Unsafe
351  * Method:    getLong
352  * Signature: (Ljava/lang/Object;J)J
353  */
354 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)
355 {
356         int64_t *p;
357         int64_t  value;
358
359         p = (int64_t *) (((uint8_t *) o) + offset);
360
361         value = *p;
362
363         return value;
364 }
365
366
367 /*
368  * Class:     sun/misc/Unsafe
369  * Method:    putLong
370  * Signature: (Ljava/lang/Object;JJ)V
371  */
372 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x)
373 {
374         int64_t *p;
375
376         p = (int64_t *) (((uint8_t *) o) + offset);
377
378         *p = x;
379 }
380
381
382 /*
383  * Class:     sun/misc/Unsafe
384  * Method:    getFloat
385  * Signature: (Ljava/lang/Object;J)F
386  */
387 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)
388 {
389         float *p;
390         float  value;
391
392         p = (float *) (((uint8_t *) o) + offset);
393
394         value = *p;
395
396         return value;
397 }
398
399
400 /*
401  * Class:     sun/misc/Unsafe
402  * Method:    putFloat
403  * Signature: (Ljava/lang/Object;JF)V
404  */
405 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)
406 {
407         float *p;
408
409         p = (float *) (((uint8_t *) o) + offset);
410
411         *p = x;
412 }
413
414
415 /*
416  * Class:     sun/misc/Unsafe
417  * Method:    getDouble
418  * Signature: (Ljava/lang/Object;J)D
419  */
420 JNIEXPORT double JNICALL Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
421 {
422         double *p;
423         double  value;
424
425         p = (double *) (((uint8_t *) o) + offset);
426
427         value = *p;
428
429         return value;
430 }
431
432
433 /*
434  * Class:     sun/misc/Unsafe
435  * Method:    putDouble
436  * Signature: (Ljava/lang/Object;JD)V
437  */
438 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, double x)
439 {
440         double *p;
441
442         p = (double *) (((uint8_t *) o) + offset);
443
444         *p = x;
445 }
446
447
448 /*
449  * Class:     sun/misc/Unsafe
450  * Method:    getByte
451  * Signature: (J)B
452  */
453 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
454 {
455         int8_t *p;
456         int8_t  value;
457
458         p = (int8_t *) (intptr_t) address;
459
460         value = *p;
461
462         return (int32_t) value;
463 }
464
465
466 /*
467  * Class:     sun/misc/Unsafe
468  * Method:    putByte
469  * Signature: (JB)V
470  */
471 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__JB(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
472 {
473         int8_t *p;
474
475         p = (int8_t *) (intptr_t) address;
476
477         *p = (int8_t) value;
478 }
479
480
481 /*
482  * Class:     sun/misc/Unsafe
483  * Method:    getShort
484  * Signature: (J)S
485  */
486 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
487 {
488         int16_t *p;
489         int16_t  value;
490
491         p = (int16_t *) (intptr_t) address;
492
493         value = *p;
494
495         return (int32_t) value;
496 }
497
498
499 /*
500  * Class:     sun/misc/Unsafe
501  * Method:    putShort
502  * Signature: (JS)V
503  */
504 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__JS(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
505 {
506         int16_t *p;
507
508         p = (int16_t *) (intptr_t) address;
509
510         *p = (int16_t) value;
511 }
512
513
514 /*
515  * Class:     sun/misc/Unsafe
516  * Method:    getChar
517  * Signature: (J)C
518  */
519 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
520 {
521         uint16_t *p;
522         uint16_t  value;
523
524         p = (uint16_t *) (intptr_t) address;
525
526         value = *p;
527
528         return (int32_t) value;
529 }
530
531
532 /*
533  * Class:     sun/misc/Unsafe
534  * Method:    putChar
535  * Signature: (JC)V
536  */
537 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__JC(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
538 {
539         uint16_t *p;
540
541         p = (uint16_t *) (intptr_t) address;
542
543         *p = (uint16_t) value;
544 }
545
546
547 /*
548  * Class:     sun/misc/Unsafe
549  * Method:    getInt
550  * Signature: (J)I
551  */
552 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
553 {
554         int32_t *p;
555         int32_t  value;
556
557         p = (int32_t *) (intptr_t) address;
558
559         value = *p;
560
561         return value;
562 }
563
564
565 /*
566  * Class:     sun/misc/Unsafe
567  * Method:    putInt
568  * Signature: (JI)V
569  */
570 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__JI(JNIEnv *env, struct sun_misc_Unsafe* this, int64_t address, int32_t value)
571 {
572         int32_t *p;
573
574         p = (int32_t *) (intptr_t) address;
575
576         *p = value;
577 }
578
579
580 /*
581  * Class:     sun/misc/Unsafe
582  * Method:    getLong
583  * Signature: (J)J
584  */
585 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
586 {
587         int64_t *p;
588         int64_t  value;
589
590         p = (int64_t *) (intptr_t) address;
591
592         value = *p;
593
594         return value;
595 }
596
597
598 /*
599  * Class:     sun/misc/Unsafe
600  * Method:    putLong
601  * Signature: (JJ)V
602  */
603 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
604 {
605         int64_t *p;
606
607         p = (int64_t *) (intptr_t) address;
608
609         *p = value;
610 }
611
612
613 /*
614  * Class:     sun/misc/Unsafe
615  * Method:    getFloat
616  * Signature: (J)F
617  */
618 JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
619 {
620         float *p;
621         float  value;
622
623         p = (float *) (intptr_t) address;
624
625         value = *p;
626
627         return value;
628 }
629
630
631 /*
632  * Class:     sun/misc/Unsafe
633  * Method:    objectFieldOffset
634  * Signature: (Ljava/lang/reflect/Field;)J
635  */
636 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
637 {
638         classinfo *c;
639         fieldinfo *f;
640         int32_t    slot;
641
642         LLNI_field_get_cls(field, clazz, c);
643         LLNI_field_get_val(field, slot , slot);
644
645         f = &c->fields[slot];
646
647         return (int64_t) f->offset;
648 }
649
650
651 /*
652  * Class:     sun/misc/Unsafe
653  * Method:    allocateMemory
654  * Signature: (J)J
655  */
656 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
657 {
658         size_t  length;
659         void   *p;
660
661         length = (size_t) bytes;
662
663         if ((length != (uint64_t) bytes) || (bytes < 0)) {
664                 exceptions_throw_illegalargumentexception();
665                 return 0;
666         }
667
668         p = MNEW(uint8_t, length);
669
670         return (int64_t) (intptr_t) p;
671 }
672
673
674 /*
675  * Class:     sun/misc/Unsafe
676  * Method:    setMemory
677  * Signature: (Ljava/lang/Object;JJB)V
678  */
679 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)
680 {
681         size_t  length;
682         void   *p;
683
684         length = (size_t) bytes;
685
686         if ((length != (uint64_t) bytes) || (bytes < 0)) {
687                 exceptions_throw_illegalargumentexception();
688                 return;
689         }
690
691         /* XXX Missing LLNI: we need to unwrap this object. */
692
693         p = (void *) (((uint8_t *) o) + offset);
694
695         /* XXX Not sure this is correct. */
696
697         MSET(p, value, uint8_t, length);
698 }
699
700
701 /*
702  * Class:     sun/misc/Unsafe
703  * Method:    copyMemory
704  * Signature: (Ljava/lang/Object;JLjava/lang/Object;JJ)V
705  */
706 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *srcBase, int64_t srcOffset, java_lang_Object *destBase, int64_t destOffset, int64_t bytes)
707 {
708         size_t  length;
709         void   *src;
710         void   *dest;
711
712         if (bytes == 0)
713                 return;
714
715         length = (size_t) bytes;
716
717         if ((length != (uint64_t) bytes) || (bytes < 0)) {
718                 exceptions_throw_illegalargumentexception();
719                 return;
720         }
721
722         /* XXX Missing LLNI: We need to unwrap these objects. */
723
724         src  = (void *) (((uint8_t *) srcBase) + srcOffset);
725         dest = (void *) (((uint8_t *) destBase) + destOffset);
726
727         MCOPY(dest, src, uint8_t, length);
728 }
729
730
731 /*
732  * Class:     sun/misc/Unsafe
733  * Method:    freeMemory
734  * Signature: (J)V
735  */
736 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
737 {
738         void *p;
739
740         p = (void *) (intptr_t) address;
741
742         if (p == NULL)
743                 return;
744
745         /* we pass length 1 to trick the free function */
746
747         MFREE(p, uint8_t, 1);
748 }
749
750
751 /*
752  * Class:     sun/misc/Unsafe
753  * Method:    staticFieldOffset
754  * Signature: (Ljava/lang/reflect/Field;)J
755  */
756 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
757 {
758         /* The offset of static fields is 0. */
759
760         return 0;
761 }
762
763
764 /*
765  * Class:     sun/misc/Unsafe
766  * Method:    staticFieldBase
767  * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
768  */
769 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *rf)
770 {
771         classinfo *c;
772         fieldinfo *f;
773         int32_t    slot;
774
775         LLNI_field_get_cls(rf, clazz, c);
776         LLNI_field_get_val(rf, slot , slot);
777
778         f = &(c->fields[slot]);
779
780         return (java_lang_Object *) (f->value);
781 }
782
783
784 /*
785  * Class:     sun/misc/Unsafe
786  * Method:    ensureClassInitialized
787  * Signature: (Ljava/lang/Class;)V
788  */
789 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
790 {
791         classinfo *c;
792
793         c = LLNI_classinfo_unwrap(class);
794
795         if (!(c->state & CLASS_INITIALIZED))
796                 initialize_class(c);
797 }
798
799
800 /*
801  * Class:     sun/misc/Unsafe
802  * Method:    arrayBaseOffset
803  * Signature: (Ljava/lang/Class;)I
804  */
805 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
806 {
807         classinfo       *c;
808         arraydescriptor *ad;
809
810         c  = LLNI_classinfo_unwrap(arrayClass);
811         ad = c->vftbl->arraydesc;
812
813         if (ad == NULL) {
814                 /* XXX does that exception exist? */
815                 exceptions_throw_internalerror("java/lang/InvalidClassException");
816                 return 0;
817         }
818
819         return ad->dataoffset;
820 }
821
822
823 /*
824  * Class:     sun/misc/Unsafe
825  * Method:    arrayIndexScale
826  * Signature: (Ljava/lang/Class;)I
827  */
828 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
829 {
830         classinfo       *c;
831         arraydescriptor *ad;
832
833         c  = LLNI_classinfo_unwrap(arrayClass);
834         ad = c->vftbl->arraydesc;
835
836         if (ad == NULL) {
837                 /* XXX does that exception exist? */
838                 exceptions_throw_internalerror("java/lang/InvalidClassException");
839                 return 0;
840         }
841
842         return ad->componentsize;
843 }
844
845
846 /*
847  * Class:     sun/misc/Unsafe
848  * Method:    addressSize
849  * Signature: ()I
850  */
851 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this)
852 {
853         return SIZEOF_VOID_P;
854 }
855
856
857 /*
858  * Class:     sun/misc/Unsafe
859  * Method:    pageSize
860  * Signature: ()I
861  */
862 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_pageSize(JNIEnv *env, sun_misc_Unsafe *this)
863 {
864         int sz;
865
866         sz = getpagesize();
867
868         return sz;
869 }
870
871
872 /*
873  * Class:     sun/misc/Unsafe
874  * Method:    defineClass
875  * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
876  */
877 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)
878 {
879         classloader     *cl;
880         utf             *utfname;
881         classinfo       *c;
882         java_lang_Class *o;
883
884         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
885
886         /* check if data was passed */
887
888         if (b == NULL) {
889                 exceptions_throw_nullpointerexception();
890                 return NULL;
891         }
892
893         /* check the indexes passed */
894
895         if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) {
896                 exceptions_throw_arrayindexoutofboundsexception();
897                 return NULL;
898         }
899
900         if (name != NULL) {
901                 /* convert '.' to '/' in java string */
902
903                 utfname = javastring_toutf((java_handle_t *) name, true);
904         } 
905         else {
906                 utfname = NULL;
907         }
908
909         /* define the class */
910
911         c = class_define(utfname, cl, len, (uint8_t *) &(LLNI_array_direct(b, off)),
912                                          (java_handle_t *) protectionDomain);
913
914         if (c == NULL)
915                 return NULL;
916
917         /* for convenience */
918
919         o = LLNI_classinfo_wrap(c);
920
921 #if defined(WITH_CLASSPATH_GNU)
922         /* set ProtectionDomain */
923
924         LLNI_field_set_ref(o, pd, protectionDomain);
925 #endif
926
927         return o;
928 }
929
930
931 /*
932  * Class:     sun/misc/Unsafe
933  * Method:    allocateInstance
934  * Signature: (Ljava/lang/Class;)Ljava/lang/Object;
935  */
936 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_allocateInstance(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *cls)
937 {
938         classinfo     *c;
939         java_handle_t *o;
940
941         c = LLNI_classinfo_unwrap(cls);
942
943         o = builtin_new(c);
944
945         return (java_lang_Object *) o;
946 }
947
948
949 /*
950  * Class:     sun/misc/Unsafe
951  * Method:    throwException
952  * Signature: (Ljava/lang/Throwable;)V
953  */
954 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
955 {
956         java_handle_t *o;
957
958         o = (java_handle_t *) ee;
959
960         exceptions_set_exception(o);
961 }
962
963
964 /*
965  * Class:     sun/misc/Unsafe
966  * Method:    compareAndSwapObject
967  * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
968  */
969 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)
970 {
971         void **p;
972         void  *value;
973
974         p = (void **) (((uint8_t *) o) + offset);
975
976         /* XXX this should be atomic */
977
978         value = *p;
979
980         if (value == expected) {
981                 *p = x;
982
983                 return true;
984         }
985
986         return false;
987 }
988
989
990 /*
991  * Class:     sun/misc/Unsafe
992  * Method:    compareAndSwapInt
993  * Signature: (Ljava/lang/Object;JII)Z
994  */
995 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)
996 {
997         int32_t *p;
998         int32_t  value;
999
1000         p = (int32_t *) (((uint8_t *) obj) + offset);
1001
1002         /* XXX this should be atomic */
1003
1004         value = *p;
1005
1006         if (value == expect) {
1007                 *p = update;
1008
1009                 return true;
1010         }
1011
1012         return false;
1013 }
1014
1015
1016 /*
1017  * Class:     sun/misc/Unsafe
1018  * Method:    compareAndSwapLong
1019  * Signature: (Ljava/lang/Object;JJJ)Z
1020  */
1021 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)
1022 {
1023         int64_t *p;
1024         int64_t  value;
1025
1026         p = (int64_t *) (((uint8_t *) o) + offset);
1027
1028         /* XXX this should be atomic */
1029
1030         value = *p;
1031
1032         if (value == expected) {
1033                 *p = x;
1034
1035                 return true;
1036         }
1037
1038         return false;
1039 }
1040
1041
1042 /*
1043  * Class:     sun/misc/Unsafe
1044  * Method:    getObjectVolatile
1045  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
1046  */
1047 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
1048 {
1049         volatile void **p;
1050         volatile void  *value;
1051
1052         p = (volatile void **) (((uint8_t *) o) + offset);
1053
1054         value = *p;
1055
1056         return (java_lang_Object *) value;
1057 }
1058
1059
1060 /*
1061  * Class:     sun/misc/Unsafe
1062  * Method:    putObjectVolatile
1063  * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
1064  */
1065 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
1066 {
1067         volatile void **p;
1068
1069         p = (volatile void **) (((uint8_t *) o) + offset);
1070
1071         *p = x;
1072 }
1073
1074
1075 /*
1076  * Class:     sun/misc/Unsafe
1077  * Method:    getIntVolatile
1078  * Signature: (Ljava/lang/Object;J)I
1079  */
1080 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
1081 {
1082         volatile int32_t *p;
1083         volatile int32_t  value;
1084
1085         p = (volatile int32_t *) (((uint8_t *) o) + offset);
1086
1087         value = *p;
1088
1089         return value;
1090 }
1091
1092
1093 /*
1094  * Class:     sun/misc/Unsafe
1095  * Method:    getLongVolatile
1096  * Signature: (Ljava/lang/Object;J)J
1097  */
1098 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
1099 {
1100         volatile int64_t *p;
1101         volatile int64_t  value;
1102
1103         p = (volatile int64_t *) (((uint8_t *) o) + offset);
1104
1105         value = *p;
1106
1107         return value;
1108 }
1109
1110
1111 /*
1112  * Class:     sun/misc/Unsafe
1113  * Method:    unpark
1114  * Signature: (Ljava/lang/Object;)V
1115  */
1116 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
1117 {
1118         /* XXX IMPLEMENT ME */
1119 }
1120
1121
1122 /*
1123  * Class:     sun/misc/Unsafe
1124  * Method:    park
1125  * Signature: (ZJ)V
1126  */
1127 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
1128 {
1129         /* XXX IMPLEMENT ME */
1130 }
1131
1132
1133 /*
1134  * These are local overrides for various environment variables in Emacs.
1135  * Please do not remove this and leave it at the end of the file, where
1136  * Emacs will automagically detect them.
1137  * ---------------------------------------------------------------------
1138  * Local variables:
1139  * mode: c
1140  * indent-tabs-mode: t
1141  * c-basic-offset: 4
1142  * tab-width: 4
1143  * End:
1144  */