Реализация System.arraycopy в OpenJDK

После вопроса, связанного с тем, как JVM реализует создание строк на основе char[], я упомянул, что итерации не происходит, когда char[] копируется внутрь новой строки, поскольку в конечном итоге вызывается System.arraycopy, который копирует нужную память с помощью такой функции, как memcpy, на собственном, зависящем от реализации уровне (исходный вопрос).

Я хотел проверить это сам, поэтому скачал исходный код Openjdk 7 и начал его просматривать. Я нашел реализацию System.arraycopy в исходном коде OpenJDK C++, в openjdx/hotspot/src/share/vm/oops/objArrayKlass.cpp:

if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) {
  // elements are guaranteed to be subtypes, so no check necessary
  bs->write_ref_array_pre(dst, length);
  Copy::conjoint_oops_atomic(src, dst, length);
} else {
  // slow case: need individual subtype checks

Если элементы не требуют проверки типа (это случае, например, массивов примитивных типов данных), вызывается Copy::conjoin_oops_atomic.

Функция Copy::conjoint_oops_atomicнаходится в 'copy.hpp':

// overloaded for UseCompressedOops
static void conjoint_oops_atomic(narrowOop* from, narrowOop* to, size_t count) {
  assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong");
  assert_params_ok(from, to, LogBytesPerInt);
  pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
}

Теперь мы зависим от платформы, так как операция копирования реализуется по-разному в зависимости от ОС/архитектуры. Я пойду с Windows в качестве примера. openjdk\hotspot\src\os_cpu\windows_x86\vm\copy_windows_x86.inline.hpp:

static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
// Do better than this: inline memmove body  NEEDS CLEANUP
if (from > to) {
  while (count-- > 0) {
    // Copy forwards
    *to++ = *from++;
  }
} else {
  from += count - 1;
  to   += count - 1;
  while (count-- > 0) {
    // Copy backwards
    *to-- = *from--;
  }
 }
}

И... к моему удивлению, он перебирает элементы (значения oop), копируя их один за другим один (кажется).Может кто-нибудь объяснить, почему копирование выполняется даже на нативном уровне путем перебора элементов массива?

9
задан Community 23 May 2017 в 02:08
поделиться