После вопроса, связанного с тем, как 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), копируя их один за другим один (кажется).Может кто-нибудь объяснить, почему копирование выполняется даже на нативном уровне путем перебора элементов массива?