Project Panama - Beyond the (JVM) Wall

Post on 11-Apr-2017

1.131 views 0 download

Transcript of Project Panama - Beyond the (JVM) Wall

https://middleofnowheregaming.files.wordpress.com/2015/04/game-of-thrones_20150327091828.jpg

Project PanamaBeyond the (JVM) Wall

www.hazelcast.com@noctarius2k

DisclaimerThis is not a rant - promised!

Just a little bit about JNI ;-)

www.hazelcast.com@noctarius2k

Disclaimer #2If you haven’t seen Game of Thrones yet

keep your eyes closed!

www.hazelcast.com@noctarius2k

Disclaimer #3Everything 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 JNICALLJava_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 JNICALLJava_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

Starting with the C part :-)JNIEXPORT jint JNICALLJNI_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

Starting with the C part :-)JNIEXPORT jint JNICALLJNI_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

done, easy right?JNIEXPORT jint JNICALLJNI_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

oh, missing the Java side, stillJNIEXPORT jint JNICALLJNI_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

oh, missing the Java side, stillJNIEXPORT jint JNICALLJNI_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

oh, missing the Java side, stillJNIEXPORT jint JNICALLJNI_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 JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObject) { return getpid();}

ok, ok, now we’re done!JNIEXPORT jint JNICALLJNI_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

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type);

int pid = mh.invokeExact();

www.hazelcast.com@noctarius2k

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type);

int pid = mh.invokeExact();

type definition

www.hazelcast.com@noctarius2k

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type);

int pid = mh.invokeExact();

returntypetype definition

www.hazelcast.com@noctarius2k

MethodHandlesMethodType 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

MethodHandlesMethodType 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

MethodHandlesMethodType 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

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type);

int pid = mh.invokeExact();

www.hazelcast.com@noctarius2k

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type);

int pid = mh.invokeExact();

virtual call

www.hazelcast.com@noctarius2k

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findNative(null, "getpid", type);

int pid = mh.invokeExact();

native

www.hazelcast.com@noctarius2k

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findNative(null, "getpid", type);

int pid = mh.invokeExact();

native

native call

www.hazelcast.com@noctarius2k

MethodHandlesMethodType type = MethodType.methodType(int.class);MethodHandle mh = MethodHandles.lookup() .findNative(null, "getpid", type);

int pid = mh.invokeExact();

native

native call null = kernel callotherwise lib name

www.hazelcast.com@noctarius2k

Easier than takingthe 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 anywaysLayoutType<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 anywaysLayoutType<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-arraylayout

www.hazelcast.com@noctarius2k

Who needs Unsafe anywaysLayoutType<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-arraylayout

create ascope

www.hazelcast.com@noctarius2k

Who needs Unsafe anywaysLayoutType<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-arraylayout

create ascope

allocate 20 bytes

www.hazelcast.com@noctarius2k

Who needs Unsafe anywaysLayoutType<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-arraylayout

create ascope

allocate 20 bytesget 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 JavaMethodType 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 Javahigh-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 Javahigh-level

void addVector(float[] left, float[] right, float[] res, int length) { // …}

www.hazelcast.com@noctarius2k

Coding a Vector-Function in Javahigh-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 Javahigh-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 DragonsC / 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

Germanspeaking?

JVM related talk on Slack

Get your own invite at:https://slackin-jvm-german.herokuapp.com