Can anyone interpret this C ++ code (from OpenJDK6) to plain English?

Here is a snippet of code from OpenJDK6 hotspot/src/share/vm/prims/unsafe.cpp (starting at line 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 

The key method oopDesc ​​:: atomic_compare_exchange_oop is also added.

  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); } } 

What is the purpose of this code in the context of the JVM? I am not familiar with C ++.

Atomic :: cmpxchg and Atomic :: cmpxchg_ptr become OS and CPU dependent and 32 bit / 64 bit. So, the JVMs are split here.

EDIT

As Steve-O noted, CAS has its weakness as an ABA problem, so a memory barrier is needed here to ensure that CAS is still valid in a multi-threaded environment. In addition, CAS will require three parameters: address, old value, and new value, so a modern processor is required for this process.

EDIT

With the new C ++ 0x standard (not officially published now?), Does this mean that the JVM does not need to be split then? At least at the source code level. The binary file can be split, but it will be processed by the C ++ compiler.

+4
source share
2 answers

This is the JNI wrapper for the CAS API with memory barriers for the IA64 architecture .

edit: to describe CAS:

Compare dest with the comparison value, and if they match the purpose of the exchange value for dest.

This is an atomic operation which means that no other processor can change the dest value during the operation.

Here are typical problems that can occur without atomic operations, "ABA problem"

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

Why are you using the CAS function?

A simple example is a counter, if you have several threads increasing the counter, consider what the increment process does:

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

What happens when another processor reads i and saves i + 1 until this processor completes?

As a result, you get i + 1 instead of i + 2.

+5
source

Here are some explanations about

  • What is oop, and why should they be compressed?


"oop" or "regular object pointer" in HotSpot is a managed pointer to an object. It usually has the same size as the native machine pointer, which means 64 bits on an LP64 system. On an ILP32 system, the maximum heap size is slightly less than 4 GB, which is not enough for many applications.

  • What compression are compressed?

In the JVM in ILP32 mode, or if the UseCompressedOops flag is disabled in LP64 mode, all oops is the native size of the machine word.

If UseCompressedOops is true, the following heap compressions will be compressed:

• klass field of each object • each field of the oop instance • each element of the oop array (objArray)

See the sun wiki for more information.

+1
source

All Articles