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
558 address dst = (address)dstOffset;
559
560 Copy::conjoint_swap(src, dst, sz, esz);
561 } else {
562 // At least one of src/dst are on heap, transition to VM to access raw pointers
563
564 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
565 oop srcp = JNIHandles::resolve(srcObj);
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) {
693 int base = 0, scale = 0;
694 getBaseAndScale(base, scale, clazz, CHECK_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 }
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
559 address dst = (address)dstOffset;
560
561 Copy::conjoint_swap(src, dst, sz, esz);
562 } else {
563 // At least one of src/dst are on heap, transition to VM to access raw pointers
564
565 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
566 oop srcp = JNIHandles::resolve(srcObj);
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 static inline void throw_new(JNIEnv *env, const char *ename) {
580 char buf[100];
581
582 jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
583
584 jclass cls = env->FindClass(buf);
585 if (env->ExceptionCheck()) {
586 env->ExceptionClear();
587 tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf);
588 return;
589 }
590
591 env->ThrowNew(cls, NULL);
592 }
593
594 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
595 return sizeof(void*);
596 } UNSAFE_END
597
598 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
599 return os::vm_page_size();
600 } UNSAFE_END
601
602 static jint find_field_offset(JNIEnv *env, jclass clazz, jstring name, TRAPS) {
603 assert(clazz != NULL, "clazz must not be NULL");
604 assert(name != NULL, "name must not be NULL");
605
606 ResourceMark rm(THREAD);
607 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
608
609 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
610
611 jint offset = -1;
612 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
613 Symbol *name = fs.name();
614 if (name->equals(utf_name)) {
615 offset = fs.offset();
616 break;
617 }
618 }
619 if (offset < 0) {
620 throw_new(env, "InternalError");
621 }
622 return field_offset_from_byte_offset(offset);
623 }
624
625 static jint find_field_offset(jobject field, int must_be_static, TRAPS) {
626 assert(field != NULL, "field must not be NULL");
627
628 oop reflected = JNIHandles::resolve_non_null(field);
629 oop mirror = java_lang_reflect_Field::clazz(reflected);
630 Klass* k = java_lang_Class::as_Klass(mirror);
631 int slot = java_lang_reflect_Field::slot(reflected);
632 int modifiers = java_lang_reflect_Field::modifiers(reflected);
633
634 if (must_be_static >= 0) {
635 int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
636 if (must_be_static != really_is_static) {
637 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
638 }
639 }
640
641 int offset = InstanceKlass::cast(k)->field_offset(slot);
642 return field_offset_from_byte_offset(offset);
643 }
644
645 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
646 return find_field_offset(field, 0, THREAD);
647 } UNSAFE_END
648
649 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset1(JNIEnv *env, jobject unsafe, jclass c, jstring name)) {
650 return find_field_offset(env, c, name, THREAD);
651 } UNSAFE_END
652
653 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
654 return find_field_offset(field, 1, THREAD);
655 } UNSAFE_END
656
657 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBase0(JNIEnv *env, jobject unsafe, jobject field)) {
658 assert(field != NULL, "field must not be NULL");
659
660 // Note: In this VM implementation, a field address is always a short
661 // offset from the base of a a klass metaobject. Thus, the full dynamic
662 // range of the return type is never used. However, some implementations
663 // might put the static field inside an array shared by many classes,
664 // or even at a fixed address, in which case the address could be quite
665 // large. In that last case, this function would return NULL, since
666 // the address would operate alone, without any base pointer.
667
668 oop reflected = JNIHandles::resolve_non_null(field);
669 oop mirror = java_lang_reflect_Field::clazz(reflected);
670 int modifiers = java_lang_reflect_Field::modifiers(reflected);
671
672 if ((modifiers & JVM_ACC_STATIC) == 0) {
736 int base = 0, scale = 0;
737 getBaseAndScale(base, scale, clazz, CHECK_0);
738
739 // This VM packs both fields and array elements down to the byte.
740 // But watch out: If this changes, so that array references for
741 // a given primitive type (say, T_BOOLEAN) use different memory units
742 // than fields, this method MUST return zero for such arrays.
743 // For example, the VM used to store sub-word sized fields in full
744 // words in the object layout, so that accessors like getByte(Object,int)
745 // did not really do what one might expect for arrays. Therefore,
746 // this function used to report a zero scale factor, so that the user
747 // would know not to attempt to access sub-word array elements.
748 // // Code for unpacked fields:
749 // if (scale < wordSize) return 0;
750
751 // The following allows for a pretty general fieldOffset cookie scheme,
752 // but requires it to be linear in byte offset.
753 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0);
754 } UNSAFE_END
755
756 static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
757 // Code lifted from JDK 1.3 ClassLoader.c
758
759 jbyte *body;
760 char *utfName = NULL;
761 jclass result = 0;
762 char buf[128];
763
764 assert(data != NULL, "Class bytes must not be NULL");
765 assert(length >= 0, "length must not be negative: %d", length);
766
767 if (UsePerfData) {
768 ClassLoader::unsafe_defineClassCallCounter()->inc();
769 }
770
771 body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal);
772 if (body == NULL) {
773 throw_new(env, "OutOfMemoryError");
774 return 0;
775 }
1192 {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObject)},
1193 {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObjectVolatile)},
1194 {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObjectVolatile)},
1195
1196 {CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
1197
1198 DECLARE_GETPUTOOP(Boolean, Z),
1199 DECLARE_GETPUTOOP(Byte, B),
1200 DECLARE_GETPUTOOP(Short, S),
1201 DECLARE_GETPUTOOP(Char, C),
1202 DECLARE_GETPUTOOP(Int, I),
1203 DECLARE_GETPUTOOP(Long, J),
1204 DECLARE_GETPUTOOP(Float, F),
1205 DECLARE_GETPUTOOP(Double, D),
1206
1207 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1208 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1209 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1210
1211 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1212 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1213 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1214 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1215 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1216 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1217 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1218 {CC "addressSize0", CC "()I", FN_PTR(Unsafe_AddressSize0)},
1219 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
1220
1221 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1222 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1223 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1224 {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1225 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1226 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1227 {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1228 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1229 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1230
1231 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1232 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
|