Why does not SetByteArrayRegion corrupt memory?

Some Name :

The SetByteArrayRegion function is implemented as

JNI_ENTRY(void, \
jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
             jsize len, const ElementType *buf)) \
  JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
  DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\
  DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
  typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
  } else { \
    if (len > 0) { \
      int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
      memcpy((u_char*) dst->Tag##_at_addr(start), \
             (u_char*) buf, \
             len << sc);    \
    } \
  } \
JNI_END

As can be observed it calls memcpy on a native pointer to the java heap array: dst->Tag##_at_addr(start). memcpy itself is not atomic so I concluded that nothing stops GC from moving the array in the middle of memcpy call.

Moreover the array can be moved somwhere right after the dst->Tag##_at_addr(start) again causing memory corruption.

By contract, "critical" methods employ the GC_locker::lock_critical(thread);.

So why are SetArrayRegion methods safe? What did I miss?

apangin :

As you can see, the function is wrapped in JNI_ENTRY macro, which in turn performs ThreadInVMfromNative state transition. This means, a Java thread executing SetByteArrayRegion is guaranteed to be in _thread_in_vm state.

Non-concurrent compacting collectors can move objects only at the global safepoint. A safepoint implies that all Java thread are either blocked or running native code (_thread_in_native state).

So, if a safepoint is requested while SetByteArrayRegion is running, JVM will wait until all threads complete current VM operation. Сontrariwise, if SetByteArrayRegion is executed while GC is running, the thread will block at state transition until GC completes.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=128815&siteId=1