10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classFileStream.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "memory/allocation.inline.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "oops/objArrayOop.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "prims/jni.h"
33 #include "prims/jvm.h"
34 #include "prims/unsafe.hpp"
35 #include "runtime/atomic.hpp"
36 #include "runtime/globals.hpp"
37 #include "runtime/interfaceSupport.hpp"
38 #include "runtime/orderAccess.inline.hpp"
39 #include "runtime/reflection.hpp"
40 #include "runtime/vm_version.hpp"
41 #include "services/threadService.hpp"
42 #include "trace/tracing.hpp"
43 #include "utilities/copy.hpp"
44 #include "utilities/dtrace.hpp"
45 #include "utilities/macros.hpp"
46 #if INCLUDE_ALL_GCS
47 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
48 #endif // INCLUDE_ALL_GCS
49
566 oop dstp = JNIHandles::resolve(dstObj);
567
568 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
569 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
570
571 Copy::conjoint_swap(src, dst, sz, esz);
572 } JVM_END
573 }
574 } UNSAFE_END
575
576 ////// Random queries
577
578 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
579 return sizeof(void*);
580 } UNSAFE_END
581
582 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
583 return os::vm_page_size();
584 } UNSAFE_END
585
586 static jint find_field_offset(jobject field, int must_be_static, TRAPS) {
587 assert(field != NULL, "field must not be NULL");
588
589 oop reflected = JNIHandles::resolve_non_null(field);
590 oop mirror = java_lang_reflect_Field::clazz(reflected);
591 Klass* k = java_lang_Class::as_Klass(mirror);
592 int slot = java_lang_reflect_Field::slot(reflected);
593 int modifiers = java_lang_reflect_Field::modifiers(reflected);
594
595 if (must_be_static >= 0) {
596 int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
597 if (must_be_static != really_is_static) {
598 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
599 }
600 }
601
602 int offset = InstanceKlass::cast(k)->field_offset(slot);
603 return field_offset_from_byte_offset(offset);
604 }
605
606 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
607 return find_field_offset(field, 0, THREAD);
608 } UNSAFE_END
609
610 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
611 return find_field_offset(field, 1, THREAD);
612 } UNSAFE_END
613
614 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBase0(JNIEnv *env, jobject unsafe, jobject field)) {
615 assert(field != NULL, "field must not be NULL");
616
617 // Note: In this VM implementation, a field address is always a short
618 // offset from the base of a a klass metaobject. Thus, the full dynamic
619 // range of the return type is never used. However, some implementations
620 // might put the static field inside an array shared by many classes,
621 // or even at a fixed address, in which case the address could be quite
622 // large. In that last case, this function would return NULL, since
623 // the address would operate alone, without any base pointer.
624
625 oop reflected = JNIHandles::resolve_non_null(field);
626 oop mirror = java_lang_reflect_Field::clazz(reflected);
627 int modifiers = java_lang_reflect_Field::modifiers(reflected);
628
629 if ((modifiers & JVM_ACC_STATIC) == 0) {
695
696 // This VM packs both fields and array elements down to the byte.
697 // But watch out: If this changes, so that array references for
698 // a given primitive type (say, T_BOOLEAN) use different memory units
699 // than fields, this method MUST return zero for such arrays.
700 // For example, the VM used to store sub-word sized fields in full
701 // words in the object layout, so that accessors like getByte(Object,int)
702 // did not really do what one might expect for arrays. Therefore,
703 // this function used to report a zero scale factor, so that the user
704 // would know not to attempt to access sub-word array elements.
705 // // Code for unpacked fields:
706 // if (scale < wordSize) return 0;
707
708 // The following allows for a pretty general fieldOffset cookie scheme,
709 // but requires it to be linear in byte offset.
710 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0);
711 } UNSAFE_END
712
713
714 static inline void throw_new(JNIEnv *env, const char *ename) {
715 char buf[100];
716
717 jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
718
719 jclass cls = env->FindClass(buf);
720 if (env->ExceptionCheck()) {
721 env->ExceptionClear();
722 tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf);
723 return;
724 }
725
726 env->ThrowNew(cls, NULL);
727 }
728
729 static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
730 // Code lifted from JDK 1.3 ClassLoader.c
731
732 jbyte *body;
733 char *utfName = NULL;
734 jclass result = 0;
735 char buf[128];
736
737 assert(data != NULL, "Class bytes must not be NULL");
738 assert(length >= 0, "length must not be negative: %d", length);
739
740 if (UsePerfData) {
741 ClassLoader::unsafe_defineClassCallCounter()->inc();
742 }
743
744 body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal);
745 if (body == NULL) {
746 throw_new(env, "OutOfMemoryError");
747 return 0;
748 }
749
750 env->GetByteArrayRegion(data, offset, length, body);
751 if (env->ExceptionOccurred()) {
752 goto free_body;
753 }
754
755 if (name != NULL) {
756 uint len = env->GetStringUTFLength(name);
757 int unicode_len = env->GetStringLength(name);
758
759 if (len >= sizeof(buf)) {
760 utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
761 if (utfName == NULL) {
762 throw_new(env, "OutOfMemoryError");
763 goto free_body;
764 }
765 } else {
766 utfName = buf;
767 }
768
769 env->GetStringUTFRegion(name, 0, unicode_len, utfName);
770
771 for (uint i = 0; i < len; i++) {
772 if (utfName[i] == '.') utfName[i] = '/';
773 }
774 }
775
776 result = JVM_DefineClass(env, utfName, loader, body, length, pd);
777
778 if (utfName && utfName != buf) {
779 FREE_C_HEAP_ARRAY(char, utfName);
780 }
781
782 free_body:
1165 {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObject)},
1166 {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObjectVolatile)},
1167 {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObjectVolatile)},
1168
1169 {CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
1170
1171 DECLARE_GETPUTOOP(Boolean, Z),
1172 DECLARE_GETPUTOOP(Byte, B),
1173 DECLARE_GETPUTOOP(Short, S),
1174 DECLARE_GETPUTOOP(Char, C),
1175 DECLARE_GETPUTOOP(Int, I),
1176 DECLARE_GETPUTOOP(Long, J),
1177 DECLARE_GETPUTOOP(Float, F),
1178 DECLARE_GETPUTOOP(Double, D),
1179
1180 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1181 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1182 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1183
1184 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1185 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1186 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1187 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1188 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1189 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1190 {CC "addressSize0", CC "()I", FN_PTR(Unsafe_AddressSize0)},
1191 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
1192
1193 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1194 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1195 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1196 {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1197 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1198 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1199 {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1200 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1201 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1202
1203 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1204 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classFileStream.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "memory/allocation.inline.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "oops/fieldStreams.hpp"
31 #include "oops/objArrayOop.inline.hpp"
32 #include "oops/oop.inline.hpp"
33 #include "prims/jni.h"
34 #include "prims/jvm.h"
35 #include "prims/unsafe.hpp"
36 #include "runtime/atomic.hpp"
37 #include "runtime/globals.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/orderAccess.inline.hpp"
40 #include "runtime/reflection.hpp"
41 #include "runtime/vm_version.hpp"
42 #include "services/threadService.hpp"
43 #include "trace/tracing.hpp"
44 #include "utilities/copy.hpp"
45 #include "utilities/dtrace.hpp"
46 #include "utilities/macros.hpp"
47 #if INCLUDE_ALL_GCS
48 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
49 #endif // INCLUDE_ALL_GCS
50
567 oop dstp = JNIHandles::resolve(dstObj);
568
569 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
570 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
571
572 Copy::conjoint_swap(src, dst, sz, esz);
573 } JVM_END
574 }
575 } UNSAFE_END
576
577 ////// Random queries
578
579 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
580 return sizeof(void*);
581 } UNSAFE_END
582
583 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
584 return os::vm_page_size();
585 } UNSAFE_END
586
587 static jint 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 jint find_field_offset(jobject field, int must_be_static, TRAPS) {
611 assert(field != NULL, "field must not be NULL");
612
613 oop reflected = JNIHandles::resolve_non_null(field);
614 oop mirror = java_lang_reflect_Field::clazz(reflected);
615 Klass* k = java_lang_Class::as_Klass(mirror);
616 int slot = java_lang_reflect_Field::slot(reflected);
617 int modifiers = java_lang_reflect_Field::modifiers(reflected);
618
619 if (must_be_static >= 0) {
620 int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
621 if (must_be_static != really_is_static) {
622 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
623 }
624 }
625
626 int offset = InstanceKlass::cast(k)->field_offset(slot);
627 return field_offset_from_byte_offset(offset);
628 }
629
630 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
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);
636 } UNSAFE_END
637
638 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
639 return find_field_offset(field, 1, THREAD);
640 } UNSAFE_END
641
642 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBase0(JNIEnv *env, jobject unsafe, jobject field)) {
643 assert(field != NULL, "field must not be NULL");
644
645 // Note: In this VM implementation, a field address is always a short
646 // offset from the base of a a klass metaobject. Thus, the full dynamic
647 // range of the return type is never used. However, some implementations
648 // might put the static field inside an array shared by many classes,
649 // or even at a fixed address, in which case the address could be quite
650 // large. In that last case, this function would return NULL, since
651 // the address would operate alone, without any base pointer.
652
653 oop reflected = JNIHandles::resolve_non_null(field);
654 oop mirror = java_lang_reflect_Field::clazz(reflected);
655 int modifiers = java_lang_reflect_Field::modifiers(reflected);
656
657 if ((modifiers & JVM_ACC_STATIC) == 0) {
723
724 // This VM packs both fields and array elements down to the byte.
725 // But watch out: If this changes, so that array references for
726 // a given primitive type (say, T_BOOLEAN) use different memory units
727 // than fields, this method MUST return zero for such arrays.
728 // For example, the VM used to store sub-word sized fields in full
729 // words in the object layout, so that accessors like getByte(Object,int)
730 // did not really do what one might expect for arrays. Therefore,
731 // this function used to report a zero scale factor, so that the user
732 // would know not to attempt to access sub-word array elements.
733 // // Code for unpacked fields:
734 // if (scale < wordSize) return 0;
735
736 // The following allows for a pretty general fieldOffset cookie scheme,
737 // but requires it to be linear in byte offset.
738 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0);
739 } UNSAFE_END
740
741
742 static inline void throw_new(JNIEnv *env, const char *ename) {
743 jclass cls = env->FindClass(ename);
744 if (env->ExceptionCheck()) {
745 env->ExceptionClear();
746 tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", ename);
747 return;
748 }
749
750 env->ThrowNew(cls, NULL);
751 }
752
753 static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
754 // Code lifted from JDK 1.3 ClassLoader.c
755
756 jbyte *body;
757 char *utfName = NULL;
758 jclass result = 0;
759 char buf[128];
760
761 assert(data != NULL, "Class bytes must not be NULL");
762 assert(length >= 0, "length must not be negative: %d", length);
763
764 if (UsePerfData) {
765 ClassLoader::unsafe_defineClassCallCounter()->inc();
766 }
767
768 body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal);
769 if (body == NULL) {
770 throw_new(env, "java/lang/OutOfMemoryError");
771 return 0;
772 }
773
774 env->GetByteArrayRegion(data, offset, length, body);
775 if (env->ExceptionOccurred()) {
776 goto free_body;
777 }
778
779 if (name != NULL) {
780 uint len = env->GetStringUTFLength(name);
781 int unicode_len = env->GetStringLength(name);
782
783 if (len >= sizeof(buf)) {
784 utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
785 if (utfName == NULL) {
786 throw_new(env, "java/lang/OutOfMemoryError");
787 goto free_body;
788 }
789 } else {
790 utfName = buf;
791 }
792
793 env->GetStringUTFRegion(name, 0, unicode_len, utfName);
794
795 for (uint i = 0; i < len; i++) {
796 if (utfName[i] == '.') utfName[i] = '/';
797 }
798 }
799
800 result = JVM_DefineClass(env, utfName, loader, body, length, pd);
801
802 if (utfName && utfName != buf) {
803 FREE_C_HEAP_ARRAY(char, utfName);
804 }
805
806 free_body:
1189 {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObject)},
1190 {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObjectVolatile)},
1191 {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObjectVolatile)},
1192
1193 {CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
1194
1195 DECLARE_GETPUTOOP(Boolean, Z),
1196 DECLARE_GETPUTOOP(Byte, B),
1197 DECLARE_GETPUTOOP(Short, S),
1198 DECLARE_GETPUTOOP(Char, C),
1199 DECLARE_GETPUTOOP(Int, I),
1200 DECLARE_GETPUTOOP(Long, J),
1201 DECLARE_GETPUTOOP(Float, F),
1202 DECLARE_GETPUTOOP(Double, D),
1203
1204 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1205 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1206 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1207
1208 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1209 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1210 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1211 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1212 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1213 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1214 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1215 {CC "addressSize0", CC "()I", FN_PTR(Unsafe_AddressSize0)},
1216 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
1217
1218 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1219 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1220 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1221 {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1222 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1223 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1224 {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1225 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1226 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1227
1228 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1229 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
|