25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/classFileStream.hpp" |
26 #include "classfile/classFileStream.hpp" |
27 #include "classfile/vmSymbols.hpp" |
27 #include "classfile/vmSymbols.hpp" |
28 #include "memory/allocation.inline.hpp" |
28 #include "memory/allocation.inline.hpp" |
29 #include "memory/resourceArea.hpp" |
29 #include "memory/resourceArea.hpp" |
|
30 #include "oops/fieldStreams.hpp" |
30 #include "oops/objArrayOop.inline.hpp" |
31 #include "oops/objArrayOop.inline.hpp" |
31 #include "oops/oop.inline.hpp" |
32 #include "oops/oop.inline.hpp" |
32 #include "prims/jni.h" |
33 #include "prims/jni.h" |
33 #include "prims/jvm.h" |
34 #include "prims/jvm.h" |
34 #include "prims/unsafe.hpp" |
35 #include "prims/unsafe.hpp" |
581 |
582 |
582 UNSAFE_LEAF(jint, Unsafe_PageSize()) { |
583 UNSAFE_LEAF(jint, Unsafe_PageSize()) { |
583 return os::vm_page_size(); |
584 return os::vm_page_size(); |
584 } UNSAFE_END |
585 } UNSAFE_END |
585 |
586 |
586 static jint find_field_offset(jobject field, int must_be_static, TRAPS) { |
587 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) { |
|
588 assert(clazz != NULL, "clazz must not be NULL"); |
|
589 assert(name != NULL, "name must not be NULL"); |
|
590 |
|
591 ResourceMark rm(THREAD); |
|
592 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name)); |
|
593 |
|
594 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
|
595 |
|
596 jint offset = -1; |
|
597 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
|
598 Symbol *name = fs.name(); |
|
599 if (name->equals(utf_name)) { |
|
600 offset = fs.offset(); |
|
601 break; |
|
602 } |
|
603 } |
|
604 if (offset < 0) { |
|
605 THROW_0(vmSymbols::java_lang_InternalError()); |
|
606 } |
|
607 return field_offset_from_byte_offset(offset); |
|
608 } |
|
609 |
|
610 static jlong find_field_offset(jobject field, int must_be_static, TRAPS) { |
587 assert(field != NULL, "field must not be NULL"); |
611 assert(field != NULL, "field must not be NULL"); |
588 |
612 |
589 oop reflected = JNIHandles::resolve_non_null(field); |
613 oop reflected = JNIHandles::resolve_non_null(field); |
590 oop mirror = java_lang_reflect_Field::clazz(reflected); |
614 oop mirror = java_lang_reflect_Field::clazz(reflected); |
591 Klass* k = java_lang_Class::as_Klass(mirror); |
615 Klass* k = java_lang_Class::as_Klass(mirror); |
603 return field_offset_from_byte_offset(offset); |
627 return field_offset_from_byte_offset(offset); |
604 } |
628 } |
605 |
629 |
606 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) { |
630 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) { |
607 return find_field_offset(field, 0, THREAD); |
631 return find_field_offset(field, 0, THREAD); |
|
632 } UNSAFE_END |
|
633 |
|
634 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset1(JNIEnv *env, jobject unsafe, jclass c, jstring name)) { |
|
635 return find_field_offset(c, name, THREAD); |
608 } UNSAFE_END |
636 } UNSAFE_END |
609 |
637 |
610 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) { |
638 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) { |
611 return find_field_offset(field, 1, THREAD); |
639 return find_field_offset(field, 1, THREAD); |
612 } UNSAFE_END |
640 } UNSAFE_END |
710 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0); |
738 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0); |
711 } UNSAFE_END |
739 } UNSAFE_END |
712 |
740 |
713 |
741 |
714 static inline void throw_new(JNIEnv *env, const char *ename) { |
742 static inline void throw_new(JNIEnv *env, const char *ename) { |
715 char buf[100]; |
743 jclass cls = env->FindClass(ename); |
716 |
|
717 jio_snprintf(buf, 100, "%s%s", "java/lang/", ename); |
|
718 |
|
719 jclass cls = env->FindClass(buf); |
|
720 if (env->ExceptionCheck()) { |
744 if (env->ExceptionCheck()) { |
721 env->ExceptionClear(); |
745 env->ExceptionClear(); |
722 tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf); |
746 tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", ename); |
723 return; |
747 return; |
724 } |
748 } |
725 |
749 |
726 env->ThrowNew(cls, NULL); |
750 env->ThrowNew(cls, NULL); |
727 } |
751 } |
741 ClassLoader::unsafe_defineClassCallCounter()->inc(); |
765 ClassLoader::unsafe_defineClassCallCounter()->inc(); |
742 } |
766 } |
743 |
767 |
744 body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal); |
768 body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal); |
745 if (body == NULL) { |
769 if (body == NULL) { |
746 throw_new(env, "OutOfMemoryError"); |
770 throw_new(env, "java/lang/OutOfMemoryError"); |
747 return 0; |
771 return 0; |
748 } |
772 } |
749 |
773 |
750 env->GetByteArrayRegion(data, offset, length, body); |
774 env->GetByteArrayRegion(data, offset, length, body); |
751 if (env->ExceptionOccurred()) { |
775 if (env->ExceptionOccurred()) { |
757 int unicode_len = env->GetStringLength(name); |
781 int unicode_len = env->GetStringLength(name); |
758 |
782 |
759 if (len >= sizeof(buf)) { |
783 if (len >= sizeof(buf)) { |
760 utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); |
784 utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); |
761 if (utfName == NULL) { |
785 if (utfName == NULL) { |
762 throw_new(env, "OutOfMemoryError"); |
786 throw_new(env, "java/lang/OutOfMemoryError"); |
763 goto free_body; |
787 goto free_body; |
764 } |
788 } |
765 } else { |
789 } else { |
766 utfName = buf; |
790 utfName = buf; |
767 } |
791 } |
1180 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)}, |
1204 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)}, |
1181 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)}, |
1205 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)}, |
1182 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)}, |
1206 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)}, |
1183 |
1207 |
1184 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)}, |
1208 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)}, |
|
1209 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)}, |
1185 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)}, |
1210 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)}, |
1186 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)}, |
1211 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)}, |
1187 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)}, |
1212 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)}, |
1188 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)}, |
1213 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)}, |
1189 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)}, |
1214 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)}, |