41 #include "runtime/vm_version.hpp" 42 #include "services/threadService.hpp" 43 #include "trace/tracing.hpp" 44 #include "utilities/align.hpp" 45 #include "utilities/copy.hpp" 46 #include "utilities/dtrace.hpp" 47 #include "utilities/macros.hpp" 48 #if INCLUDE_ALL_GCS 49 #include "gc/g1/g1SATBCardTableModRefBS.hpp" 50 #endif // INCLUDE_ALL_GCS 51 52 /** 53 * Implementation of the jdk.internal.misc.Unsafe class 54 */ 55 56 57 #define MAX_OBJECT_SIZE \ 58 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \ 59 + ((julong)max_jint * sizeof(double)) ) 60 61 62 #define UNSAFE_ENTRY(result_type, header) \ 63 JVM_ENTRY(static result_type, header) 64 65 #define UNSAFE_LEAF(result_type, header) \ 66 JVM_LEAF(static result_type, header) 67 68 #define UNSAFE_END JVM_END 69 70 71 static inline void* addr_from_java(jlong addr) { 72 // This assert fails in a variety of ways on 32-bit systems. 73 // It is impossible to predict whether native code that converts 74 // pointers to longs will sign-extend or zero-extend the addresses. 75 //assert(addr == (uintptr_t)addr, "must not be odd high bits"); 76 return (void*)(uintptr_t)addr; 77 } 78 79 static inline jlong addr_to_java(void* p) { 80 assert(p == (void*)(uintptr_t)p, "must not be odd high bits"); 81 return (uintptr_t)p; 82 } 83 84 85 // Note: The VM's obj_field and related accessors use byte-scaled 86 // ("unscaled") offsets, just as the unsafe methods do. 87 88 // However, the method Unsafe.fieldOffset explicitly declines to 89 // guarantee this. The field offset values manipulated by the Java user 508 509 return addr_to_java(x); 510 } UNSAFE_END 511 512 UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory0(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) { 513 void* p = addr_from_java(addr); 514 size_t sz = (size_t)size; 515 sz = align_up(sz, HeapWordSize); 516 517 void* x = os::realloc(p, sz, mtInternal); 518 519 return addr_to_java(x); 520 } UNSAFE_END 521 522 UNSAFE_ENTRY(void, Unsafe_FreeMemory0(JNIEnv *env, jobject unsafe, jlong addr)) { 523 void* p = addr_from_java(addr); 524 525 os::free(p); 526 } UNSAFE_END 527 528 UNSAFE_ENTRY(void, Unsafe_SetMemory0(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) { 529 size_t sz = (size_t)size; 530 531 oop base = JNIHandles::resolve(obj); 532 void* p = index_oop_from_field_offset_long(base, offset); 533 534 Copy::fill_to_memory_atomic(p, sz, value); 535 } UNSAFE_END 536 537 UNSAFE_ENTRY(void, Unsafe_CopyMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) { 538 size_t sz = (size_t)size; 539 540 oop srcp = JNIHandles::resolve(srcObj); 541 oop dstp = JNIHandles::resolve(dstObj); 542 543 void* src = index_oop_from_field_offset_long(srcp, srcOffset); 544 void* dst = index_oop_from_field_offset_long(dstp, dstOffset); 545 546 Copy::conjoint_memory_atomic(src, dst, sz); 547 } UNSAFE_END 548 549 // This function is a leaf since if the source and destination are both in native memory 550 // the copy may potentially be very large, and we don't want to disable GC if we can avoid it. 551 // If either source or destination (or both) are on the heap, the function will enter VM using 552 // JVM_ENTRY_FROM_LEAF 553 UNSAFE_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size, jlong elemSize)) { 554 size_t sz = (size_t)size; 555 size_t esz = (size_t)elemSize; 556 557 if (srcObj == NULL && dstObj == NULL) { 558 // Both src & dst are in native memory 559 address src = (address)srcOffset; 560 address dst = (address)dstOffset; 561 562 Copy::conjoint_swap(src, dst, sz, esz); 563 } else { 564 // At least one of src/dst are on heap, transition to VM to access raw pointers 565 566 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) { 567 oop srcp = JNIHandles::resolve(srcObj); 568 oop dstp = JNIHandles::resolve(dstObj); 569 570 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset); 571 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset); 572 573 Copy::conjoint_swap(src, dst, sz, esz); 574 } JVM_END 575 } 576 } UNSAFE_END 577 578 ////// Random queries 579 580 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) { 581 return sizeof(void*); 582 } UNSAFE_END 583 584 UNSAFE_LEAF(jint, Unsafe_PageSize()) { 585 return os::vm_page_size(); 586 } UNSAFE_END 587 588 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) { 589 assert(clazz != NULL, "clazz must not be NULL"); 590 assert(name != NULL, "name must not be NULL"); 591 592 ResourceMark rm(THREAD); 593 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name)); 594 595 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); 596 | 41 #include "runtime/vm_version.hpp" 42 #include "services/threadService.hpp" 43 #include "trace/tracing.hpp" 44 #include "utilities/align.hpp" 45 #include "utilities/copy.hpp" 46 #include "utilities/dtrace.hpp" 47 #include "utilities/macros.hpp" 48 #if INCLUDE_ALL_GCS 49 #include "gc/g1/g1SATBCardTableModRefBS.hpp" 50 #endif // INCLUDE_ALL_GCS 51 52 /** 53 * Implementation of the jdk.internal.misc.Unsafe class 54 */ 55 56 57 #define MAX_OBJECT_SIZE \ 58 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \ 59 + ((julong)max_jint * sizeof(double)) ) 60 61 #define UNSAFE_ENTRY(result_type, header) \ 62 JVM_ENTRY(static result_type, header) 63 64 #define UNSAFE_ACCESS_ENTRY(result_type, header) \ 65 JVM_ENTRY(static result_type, header) \ 66 thread->set_doing_unsafe_access(true); 67 68 #define UNSAFE_LEAF(result_type, header) \ 69 JVM_LEAF(static result_type, header) 70 71 #define UNSAFE_ACCESS_LEAF(result_type, header) \ 72 JVM_LEAF(static result_type, header) \ 73 JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ 74 thread->set_doing_unsafe_access(true); 75 76 #define UNSAFE_ACCESS_END \ 77 thread->set_doing_unsafe_access(false); \ 78 JVM_END 79 80 #define UNSAFE_END JVM_END 81 82 static inline void* addr_from_java(jlong addr) { 83 // This assert fails in a variety of ways on 32-bit systems. 84 // It is impossible to predict whether native code that converts 85 // pointers to longs will sign-extend or zero-extend the addresses. 86 //assert(addr == (uintptr_t)addr, "must not be odd high bits"); 87 return (void*)(uintptr_t)addr; 88 } 89 90 static inline jlong addr_to_java(void* p) { 91 assert(p == (void*)(uintptr_t)p, "must not be odd high bits"); 92 return (uintptr_t)p; 93 } 94 95 96 // Note: The VM's obj_field and related accessors use byte-scaled 97 // ("unscaled") offsets, just as the unsafe methods do. 98 99 // However, the method Unsafe.fieldOffset explicitly declines to 100 // guarantee this. The field offset values manipulated by the Java user 519 520 return addr_to_java(x); 521 } UNSAFE_END 522 523 UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory0(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) { 524 void* p = addr_from_java(addr); 525 size_t sz = (size_t)size; 526 sz = align_up(sz, HeapWordSize); 527 528 void* x = os::realloc(p, sz, mtInternal); 529 530 return addr_to_java(x); 531 } UNSAFE_END 532 533 UNSAFE_ENTRY(void, Unsafe_FreeMemory0(JNIEnv *env, jobject unsafe, jlong addr)) { 534 void* p = addr_from_java(addr); 535 536 os::free(p); 537 } UNSAFE_END 538 539 UNSAFE_ACCESS_ENTRY(void, Unsafe_SetMemory0(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) { 540 size_t sz = (size_t)size; 541 542 oop base = JNIHandles::resolve(obj); 543 void* p = index_oop_from_field_offset_long(base, offset); 544 545 Copy::fill_to_memory_atomic(p, sz, value); 546 } UNSAFE_ACCESS_END 547 548 UNSAFE_ACCESS_ENTRY(void, Unsafe_CopyMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) { 549 size_t sz = (size_t)size; 550 551 oop srcp = JNIHandles::resolve(srcObj); 552 oop dstp = JNIHandles::resolve(dstObj); 553 554 void* src = index_oop_from_field_offset_long(srcp, srcOffset); 555 void* dst = index_oop_from_field_offset_long(dstp, dstOffset); 556 557 Copy::conjoint_memory_atomic(src, dst, sz); 558 } UNSAFE_ACCESS_END 559 560 // This function is a leaf since if the source and destination are both in native memory 561 // the copy may potentially be very large, and we don't want to disable GC if we can avoid it. 562 // If either source or destination (or both) are on the heap, the function will enter VM using 563 // JVM_ENTRY_FROM_LEAF 564 UNSAFE_ACCESS_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size, jlong elemSize)) { 565 size_t sz = (size_t)size; 566 size_t esz = (size_t)elemSize; 567 568 if (srcObj == NULL && dstObj == NULL) { 569 // Both src & dst are in native memory 570 address src = (address)srcOffset; 571 address dst = (address)dstOffset; 572 573 Copy::conjoint_swap(src, dst, sz, esz); 574 } else { 575 // At least one of src/dst are on heap, transition to VM to access raw pointers 576 577 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) { 578 oop srcp = JNIHandles::resolve(srcObj); 579 oop dstp = JNIHandles::resolve(dstObj); 580 581 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset); 582 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset); 583 584 Copy::conjoint_swap(src, dst, sz, esz); 585 } JVM_END 586 } 587 } UNSAFE_ACCESS_END 588 589 ////// Random queries 590 591 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) { 592 return sizeof(void*); 593 } UNSAFE_END 594 595 UNSAFE_LEAF(jint, Unsafe_PageSize()) { 596 return os::vm_page_size(); 597 } UNSAFE_END 598 599 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) { 600 assert(clazz != NULL, "clazz must not be NULL"); 601 assert(name != NULL, "name must not be NULL"); 602 603 ResourceMark rm(THREAD); 604 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name)); 605 606 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); 607 |