https://middleofnowheregaming.files.wordpress.com/2015/04/game-of-thrones_20150327091828.jpg
Project Panama
Beyond the (JVM) Wall
www.hazelcast.com@noctarius2k
Disclaimer
This is not a rant - promised!
Just a little bit about JNI ;-)
www.hazelcast.com@noctarius2k
Disclaimer #2
If you haven’t seen Game of Thrones yet

keep your eyes closed!
www.hazelcast.com@noctarius2k
Disclaimer #3
Everything is provisional
Don’t take anything as final!
www.hazelcast.com@noctarius2k
Who’s that dude?
• Chris Engelbert
• Manager of Developer Relations @Hazelcast
• Java-Passionate (10+ years)
• Performance
• Garbage Collection
• JVM / Benchmark Fairytales
www.hazelcast.com@noctarius2k
I drink and I know things (sometimes)
www.hazelcast.com@noctarius2k
Project Panama
The True Native Love
www.hazelcast.com@noctarius2k
Unite Enemies
C/C++Java
www.hazelcast.com@noctarius2k
JNI! That's a good name for you!
www.hazelcast.com@noctarius2k
JNI brings interaction between
native code and Java
#include <unistd.h>
int pid = getpid();
simple kernel call
www.hazelcast.com@noctarius2k
JNI brings interaction between
native code and Java
#include <unistd.h>
int pid = getpid();
simple kernel call header import
www.hazelcast.com@noctarius2k
JNI brings interaction between
native code and Java
#include <unistd.h>
int pid = getpid();
simple kernel call header import
request PID
www.hazelcast.com@noctarius2k
#include <unistd.h>
int pid = getpid();
Isn’t that easy in C?
www.hazelcast.com@noctarius2k
You know nothing, of JNI!
www.hazelcast.com@noctarius2k
Starting with the C part :-)
www.hazelcast.com@noctarius2k
Starting with the C part :-)
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
www.hazelcast.com@noctarius2k
Starting with the C part :-)
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
export it as a JNI method
www.hazelcast.com@noctarius2k
Starting with the C part :-)
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
export it as a JNI method
Java Classname
www.hazelcast.com@noctarius2k
Starting with the C part :-)
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
export it as a JNI method
Java Classname Java Methodname
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
Starting with the C part :-)
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
Starting with the C part :-)
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
kernel call
www.hazelcast.com@noctarius2k
When you think you just won…
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
Starting with the C part :-)
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
Starting with the C part :-)
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
JNI version definition
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
done, easy right?
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
oh, missing the Java side, still
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
public class ProcessIdentifier {
static {
System.loadLibrary("processidentifier");
}
public native void getProcessId();
}
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
oh, missing the Java side, still
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
public class ProcessIdentifier {
static {
System.loadLibrary("processidentifier");
}
public native void getProcessId();
}
Java Classname
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
oh, missing the Java side, still
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
public class ProcessIdentifier {
static {
System.loadLibrary("processidentifier");
}
public native void getProcessId();
}
Java Classname Java Methodname
www.hazelcast.com@noctarius2k
extern C {
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
}
JNIEXPORT int JNICALL
Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) {
return getpid();
}
ok, ok, now we’re done!
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
public class ProcessIdentifier {
static {
System.loadLibrary("processidentifier");
}
public native void getProcessId();
}
www.hazelcast.com@noctarius2k
Wasn’t that easy?
www.hazelcast.com@noctarius2k
Wasn’t that easy?
but remember…
www.hazelcast.com@noctarius2k
Everybody struggles with JNI!
www.hazelcast.com@noctarius2k
meanwhile behind

the wall…
www.hazelcast.com@noctarius2k
Java 9 to the rescue
www.hazelcast.com@noctarius2k
Java 9 to the rescue
long pid = ProcessHandle.current().getPid();
www.hazelcast.com@noctarius2k
Java 9 to the rescue
long pid = ProcessHandle.current().getPid();
convenient, eh?
www.hazelcast.com@noctarius2k
but how many can
just update?
www.hazelcast.com@noctarius2k
So? JNI?
www.hazelcast.com@noctarius2k
So? JNI? - NO!
www.hazelcast.com@noctarius2k
A Song From Methods And Handles
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
type definition
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
returntypetype definition
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
returntypetype definition
Java Classname
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
returntypetype definition
Java Classname Java Methodname
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
returntypetype definition
Java Classname Java Methodnamecall the new callsite
www.hazelcast.com@noctarius2k
MethodHandles
So? What’s the deal? Java 7, right?
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findVirtual(ProcessIdentifier.class, "getProcessId", type);
int pid = mh.invokeExact();
virtual call
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findNative(null, "getpid", type);
int pid = mh.invokeExact();
native
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findNative(null, "getpid", type);
int pid = mh.invokeExact();
native
native call
www.hazelcast.com@noctarius2k
MethodHandles
MethodType type = MethodType.methodType(int.class);
MethodHandle mh = MethodHandles.lookup()
.findNative(null, "getpid", type);
int pid = mh.invokeExact();
native
native call null = kernel call

otherwise lib name
www.hazelcast.com@noctarius2k
Easier than taking
the Iron Throne!
www.hazelcast.com@noctarius2k
The Mad King
www.hazelcast.com@noctarius2k
Pointer with sun.misc.Unsafe
Unsafe unsafe = getUnsafeWithMagic();
long ptr = unsafe.allocateMemory(20);
byte val = unsafe.getByte(ptr + 5);
www.hazelcast.com@noctarius2k
Pointer with sun.misc.Unsafe
Unsafe unsafe = getUnsafeWithMagic();
long ptr = unsafe.allocateMemory(20);
byte val = unsafe.getByte(ptr + 5);
retrieve sun.misc.Unsafe instance
www.hazelcast.com@noctarius2k
Pointer with sun.misc.Unsafe
Unsafe unsafe = getUnsafeWithMagic();
long ptr = unsafe.allocateMemory(20);
byte val = unsafe.getByte(ptr + 5);
retrieve sun.misc.Unsafe instance
allocate 20 bytes
www.hazelcast.com@noctarius2k
Pointer with sun.misc.Unsafe
Unsafe unsafe = getUnsafeWithMagic();
long ptr = unsafe.allocateMemory(20);
byte val = unsafe.getByte(ptr + 5);
retrieve sun.misc.Unsafe instance
allocate 20 bytesget byte at ptr+5
www.hazelcast.com@noctarius2k
So I die, for using Unsafe?
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
LayoutType<Byte> layout =
NativeLibrary.createLayout(byte.class);
try (Scope scope = new NativeScope()) {
Pointer<Byte> p = scope.allocate(layout, 20);
Reference<Byte> ref = p.offset(5).deref();
byte val = ref.get();
}
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
LayoutType<Byte> layout =
NativeLibrary.createLayout(byte.class);
try (Scope scope = new NativeScope()) {
Pointer<Byte> p = scope.allocate(layout, 20);
Reference<Byte> ref = p.offset(5).deref();
byte val = ref.get();
}
byte-array
layout
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
LayoutType<Byte> layout =
NativeLibrary.createLayout(byte.class);
try (Scope scope = new NativeScope()) {
Pointer<Byte> p = scope.allocate(layout, 20);
Reference<Byte> ref = p.offset(5).deref();
byte val = ref.get();
}
byte-array
layout
create a
scope
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
LayoutType<Byte> layout =
NativeLibrary.createLayout(byte.class);
try (Scope scope = new NativeScope()) {
Pointer<Byte> p = scope.allocate(layout, 20);
Reference<Byte> ref = p.offset(5).deref();
byte val = ref.get();
}
byte-array
layout
create a
scope
allocate

20 bytes
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
LayoutType<Byte> layout =
NativeLibrary.createLayout(byte.class);
try (Scope scope = new NativeScope()) {
Pointer<Byte> p = scope.allocate(layout, 20);
Reference<Byte> ref = p.offset(5).deref();
byte val = ref.get();
}
byte-array
layout
create a
scope
allocate

20 bytes
get byte

at ptr+5
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
www.hazelcast.com@noctarius2k
Who needs Unsafe anyways
www.hazelcast.com@noctarius2k
A REAL NULL POINTER! THANK YOU JAVA!
Who needs Unsafe anyways
www.hazelcast.com@noctarius2k
About Structs and
other Creatures
www.hazelcast.com@noctarius2k
Struct in Java? No, Layout!
typedef struct {
int32_t val;
Node next;
} Node;
www.hazelcast.com@noctarius2k
Same LinkedList Node in Java
@LayoutDesc({"x:jint:4", "y:Node:8"})
public interface Node extends Layout {
// …
}
www.hazelcast.com@noctarius2k
@LayoutDesc({"x:jint:4", "y:Node:8"})
public interface Node extends Layout {
interface EffectiveAddress {
IntPointer val();
Pointer<Node> next();
}
// …
}
Same LinkedList Node in Java
www.hazelcast.com@noctarius2k
@LayoutDesc({"x:jint:4", "y:Node:8"})
public interface Node extends Layout {
Node.EffectiveAddress EA();
long sizeof();
int val();
// …
}
Same LinkedList Node in Java
www.hazelcast.com@noctarius2k
@LayoutDesc({"x:jint:4", "y:Node:8"})
public interface Node extends Layout {
Node next();
void val(int val);
void next(Node next);
String toString();
}
Same LinkedList Node in Java
www.hazelcast.com@noctarius2k
Scope scope = new NativeScope();
Pointer<Node> ptr = scope.allocate(Node.class);
Node node = ptr.getLayout();
int val = node.val();
Node next = node.next();
Creating layouted Objects
www.hazelcast.com@noctarius2k
I slayed the Mad King
www.hazelcast.com@noctarius2k
Value Isn’t A Pit. Value Is A Ladder.
www.hazelcast.com@noctarius2k
Value Types
value class Point {
int x;
int y;
}
www.hazelcast.com@noctarius2k
Value Types
Point point = __make Point(1, 2);
int x = point.x;
int y = point.y;
www.hazelcast.com@noctarius2k
Yet another layout?
www.hazelcast.com@noctarius2k
class Point {}
Point[] points = …
Arrays of Points
www.hazelcast.com@noctarius2k
value class Point {}
Point[] points = …
Arrays of Points
www.hazelcast.com@noctarius2k
I’m feeling so Assembler today
www.hazelcast.com@noctarius2k
Coding a Vector-Function in Java
MethodType type = MethodType.methodType(
Float.class, Float.class, Float.class);
MethodHandle m256_vadds = CodeSnippets
.make(..., type, …);
m256_vadds.invokeExact(out, in1, in2);
low-level
www.hazelcast.com@noctarius2k
Coding a Vector-Function in Java
high-level
interface Vector<E, S extends Shape<Vector?, S>> {
Vector<E, S> add (Vector<E, S> other);
Vector<E, S> mul (Vector<E, S> other);
Vector<E, S> and (Vector<E, S> other);
// ... more operations
}
www.hazelcast.com@noctarius2k
Coding a Vector-Function in Java
high-level
void addVector(float[] left, float[] right,
float[] res, int length) {
// …
}
www.hazelcast.com@noctarius2k
Coding a Vector-Function in Java
high-level
void addVector(float[] left, float[] right,
float[] res, int length) {
FloatVector<S256Bit> l =
float256FromArray(left, length);
FloatVector<S256Bit> r =
float256FromArray(right, length);
// …
}
www.hazelcast.com@noctarius2k
Coding a Vector-Function in Java
high-level
void addVector(float[] left, float[] right,
float[] res, int length) {
// …
FloatVector<S256Bit> lr = l.add(r);
lr.intoArray(res, length);
}
www.hazelcast.com@noctarius2k
Razersharp tooling
www.hazelcast.com@noctarius2k
So what do we expect?
www.hazelcast.com@noctarius2k
Peace with the Dragons
www.hazelcast.com@noctarius2k
Peace with the Dragons
C / C++
www.hazelcast.com@noctarius2k
Painless communication…
www.hazelcast.com@noctarius2k
Painless communication…
…between native and Java code
www.hazelcast.com@noctarius2k
More fun…
www.hazelcast.com@noctarius2k
More fun…
… and faster code …
www.hazelcast.com@noctarius2k
More fun…
…without JNI
… and faster code …
www.hazelcast.com@noctarius2k
Thank You &
George R.R. Martin
www.hazelcast.com@noctarius2k
More information:
• http://openjdk.java.net/projects/valhalla/
• http://openjdk.java.net/projects/panama/
• http://cr.openjdk.java.net/~jrose/values/values-0.html
• http://blog.codefx.org/java/dev/the-road-to-valhalla/
• http://openjdk.java.net/jeps/191
• https://www.youtube.com/watch?v=JR1zI5gLhRM
• https://github.com/J9Java/panama-layout-prototype
• https://developer.ibm.com/open/openprojects/project-panama-layout-prototype/
• https://www.youtube.com/watch?v=Tc9vs_HFHVo
• https://www.youtube.com/watch?v=Z2XgO1H6xPM
Thank You!
www.hazelcast.com@noctarius2k
Thank You!
Any Questions?
@noctarius2k
http://www.sourceprojects.org
http://github.com/noctarius
@hazelcast
http://www.hazelcast.com
http://www.hazelcast.org
http://github.com/hazelcast
www.hazelcast.com@noctarius2k
German
speaking?
JVM related talk
on Slack
Get your own invite at:
https://slackin-jvm-german.herokuapp.com

Project Panama - Beyond the (JVM) Wall