This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# {method} 'poll' '()Ljava/lang/Object;' in 'io/jaq/spsc/FFBuffer' BEFORE | |
# [sp+0x20] (sp of caller) | |
0x00007facb1060c80: mov r10d,DWORD PTR [rsi+0x8] | |
0x00007facb1060c84: cmp rax,r10 | |
0x00007facb1060c87: jne 0x00007facb1037960 ; {runtime_call} | |
0x00007facb1060c8d: xchg ax,ax | |
[Verified Entry Point] | |
0x00007facb1060c90: sub rsp,0x18 | |
0x00007facb1060c97: mov QWORD PTR [rsp+0x10],rbp ;*synchronization entry | |
; - io.jaq.spsc.FFBuffer::poll@-1 (line 133) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public E poll() { | |
final long offset = offset(head); | |
final E[] lb = buffer; | |
@SuppressWarnings("unchecked") | |
final E e = (E) UnsafeAccess.UNSAFE.getObjectVolatile(lb, offset); | |
if (null == e) { | |
return null; | |
} | |
UnsafeAccess.UNSAFE.putOrderedObject(lb, offset, null); | |
head++; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# {method} 'poll' '()Ljava/lang/Object;' in 'io/jaq/spsc/FFBuffer' AFTER | |
# [sp+0x20] (sp of caller) | |
0x00007f885ca2ccc0: mov r10d,DWORD PTR [rsi+0x8] | |
0x00007f885ca2ccc4: cmp rax,r10 | |
0x00007f885ca2ccc7: jne 0x00007f885ca03960 ; {runtime_call} | |
0x00007f885ca2cccd: xchg ax,ax | |
[Verified Entry Point] | |
0x00007f885ca2ccd0: sub rsp,0x18 | |
0x00007f885ca2ccd7: mov QWORD PTR [rsp+0x10],rbp ;*synchronization entry | |
; - io.jaq.spsc.FFBuffer::poll@-1 (line 133) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Allocates a new block of native memory, of the given size in bytes.The | |
* contents of the memory are uninitialized; they will generally be | |
* garbage.The resulting native pointer will never be zero, and will be | |
* aligned for all value types.Dispose of this memory by calling {@link | |
* #freeMemory}, or resize it with {@link #reallocateMemory}. | |
* | |
* @throws IllegalArgumentException if the size is negative or too large | |
* for the native size_t type | |
* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Foo{ | |
volatile Foo next; | |
Foo getNextNext(){ | |
// Commented out code as reminder of silly bug | |
// if (next != null) { | |
// // This can still result in NPE, next can change between reads | |
// return next.next; | |
// } | |
// This is how we do it! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static final int REF_SIZE = ...; | |
static final int OBJECT_ARRAY_BASE = UNSAFE.arrayBaseOffset((Object[].class); | |
static final boolean USE_COMPRESSED_REFS = ...; | |
static final int COMPRESSED_REF_SHIFT = ...; | |
public static long addressOf(Object o) { | |
return addressOf(o, REF_SIZE); | |
} | |
public static long addressOf(Object o, int oopSize) { | |
Object[] array = new Object[1]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Let Shipilev do all the heavy lifting! | |
import org.openjdk.jol.util.VMSupport; | |
... | |
// Suddenly, I feel the urge to get an object address | |
long address = VMSupport.addressOf(anUnsuspectingObject); | |
// Satisfied. I move on to never using that address... | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static long sizeOf(Object object) { | |
Unsafe unsafe = getUnsafe(); | |
// Original : return unsafe.getAddress( normalize( unsafe.getInt(object, 4L) ) + 12L ); | |
// This is my elaborate breakdown of original one liner | |
int addressOfKlassInObjectHeader = unsafe.getInt(object, 4L); | |
long nativeAddressOfKlass = normalize(addressOfKlassInObjectHeader); | |
long addressOfLayoutHelper = nativeAddressOfKlass + 12L; | |
return unsafe.getAddress(addressOfLayoutHelper); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static Object shallowCopy(Object obj) { | |
long size = sizeOf(obj); | |
long start = toAddress(obj); | |
long address = getUnsafe().allocateMemory(size); | |
getUnsafe().copyMemory(start, address, size); | |
return fromAddress(address); | |
} | |
static long toAddress(Object obj) { | |
Object[] array = new Object[] {obj}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public boolean offer(final E e) { | |
if (null == e) { | |
throw new NullPointerException("Null is not a valid element"); | |
} | |
final long currHeadCache = lvHeadCache(); // Must load volatile, may have changed by other producer | |
long currentTail; | |
do { | |
currentTail = lvTail(); // Must load volatile, may have changed by other producer | |
final long wrapPoint = currentTail - capacity; |
OlderNewer