1 /* src/native/vm/sun_misc_Unsafe.c - sun/misc/Unsafe
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
8 This file is part of CACAO.
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.
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.
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
25 $Id: java_lang_VMObject.c 5153 2006-07-18 08:19:24Z twisti $
34 #include "mm/memory.h"
36 #include "native/jni.h"
37 #include "native/native.h"
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 */
42 #if defined(WITH_CLASSPATH_SUN)
43 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
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"
52 #include "native/include/java_security_ProtectionDomain.h" /* required by smU */
54 #include "native/include/sun_misc_Unsafe.h"
56 #include "vm/exceptions.h"
57 #include "vm/initialize.h"
58 #include "vm/stringlocal.h"
60 #include "vmcore/utf8.h"
63 /* native methods implemented by this file ************************************/
65 static JNINativeMethod methods[] = {
66 { "registerNatives", "()V", (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives },
67 { "getInt", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J },
68 { "putInt", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI },
69 { "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObject },
70 { "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject },
71 { "getBoolean", "(Ljava/lang/Object;J)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean },
72 { "putBoolean", "(Ljava/lang/Object;JZ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean },
73 { "getByte", "(Ljava/lang/Object;J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J },
74 { "putByte", "(Ljava/lang/Object;JB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB },
75 { "getChar", "(Ljava/lang/Object;J)C", (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J },
76 { "putChar", "(Ljava/lang/Object;JC)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC },
77 { "getByte", "(J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J },
78 { "getInt", "(J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J },
79 { "getLong", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J },
80 { "putLong", "(JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ },
81 { "objectFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset },
82 { "allocateMemory", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory },
83 { "freeMemory", "(J)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory },
84 { "staticFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset },
85 { "staticFieldBase", "(Ljava/lang/reflect/Field;)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase },
86 { "ensureClassInitialized", "(Ljava/lang/Class;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized },
87 { "arrayBaseOffset", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset },
88 { "arrayIndexScale", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale },
89 { "addressSize", "()I", (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize },
90 { "defineClass", "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (intptr_t) &Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2 },
91 { "throwException", "(Ljava/lang/Throwable;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException },
92 { "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject },
93 { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt },
94 { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong },
95 { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile },
96 { "getIntVolatile", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile },
97 { "unpark", "(Ljava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark },
98 { "park", "(ZJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_park },
102 /* _Jv_sun_misc_Unsafe_init ****************************************************
104 Register native functions.
106 *******************************************************************************/
108 void _Jv_sun_misc_Unsafe_init(void)
112 u = utf_new_char("sun/misc/Unsafe");
114 native_method_register(u, methods, NATIVE_METHODS_COUNT);
119 * Class: sun/misc/Unsafe
120 * Method: registerNatives
123 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
125 /* The native methods of this function are already registered in
126 _Jv_sun_misc_Unsafe_init() which is called during VM
132 * Class: sun/misc/Unsafe
134 * Signature: (Ljava/lang/Object;J)I
136 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
141 p = (int32_t *) (((uint8_t *) o) + offset);
150 * Class: sun/misc/Unsafe
152 * Signature: (Ljava/lang/Object;JI)V
154 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
158 p = (int32_t *) (((uint8_t *) o) + offset);
165 * Class: sun/misc/Unsafe
167 * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
169 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
174 p = (void **) (((uint8_t *) o) + offset);
183 * Class: sun/misc/Unsafe
185 * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
187 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
191 p = (void **) (((uint8_t *) o) + offset);
198 * Class: sun/misc/Unsafe
200 * Signature: (Ljava/lang/Object;J)Z
202 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
207 p = (int32_t *) (((uint8_t *) o) + offset);
216 * Class: sun/misc/Unsafe
218 * Signature: (Ljava/lang/Object;JZ)V
220 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
224 p = (int32_t *) (((uint8_t *) o) + offset);
231 * Class: sun/misc/Unsafe
233 * Signature: (Ljava/lang/Object;J)B
235 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
240 p = (int32_t *) (((uint8_t *) o) + offset);
249 * Class: sun/misc/Unsafe
251 * Signature: (Ljava/lang/Object;JB)V
253 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
257 p = (int32_t *) (((uint8_t *) o) + offset);
264 * Class: sun/misc/Unsafe
266 * Signature: (Ljava/lang/Object;J)C
268 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
273 p = (int32_t *) (((uint8_t *) o) + offset);
282 * Class: sun/misc/Unsafe
284 * Signature: (Ljava/lang/Object;JC)V
286 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
290 p = (int32_t *) (((uint8_t *) o) + offset);
297 * Class: sun/misc/Unsafe
301 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
306 p = (int8_t *) (intptr_t) address;
310 return (int32_t) value;
315 * Class: sun/misc/Unsafe
319 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
324 p = (int32_t *) (intptr_t) address;
333 * Class: sun/misc/Unsafe
337 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
342 p = (int64_t *) (intptr_t) address;
351 * Class: sun/misc/Unsafe
355 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
359 p = (int64_t *) (intptr_t) address;
366 * Class: sun/misc/Unsafe
367 * Method: objectFieldOffset
368 * Signature: (Ljava/lang/reflect/Field;)J
370 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field)
375 c = (classinfo *) field->clazz;
376 f = &c->fields[field->slot];
378 return (int64_t) f->offset;
383 * Class: sun/misc/Unsafe
384 * Method: allocateMemory
387 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
392 length = (size_t) bytes;
394 if ((length != (uint64_t) bytes) || (bytes < 0)) {
395 exceptions_throw_illegalargumentexception();
399 p = MNEW(uint8_t, length);
401 return (int64_t) (intptr_t) p;
406 * Class: sun/misc/Unsafe
410 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
414 p = (void *) (intptr_t) address;
419 /* we pass length 1 to trick the free function */
421 MFREE(p, uint8_t, 1);
426 * Class: sun/misc/Unsafe
427 * Method: staticFieldOffset
428 * Signature: (Ljava/lang/reflect/Field;)J
430 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
435 c = (classinfo *) field->clazz;
436 f = &(c->fields[field->slot]);
438 return (int64_t) (intptr_t) &(f->value);
443 * Class: sun/misc/Unsafe
444 * Method: staticFieldBase
445 * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
447 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
449 /* In CACAO we return the absolute address in staticFieldOffset. */
456 * Class: sun/misc/Unsafe
457 * Method: ensureClassInitialized
458 * Signature: (Ljava/lang/Class;)V
460 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
464 c = (classinfo *) class;
466 if (!(c->state & CLASS_INITIALIZED))
472 * Class: sun/misc/Unsafe
473 * Method: arrayBaseOffset
474 * Signature: (Ljava/lang/Class;)I
476 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
481 c = (classinfo *) arrayClass;
482 ad = c->vftbl->arraydesc;
485 /* XXX does that exception exist? */
486 exceptions_throw_internalerror("java/lang/InvalidClassException");
490 return ad->dataoffset;
495 * Class: sun/misc/Unsafe
496 * Method: arrayIndexScale
497 * Signature: (Ljava/lang/Class;)I
499 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
504 c = (classinfo *) arrayClass;
505 ad = c->vftbl->arraydesc;
508 /* XXX does that exception exist? */
509 exceptions_throw_internalerror("java/lang/InvalidClassException");
513 return ad->componentsize;
518 * Class: sun/misc/Unsafe
519 * Method: addressSize
522 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this)
524 return SIZEOF_VOID_P;
529 * Class: sun/misc/Unsafe
530 * Method: defineClass
531 * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
533 JNIEXPORT java_lang_Class* JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(JNIEnv *env, sun_misc_Unsafe *this, java_lang_String *name, java_bytearray *b, int32_t off, int32_t len, java_lang_ClassLoader *loader, java_security_ProtectionDomain *protectionDomain)
535 java_objectheader *cl;
540 cl = (java_objectheader *) loader;
542 /* check if data was passed */
545 exceptions_throw_nullpointerexception();
549 /* check the indexes passed */
551 if ((off < 0) || (len < 0) || ((off + len) > b->header.size)) {
552 exceptions_throw_arrayindexoutofboundsexception();
557 /* convert '.' to '/' in java string */
559 utfname = javastring_toutf((java_objectheader *) name, true);
565 /* define the class */
567 c = class_define(utfname, cl, len, (const uint8_t *) &b->data[off]);
572 /* for convenience */
574 o = (java_lang_Class *) c;
576 #if defined(WITH_CLASSPATH_GNU)
577 /* set ProtectionDomain */
579 o->pd = protectionDomain;
587 * Class: sun/misc/Unsafe
588 * Method: throwException
589 * Signature: (Ljava/lang/Throwable;)V
591 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
593 java_objectheader *o;
595 o = (java_objectheader *) ee;
597 exceptions_set_exception(o);
602 * Class: sun/misc/Unsafe
603 * Method: compareAndSwapObject
604 * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
606 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *expected, java_lang_Object *x)
611 p = (void **) (((uint8_t *) o) + offset);
613 /* XXX this should be atomic */
617 if (value == expected) {
628 * Class: sun/misc/Unsafe
629 * Method: compareAndSwapInt
630 * Signature: (Ljava/lang/Object;JII)Z
632 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* obj, int64_t offset, int32_t expect, int32_t update)
637 p = (int32_t *) (((uint8_t *) obj) + offset);
639 /* XXX this should be atomic */
643 if (value == expect) {
654 * Class: sun/misc/Unsafe
655 * Method: compareAndSwapLong
656 * Signature: (Ljava/lang/Object;JJJ)Z
658 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t expected, int64_t x)
663 p = (int64_t *) (((uint8_t *) o) + offset);
665 /* XXX this should be atomic */
669 if (value == expected) {
680 * Class: sun/misc/Unsafe
681 * Method: getObjectVolatile
682 * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
684 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
687 volatile void *value;
689 p = (volatile void **) (((uint8_t *) o) + offset);
693 return (java_lang_Object *) value;
698 * Class: sun/misc/Unsafe
699 * Method: getIntVolatile
700 * Signature: (Ljava/lang/Object;J)I
702 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
705 volatile int32_t value;
707 p = (volatile int32_t *) (((uint8_t *) o) + offset);
716 * Class: sun/misc/Unsafe
718 * Signature: (Ljava/lang/Object;)V
720 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
722 /* XXX IMPLEMENT ME */
727 * Class: sun/misc/Unsafe
731 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
733 /* XXX IMPLEMENT ME */
738 * These are local overrides for various environment variables in Emacs.
739 * Please do not remove this and leave it at the end of the file, where
740 * Emacs will automagically detect them.
741 * ---------------------------------------------------------------------
744 * indent-tabs-mode: t