Кто-нибудь может интерпретировать этот код C ++ (из OpenJDK6) в простой английский? - PullRequest
4 голосов
/ 24 августа 2011

Вот фрагмент кода из OpenJDK6 hotspot/src/share/vm/prims/unsafe.cpp (начиная со строки 1082):

// JSR166 ------------------------------------------------------------------

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
  UnsafeWrapper("Unsafe_CompareAndSwapObject");
  oop x = JNIHandles::resolve(x_h);
  oop e = JNIHandles::resolve(e_h);
  oop p = JNIHandles::resolve(obj);
  HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
  if (UseCompressedOops) {
    update_barrier_set_pre((narrowOop*)addr, e);
  } else {
    update_barrier_set_pre((oop*)addr, e);
  }
  oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e);
  jboolean success  = (res == e);
  if (success)
    update_barrier_set((void*)addr, x);
  return success;
UNSAFE_END

Добавлен также ключевой метод oopDesc ​​:: atomic_compare_exchange_oop .

 inline oop oopDesc::atomic_compare_exchange_oop(oop exchange_value,
                                                    volatile HeapWord *dest,
                                                    oop compare_value) {
      if (UseCompressedOops) {
        // encode exchange and compare value from oop to T
        narrowOop val = encode_heap_oop(exchange_value);
        narrowOop cmp = encode_heap_oop(compare_value);

        narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp);
        // decode old from T to oop
        return decode_heap_oop(old);
      } else {
        return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value);
      }
    }

Какова цель этого кода в контексте JVM? Я не опытный в C ++.

Atomic :: cmpxchg & Atomic :: cmpxchg_ptr становится зависимой от ОС и ЦП и зависит от 32-битной и 64-битной систем. Таким образом, JVM разделены здесь.

EDIT

Как указал steve-O, CAS имеет свою слабость как проблему ABA, поэтому здесь необходим барьер памяти, чтобы гарантировать, что CAS все еще корректен в многопоточной среде. Кроме того, поскольку CAS потребуется три параметра: адрес, старое значение и новое значение, для этого требуется современный ЦП.

EDIT

С новым C ++ 0x стандартом (формально не опубликовано сейчас?), Значит ли это, что JVM не нужно тогда расщеплять? По крайней мере, на уровне исходного кода. Бинарный файл все еще может быть разделен, но он будет обрабатываться компилятором C ++.

Ответы [ 2 ]

5 голосов
/ 24 августа 2011

Это оболочка JNI для CAS API с барьерами памяти для Архитектура IA64 .

edit: для описания CAS:

Сравнить dest с сравнить значение и, если они совпадают, присвоить значение обмена для dest .

Это атомарная операция , что означает, что никакой другой процессор не может изменить значение dest во время выполнения операции.

Типичные проблемыкоторые могут произойти без атомарных операций, перечислены здесь, «проблема ABA»

http://en.wikipedia.org/wiki/ABA_problem

Зачем вам использовать функцию CAS?

Простой пример - счетчик, если у вас есть несколько потоков, увеличивающих счетчик, подумайте, что делает процесс увеличения:

int i;
read the value of i
add one to the current value
save the value back to i.

Что происходит, когда другой процессор читает значение i и сохраняет i + 1 до завершения работы этого процессора?

В итоге вы получите i + 1 вместо i + 2 .

1 голос
/ 25 августа 2011

Вот некоторые интерпретации о

  • Что такое упс, и почему они должны быть сжаты?


«Упс» или «обычный указатель объекта» на языке HotSpot - это управляемый указатель на объект. Обычно он имеет тот же размер, что и собственный указатель компьютера, что означает 64 бита в системе LP64. В системе ILP32 максимальный размер кучи составляет несколько менее 4 ГБ, что недостаточно для многих приложений.

  • Какие упс сжимаются?

В JVM в режиме ILP32 или если флаг UseCompressedOops отключен в режиме LP64, все значения oops имеют размер машинного слова.

Если значение UseCompressedOops равно true, следующие кучи в куче будут сжаты:

• поле klass каждого объекта • каждое поле экземпляра • каждый элемент массива oop (objArray)

Подробнее смотрите в этой sun wiki

...