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 #if defined(WITH_CLASSPATH_SUN)
53 # include "native/include/java_security_ProtectionDomain.h" /* required by smU*/
56 #include "native/include/sun_misc_Unsafe.h"
58 #include "vm/exceptions.h"
59 #include "vm/initialize.h"
60 #include "vm/stringlocal.h"
62 #include "vmcore/utf8.h"
65 /* native methods implemented by this file ************************************/
67 static JNINativeMethod methods[] = {
68 { "registerNatives", "()V", (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives },
69 { "getInt", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J },
70 { "putInt", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI },
71 { "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObject },
72 { "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject },
73 { "getBoolean", "(Ljava/lang/Object;J)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean },
74 { "putBoolean", "(Ljava/lang/Object;JZ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean },
75 { "getByte", "(Ljava/lang/Object;J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J },
76 { "putByte", "(Ljava/lang/Object;JB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB },
77 { "getChar", "(Ljava/lang/Object;J)C", (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J },
78 { "putChar", "(Ljava/lang/Object;JC)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC },
79 { "getByte", "(J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J },
80 { "getInt", "(J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J },
81 { "getLong", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J },
82 { "putLong", "(JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ },
83 { "objectFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset },
84 { "allocateMemory", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory },
85 { "freeMemory", "(J)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory },
86 { "staticFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset },
87 { "staticFieldBase", "(Ljava/lang/reflect/Field;)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase },
88 { "ensureClassInitialized", "(Ljava/lang/Class;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized },
89 { "arrayBaseOffset", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset },
90 { "arrayIndexScale", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale },
91 { "addressSize", "()I", (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize },
92 { "defineClass", "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (intptr_t) &Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2 },
93 { "throwException", "(Ljava/lang/Throwable;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException },
94 { "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject },
95 { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt },
96 { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong },
97 { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile },
98 { "getIntVolatile", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile },
99 { "unpark", "(Ljava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark },
100 { "park", "(ZJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_park },
104 /* _Jv_sun_misc_Unsafe_init ****************************************************
106 Register native functions.
108 *******************************************************************************/
110 void _Jv_sun_misc_Unsafe_init(void)
114 u = utf_new_char("sun/misc/Unsafe");
116 native_method_register(u, methods, NATIVE_METHODS_COUNT);
121 * Class: sun/misc/Unsafe
122 * Method: registerNatives
125 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
127 /* The native methods of this function are already registered in
128 _Jv_sun_misc_Unsafe_init() which is called during VM
134 * Class: sun/misc/Unsafe
136 * Signature: (Ljava/lang/Object;J)I
138 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
143 p = (int32_t *) (((uint8_t *) o) + offset);
152 * Class: sun/misc/Unsafe
154 * Signature: (Ljava/lang/Object;JI)V
156 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
160 p = (int32_t *) (((uint8_t *) o) + offset);
167 * Class: sun/misc/Unsafe
169 * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
171 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
176 p = (void **) (((uint8_t *) o) + offset);
185 * Class: sun/misc/Unsafe
187 * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
189 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
193 p = (void **) (((uint8_t *) o) + offset);
200 * Class: sun/misc/Unsafe
202 * Signature: (Ljava/lang/Object;J)Z
204 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
209 p = (int32_t *) (((uint8_t *) o) + offset);
218 * Class: sun/misc/Unsafe
220 * Signature: (Ljava/lang/Object;JZ)V
222 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
226 p = (int32_t *) (((uint8_t *) o) + offset);
233 * Class: sun/misc/Unsafe
235 * Signature: (Ljava/lang/Object;J)B
237 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
242 p = (int32_t *) (((uint8_t *) o) + offset);
251 * Class: sun/misc/Unsafe
253 * Signature: (Ljava/lang/Object;JB)V
255 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
259 p = (int32_t *) (((uint8_t *) o) + offset);
266 * Class: sun/misc/Unsafe
268 * Signature: (Ljava/lang/Object;J)C
270 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
275 p = (int32_t *) (((uint8_t *) o) + offset);
284 * Class: sun/misc/Unsafe
286 * Signature: (Ljava/lang/Object;JC)V
288 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
292 p = (int32_t *) (((uint8_t *) o) + offset);
299 * Class: sun/misc/Unsafe
303 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
308 p = (int8_t *) (intptr_t) address;
312 return (int32_t) value;
317 * Class: sun/misc/Unsafe
321 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
326 p = (int32_t *) (intptr_t) address;
335 * Class: sun/misc/Unsafe
339 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
344 p = (int64_t *) (intptr_t) address;
353 * Class: sun/misc/Unsafe
357 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
361 p = (int64_t *) (intptr_t) address;
368 * Class: sun/misc/Unsafe
369 * Method: objectFieldOffset
370 * Signature: (Ljava/lang/reflect/Field;)J
372 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field)
377 c = (classinfo *) field->clazz;
378 f = &c->fields[field->slot];
380 return (int64_t) f->offset;
385 * Class: sun/misc/Unsafe
386 * Method: allocateMemory
389 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
394 length = (size_t) bytes;
396 if ((length != (uint64_t) bytes) || (bytes < 0)) {
397 exceptions_throw_illegalargumentexception();
401 p = MNEW(uint8_t, length);
403 return (int64_t) (intptr_t) p;
408 * Class: sun/misc/Unsafe
412 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
416 p = (void *) (intptr_t) address;
421 /* we pass length 1 to trick the free function */
423 MFREE(p, uint8_t, 1);
428 * Class: sun/misc/Unsafe
429 * Method: staticFieldOffset
430 * Signature: (Ljava/lang/reflect/Field;)J
432 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
437 c = (classinfo *) field->clazz;
438 f = &(c->fields[field->slot]);
440 return (int64_t) (intptr_t) &(f->value);
445 * Class: sun/misc/Unsafe
446 * Method: staticFieldBase
447 * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
449 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
451 /* In CACAO we return the absolute address in staticFieldOffset. */
458 * Class: sun/misc/Unsafe
459 * Method: ensureClassInitialized
460 * Signature: (Ljava/lang/Class;)V
462 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
466 c = (classinfo *) class;
468 if (!(c->state & CLASS_INITIALIZED))
474 * Class: sun/misc/Unsafe
475 * Method: arrayBaseOffset
476 * Signature: (Ljava/lang/Class;)I
478 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
483 c = (classinfo *) arrayClass;
484 ad = c->vftbl->arraydesc;
487 /* XXX does that exception exist? */
488 exceptions_throw_internalerror("java/lang/InvalidClassException");
492 return ad->dataoffset;
497 * Class: sun/misc/Unsafe
498 * Method: arrayIndexScale
499 * Signature: (Ljava/lang/Class;)I
501 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
506 c = (classinfo *) arrayClass;
507 ad = c->vftbl->arraydesc;
510 /* XXX does that exception exist? */
511 exceptions_throw_internalerror("java/lang/InvalidClassException");
515 return ad->componentsize;
520 * Class: sun/misc/Unsafe
521 * Method: addressSize
524 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this)
526 return SIZEOF_VOID_P;
531 * Class: sun/misc/Unsafe
532 * Method: defineClass
533 * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
535 JNIEXPORT java_lang_Class* JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(JNIEnv *env, sun_misc_Unsafe *this, java_lang_String *name, java_bytearray *b, int32_t off, int32_t len, java_lang_ClassLoader *loader, java_security_ProtectionDomain *protectionDomain)
537 java_objectheader *cl;
542 cl = (java_objectheader *) loader;
544 /* check if data was passed */
547 exceptions_throw_nullpointerexception();
551 /* check the indexes passed */
553 if ((off < 0) || (len < 0) || ((off + len) > b->header.size)) {
554 exceptions_throw_arrayindexoutofboundsexception();
559 /* convert '.' to '/' in java string */
561 utfname = javastring_toutf((java_objectheader *) name, true);
567 /* define the class */
569 c = class_define(utfname, cl, len, (const uint8_t *) &b->data[off]);
574 /* for convenience */
576 o = (java_lang_Class *) c;
578 #if defined(WITH_CLASSPATH_GNU)
579 /* set ProtectionDomain */
589 * Class: sun/misc/Unsafe
590 * Method: throwException
591 * Signature: (Ljava/lang/Throwable;)V
593 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
595 java_objectheader *o;
597 o = (java_objectheader *) ee;
599 exceptions_set_exception(o);
604 * Class: sun/misc/Unsafe
605 * Method: compareAndSwapObject
606 * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
608 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *expected, java_lang_Object *x)
613 p = (void **) (((uint8_t *) o) + offset);
615 /* XXX this should be atomic */
619 if (value == expected) {
630 * Class: sun/misc/Unsafe
631 * Method: compareAndSwapInt
632 * Signature: (Ljava/lang/Object;JII)Z
634 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* obj, int64_t offset, int32_t expect, int32_t update)
639 p = (int32_t *) (((uint8_t *) obj) + offset);
641 /* XXX this should be atomic */
645 if (value == expect) {
656 * Class: sun/misc/Unsafe
657 * Method: compareAndSwapLong
658 * Signature: (Ljava/lang/Object;JJJ)Z
660 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t expected, int64_t x)
665 p = (int64_t *) (((uint8_t *) o) + offset);
667 /* XXX this should be atomic */
671 if (value == expected) {
682 * Class: sun/misc/Unsafe
683 * Method: getObjectVolatile
684 * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
686 JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
689 volatile void *value;
691 p = (volatile void **) (((uint8_t *) o) + offset);
695 return (java_lang_Object *) value;
700 * Class: sun/misc/Unsafe
701 * Method: getIntVolatile
702 * Signature: (Ljava/lang/Object;J)I
704 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
707 volatile int32_t value;
709 p = (volatile int32_t *) (((uint8_t *) o) + offset);
718 * Class: sun/misc/Unsafe
720 * Signature: (Ljava/lang/Object;)V
722 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
724 /* XXX IMPLEMENT ME */
729 * Class: sun/misc/Unsafe
733 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
735 /* XXX IMPLEMENT ME */
740 * These are local overrides for various environment variables in Emacs.
741 * Please do not remove this and leave it at the end of the file, where
742 * Emacs will automagically detect them.
743 * ---------------------------------------------------------------------
746 * indent-tabs-mode: t