Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Project Panama - Beyond the (JVM) Wall

4 226 vues

Publié le

The days of JNI is counted, Project Panama is on the rise to tear down the walls between Java and C/C++ forever. FFI (Foreign Function Interface) technology finally arrives into the Java world.

Publié dans : Logiciels
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

Project Panama - Beyond the (JVM) Wall

  1. 1. https://middleofnowheregaming.files.wordpress.com/2015/04/game-of-thrones_20150327091828.jpg Project Panama Beyond the (JVM) Wall
  2. 2. www.hazelcast.com@noctarius2k Disclaimer This is not a rant - promised! Just a little bit about JNI ;-)
  3. 3. www.hazelcast.com@noctarius2k Disclaimer #2 If you haven’t seen Game of Thrones yet
 keep your eyes closed!
  4. 4. www.hazelcast.com@noctarius2k Disclaimer #3 Everything is provisional Don’t take anything as final!
  5. 5. 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
  6. 6. www.hazelcast.com@noctarius2k I drink and I know things (sometimes)
  7. 7. www.hazelcast.com@noctarius2k Project Panama The True Native Love
  8. 8. www.hazelcast.com@noctarius2k Unite Enemies C/C++Java
  9. 9. www.hazelcast.com@noctarius2k JNI! That's a good name for you!
  10. 10. www.hazelcast.com@noctarius2k JNI brings interaction between native code and Java #include <unistd.h> int pid = getpid(); simple kernel call
  11. 11. www.hazelcast.com@noctarius2k JNI brings interaction between native code and Java #include <unistd.h> int pid = getpid(); simple kernel call header import
  12. 12. 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
  13. 13. www.hazelcast.com@noctarius2k #include <unistd.h> int pid = getpid(); Isn’t that easy in C?
  14. 14. www.hazelcast.com@noctarius2k You know nothing, of JNI!
  15. 15. www.hazelcast.com@noctarius2k Starting with the C part :-)
  16. 16. www.hazelcast.com@noctarius2k Starting with the C part :-) extern C { JNIEXPORT int JNICALL Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject); }
  17. 17. 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
  18. 18. 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
  19. 19. 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
  20. 20. 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(); }
  21. 21. 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
  22. 22. www.hazelcast.com@noctarius2k When you think you just won…
  23. 23. 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; }
  24. 24. 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
  25. 25. 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; }
  26. 26. 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(); }
  27. 27. 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
  28. 28. 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
  29. 29. 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(); }
  30. 30. www.hazelcast.com@noctarius2k Wasn’t that easy?
  31. 31. www.hazelcast.com@noctarius2k Wasn’t that easy? but remember…
  32. 32. www.hazelcast.com@noctarius2k Everybody struggles with JNI!
  33. 33. www.hazelcast.com@noctarius2k meanwhile behind
 the wall…
  34. 34. www.hazelcast.com@noctarius2k Java 9 to the rescue
  35. 35. www.hazelcast.com@noctarius2k Java 9 to the rescue long pid = ProcessHandle.current().getPid();
  36. 36. www.hazelcast.com@noctarius2k Java 9 to the rescue long pid = ProcessHandle.current().getPid(); convenient, eh?
  37. 37. www.hazelcast.com@noctarius2k but how many can just update?
  38. 38. www.hazelcast.com@noctarius2k So? JNI?
  39. 39. www.hazelcast.com@noctarius2k So? JNI? - NO!
  40. 40. www.hazelcast.com@noctarius2k A Song From Methods And Handles
  41. 41. www.hazelcast.com@noctarius2k MethodHandles MethodType type = MethodType.methodType(int.class); MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type); int pid = mh.invokeExact();
  42. 42. 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
  43. 43. 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
  44. 44. 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
  45. 45. 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
  46. 46. 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
  47. 47. www.hazelcast.com@noctarius2k MethodHandles So? What’s the deal? Java 7, right?
  48. 48. www.hazelcast.com@noctarius2k MethodHandles MethodType type = MethodType.methodType(int.class); MethodHandle mh = MethodHandles.lookup() .findVirtual(ProcessIdentifier.class, "getProcessId", type); int pid = mh.invokeExact();
  49. 49. 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
  50. 50. www.hazelcast.com@noctarius2k MethodHandles MethodType type = MethodType.methodType(int.class); MethodHandle mh = MethodHandles.lookup() .findNative(null, "getpid", type); int pid = mh.invokeExact(); native
  51. 51. 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
  52. 52. 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
  53. 53. www.hazelcast.com@noctarius2k Easier than taking the Iron Throne!
  54. 54. www.hazelcast.com@noctarius2k The Mad King
  55. 55. www.hazelcast.com@noctarius2k Pointer with sun.misc.Unsafe Unsafe unsafe = getUnsafeWithMagic(); long ptr = unsafe.allocateMemory(20); byte val = unsafe.getByte(ptr + 5);
  56. 56. 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
  57. 57. 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
  58. 58. 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
  59. 59. www.hazelcast.com@noctarius2k So I die, for using Unsafe?
  60. 60. 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(); }
  61. 61. 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
  62. 62. 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
  63. 63. 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
  64. 64. 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
  65. 65. www.hazelcast.com@noctarius2k Who needs Unsafe anyways
  66. 66. www.hazelcast.com@noctarius2k Who needs Unsafe anyways
  67. 67. www.hazelcast.com@noctarius2k A REAL NULL POINTER! THANK YOU JAVA! Who needs Unsafe anyways
  68. 68. www.hazelcast.com@noctarius2k About Structs and other Creatures
  69. 69. www.hazelcast.com@noctarius2k Struct in Java? No, Layout! typedef struct { int32_t val; Node next; } Node;
  70. 70. www.hazelcast.com@noctarius2k Same LinkedList Node in Java @LayoutDesc({"x:jint:4", "y:Node:8"}) public interface Node extends Layout { // … }
  71. 71. 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
  72. 72. 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
  73. 73. 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
  74. 74. 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
  75. 75. www.hazelcast.com@noctarius2k I slayed the Mad King
  76. 76. www.hazelcast.com@noctarius2k Value Isn’t A Pit. Value Is A Ladder.
  77. 77. www.hazelcast.com@noctarius2k Value Types value class Point { int x; int y; }
  78. 78. www.hazelcast.com@noctarius2k Value Types Point point = __make Point(1, 2); int x = point.x; int y = point.y;
  79. 79. www.hazelcast.com@noctarius2k Yet another layout?
  80. 80. www.hazelcast.com@noctarius2k class Point {} Point[] points = … Arrays of Points
  81. 81. www.hazelcast.com@noctarius2k value class Point {} Point[] points = … Arrays of Points
  82. 82. www.hazelcast.com@noctarius2k I’m feeling so Assembler today
  83. 83. 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
  84. 84. 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 }
  85. 85. www.hazelcast.com@noctarius2k Coding a Vector-Function in Java high-level void addVector(float[] left, float[] right, float[] res, int length) { // … }
  86. 86. 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); // … }
  87. 87. 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); }
  88. 88. www.hazelcast.com@noctarius2k Razersharp tooling
  89. 89. www.hazelcast.com@noctarius2k So what do we expect?
  90. 90. www.hazelcast.com@noctarius2k Peace with the Dragons
  91. 91. www.hazelcast.com@noctarius2k Peace with the Dragons C / C++
  92. 92. www.hazelcast.com@noctarius2k Painless communication…
  93. 93. www.hazelcast.com@noctarius2k Painless communication… …between native and Java code
  94. 94. www.hazelcast.com@noctarius2k More fun…
  95. 95. www.hazelcast.com@noctarius2k More fun… … and faster code …
  96. 96. www.hazelcast.com@noctarius2k More fun… …without JNI … and faster code …
  97. 97. www.hazelcast.com@noctarius2k Thank You & George R.R. Martin
  98. 98. 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!
  99. 99. 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
  100. 100. www.hazelcast.com@noctarius2k German speaking? JVM related talk on Slack Get your own invite at: https://slackin-jvm-german.herokuapp.com

×