* configure.ac,
[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
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         { "getBoolean",             "(Ljava/lang/Object;J)Z",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean                     },
70         { "putBoolean",             "(Ljava/lang/Object;JZ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean                     },
71         { "getByte",                "(Ljava/lang/Object;J)B",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J  },
72         { "putByte",                "(Ljava/lang/Object;JB)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB },
73         { "getChar",                "(Ljava/lang/Object;J)C",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J  },
74         { "putChar",                "(Ljava/lang/Object;JC)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC },
75         { "getByte",                "(J)B",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J                     },
76         { "getInt",                 "(J)I",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J                      },
77         { "getLong",                "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J                     },
78         { "putLong",                "(JJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ                    },
79         { "objectFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset              },
80         { "allocateMemory",         "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory                 },
81         { "freeMemory",             "(J)V",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory                     },
82         { "staticFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset              },
83         { "staticFieldBase",        "(Ljava/lang/reflect/Field;)Ljava/lang/Object;",              (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase                },
84         { "ensureClassInitialized", "(Ljava/lang/Class;)V",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized         },
85         { "throwException",         "(Ljava/lang/Throwable;)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException                 },
86         { "compareAndSwapObject",   "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject           },
87         { "compareAndSwapInt",      "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt              },
88         { "compareAndSwapLong",     "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong             },
89         { "getObjectVolatile",      "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile              },
90         { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
91 };
92
93
94 /* _Jv_sun_misc_Unsafe_init ****************************************************
95
96    Register native functions.
97
98 *******************************************************************************/
99
100 void _Jv_sun_misc_Unsafe_init(void)
101 {
102         utf *u;
103
104         u = utf_new_char("sun/misc/Unsafe");
105
106         native_method_register(u, methods, NATIVE_METHODS_COUNT);
107 }
108
109
110 /*
111  * Class:     sun/misc/Unsafe
112  * Method:    registerNatives
113  * Signature: ()V
114  */
115 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
116 {
117         /* The native methods of this function are already registered in
118            _Jv_sun_misc_Unsafe_init() which is called during VM
119            startup. */
120 }
121
122
123 /*
124  * Class:     sun/misc/Unsafe
125  * Method:    getInt
126  * Signature: (Ljava/lang/Object;J)I
127  */
128 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)
129 {
130         int32_t *p;
131         int32_t  value;
132
133         p = (int32_t *) (((uint8_t *) o) + offset);
134
135         value = *p;
136
137         return value;
138 }
139
140
141 /*
142  * Class:     sun/misc/Unsafe
143  * Method:    getBoolean
144  * Signature: (Ljava/lang/Object;J)Z
145  */
146 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
147 {
148         int32_t *p;
149         int32_t  value;
150
151         p = (int32_t *) (((uint8_t *) o) + offset);
152
153         value = *p;
154
155         return value;
156 }
157
158
159 /*
160  * Class:     sun/misc/Unsafe
161  * Method:    putBoolean
162  * Signature: (Ljava/lang/Object;JZ)V
163  */
164 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
165 {
166         int32_t *p;
167
168         p = (int32_t *) (((uint8_t *) o) + offset);
169
170         *p = x;
171 }
172
173
174 /*
175  * Class:     sun/misc/Unsafe
176  * Method:    getByte
177  * Signature: (Ljava/lang/Object;J)B
178  */
179 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)
180 {
181         int32_t *p;
182         int32_t  value;
183
184         p = (int32_t *) (((uint8_t *) o) + offset);
185
186         value = *p;
187
188         return value;
189 }
190
191
192 /*
193  * Class:     sun/misc/Unsafe
194  * Method:    putByte
195  * Signature: (Ljava/lang/Object;JB)V
196  */
197 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)
198 {
199         int32_t *p;
200
201         p = (int32_t *) (((uint8_t *) o) + offset);
202
203         *p = x;
204 }
205
206
207 /*
208  * Class:     sun/misc/Unsafe
209  * Method:    getChar
210  * Signature: (Ljava/lang/Object;J)C
211  */
212 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)
213 {
214         int32_t *p;
215         int32_t  value;
216
217         p = (int32_t *) (((uint8_t *) o) + offset);
218
219         value = *p;
220
221         return value;
222 }
223
224
225 /*
226  * Class:     sun/misc/Unsafe
227  * Method:    putChar
228  * Signature: (Ljava/lang/Object;JC)V
229  */
230 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)
231 {
232         int32_t *p;
233
234         p = (int32_t *) (((uint8_t *) o) + offset);
235
236         *p = x;
237 }
238
239
240 /*
241  * Class:     sun/misc/Unsafe
242  * Method:    getByte
243  * Signature: (J)B
244  */
245 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
246 {
247         int8_t *p;
248         int8_t  value;
249
250         p = (int8_t *) (intptr_t) address;
251
252         value = *p;
253
254         return (int32_t) value;
255 }
256
257
258 /*
259  * Class:     sun/misc/Unsafe
260  * Method:    getInt
261  * Signature: (J)I
262  */
263 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
264 {
265         int32_t *p;
266         int32_t  value;
267
268         p = (int32_t *) (intptr_t) address;
269
270         value = *p;
271
272         return value;
273 }
274
275
276 /*
277  * Class:     sun/misc/Unsafe
278  * Method:    getLong
279  * Signature: (J)J
280  */
281 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
282 {
283         int64_t *p;
284         int64_t  value;
285
286         p = (int64_t *) (intptr_t) address;
287
288         value = *p;
289
290         return value;
291 }
292
293
294 /*
295  * Class:     sun/misc/Unsafe
296  * Method:    putLong
297  * Signature: (JJ)V
298  */
299 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
300 {
301         int64_t *p;
302
303         p = (int64_t *) (intptr_t) address;
304
305         *p = value;
306 }
307
308
309 /*
310  * Class:     sun/misc/Unsafe
311  * Method:    objectFieldOffset
312  * Signature: (Ljava/lang/reflect/Field;)J
313  */
314 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field)
315 {
316         classinfo *c;
317         fieldinfo *f;
318
319         c = (classinfo *) field->clazz;
320         f = &c->fields[field->slot];
321
322         return (int64_t) f->offset;
323 }
324
325
326 /*
327  * Class:     sun/misc/Unsafe
328  * Method:    allocateMemory
329  * Signature: (J)J
330  */
331 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
332 {
333         size_t  length;
334         void   *p;
335
336         length = (size_t) bytes;
337
338         if ((length != (uint64_t) bytes) || (bytes < 0)) {
339                 exceptions_throw_illegalargumentexception();
340                 return 0;
341         }
342
343         p = MNEW(uint8_t, length);
344
345         return (int64_t) (intptr_t) p;
346 }
347
348
349 /*
350  * Class:     sun/misc/Unsafe
351  * Method:    freeMemory
352  * Signature: (J)V
353  */
354 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
355 {
356         void *p;
357
358         p = (void *) (intptr_t) address;
359
360         if (p == NULL)
361                 return;
362
363         /* we pass length 1 to trick the free function */
364
365         MFREE(p, uint8_t, 1);
366 }
367
368
369 /*
370  * Class:     sun/misc/Unsafe
371  * Method:    staticFieldOffset
372  * Signature: (Ljava/lang/reflect/Field;)J
373  */
374 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
375 {
376         classinfo *c;
377         fieldinfo *f;
378
379         c = (classinfo *) field->clazz;
380         f = &(c->fields[field->slot]);
381
382         return (int64_t) (intptr_t) &(f->value);
383 }
384
385
386 /*
387  * Class:     sun/misc/Unsafe
388  * Method:    staticFieldBase
389  * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
390  */
391 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
392 {
393         /* In CACAO we return the absolute address in staticFieldOffset. */
394
395         return NULL;
396 }
397
398
399 /*
400  * Class:     sun/misc/Unsafe
401  * Method:    ensureClassInitialized
402  * Signature: (Ljava/lang/Class;)V
403  */
404 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
405 {
406         classinfo *c;
407
408         c = (classinfo *) class;
409
410         if (!(c->state & CLASS_INITIALIZED))
411                 initialize_class(c);
412 }
413
414
415 /*
416  * Class:     sun/misc/Unsafe
417  * Method:    throwException
418  * Signature: (Ljava/lang/Throwable;)V
419  */
420 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
421 {
422         java_objectheader *o;
423
424         o = (java_objectheader *) ee;
425
426         exceptions_set_exception(o);
427 }
428
429
430 /*
431  * Class:     sun/misc/Unsafe
432  * Method:    compareAndSwapObject
433  * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
434  */
435 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)
436 {
437         void **p;
438         void  *value;
439
440         p = (void **) (((uint8_t *) o) + offset);
441
442         /* XXX this should be atomic */
443
444         value = *p;
445
446         if (value == expected) {
447                 *p = x;
448
449                 return true;
450         }
451
452         return false;
453 }
454
455
456 /*
457  * Class:     sun/misc/Unsafe
458  * Method:    compareAndSwapInt
459  * Signature: (Ljava/lang/Object;JII)Z
460  */
461 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)
462 {
463         int32_t *p;
464         int32_t  value;
465
466         p = (int32_t *) (((uint8_t *) obj) + offset);
467
468         /* XXX this should be atomic */
469
470         value = *p;
471
472         if (value == expect) {
473                 *p = update;
474
475                 return true;
476         }
477
478         return false;
479 }
480
481
482 /*
483  * Class:     sun/misc/Unsafe
484  * Method:    compareAndSwapLong
485  * Signature: (Ljava/lang/Object;JJJ)Z
486  */
487 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)
488 {
489         int64_t *p;
490         int64_t  value;
491
492         p = (int64_t *) (((uint8_t *) o) + offset);
493
494         /* XXX this should be atomic */
495
496         value = *p;
497
498         if (value == expected) {
499                 *p = x;
500
501                 return true;
502         }
503
504         return false;
505 }
506
507
508 /*
509  * Class:     sun/misc/Unsafe
510  * Method:    getObjectVolatile
511  * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
512  */
513 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
514 {
515         volatile void **p;
516         volatile void  *value;
517
518         p = (volatile void **) (((uint8_t *) o) + offset);
519
520         value = *p;
521
522         return (java_lang_Object *) value;
523 }
524
525
526 /*
527  * Class:     sun/misc/Unsafe
528  * Method:    getIntVolatile
529  * Signature: (Ljava/lang/Object;J)I
530  */
531 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
532 {
533         volatile int32_t *p;
534         volatile int32_t  value;
535
536         p = (volatile int32_t *) (((uint8_t *) o) + offset);
537
538         value = *p;
539
540         return value;
541 }
542
543
544 /*
545  * These are local overrides for various environment variables in Emacs.
546  * Please do not remove this and leave it at the end of the file, where
547  * Emacs will automagically detect them.
548  * ---------------------------------------------------------------------
549  * Local variables:
550  * mode: c
551  * indent-tabs-mode: t
552  * c-basic-offset: 4
553  * tab-width: 4
554  * End:
555  */