135
Working with Native Libraries in Java Vladimir Ivanov HotSpot JVM Compile r Oracle Corp. @iwan0www OpenJDK: vlivanov 14.10.2016

Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

1 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Working with Native Libraries in Java

Vladimir Ivanov HotSpot JVM Compile r Oracle Corp.

@iwan0www OpenJDK: vlivanov

14.10.2016

Page 2: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

2 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Why?

§ LAPACK –  Linear Algebra PACKage

Page 3: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

3 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Why?

§ LAPACK –  Linear Algebra PACKage –  written in Fortran 90 –  highly optimized

§  “The original goal of the LAPACK was to … run efficiently on shared-memory vector and parallel processors.”

Page 4: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

4 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

How?

§ LAPACK 1.  invoke library code 2.  pass data into library 3.  access data from Java

Page 5: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

5 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Overview

§ Existing –  Java Native Interface (JNI) & JNR library –  java.nio.DirectByteBuffer –  sun.misc.Unsafe (get*/set*)

§  JDK9 –  j.l.i.VarHandle views over ByteBuffers

§ Future –  Project Panama

Page 6: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

6 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Native Code

Page 7: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

7 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Native Code

§ LAPACK 1.  invoke library code 2.  pass data into library 3.  access data from Java

B = A2

Page 8: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

8 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI @since 1.1

Page 9: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

9 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI

classLibC{staticnativelonggetpid();}

jlongJNICALLJava_LibC_getpid(JNIEnv*env,jclassc){ returngetpid();}

Usage scenario

Page 10: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

10 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI

jlongJNICALLJava_...(JNIEnv*env, jclasscls, jobjectobj){jmethodIDmid=env->GetMethodID(cls,“m”,“(I)J”);jlongresult=env->CallLongMethod(obj,mid,10);

Upcall

Page 11: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

11 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI

jlongJNICALLJava_...(JNIEnv*env, jclasscls, jobjectobj){jfieldIDfid=env->GetFieldID(cls,“f”,“J”);jlongresult=env->GetLongField(obj,fid);jlongresult=env->SetLongField(obj,fid,10);

Data access

Page 12: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

12 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI

§ Operations on –  Classes –  Strings –  Arrays –  Monitors

Native API: JNIEnv

Page 13: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

13 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java Frame

Java Heap Native Memory

Native Frame

GC roots

Page 14: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

14 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java Heap Native Memory

Java Frame Native Frame

GC roots

Page 15: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

15 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

jobjectraw ptr address

Java Heap

Native Memory

ptr

Page 16: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

16 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

jobjectraw ptr address

Java Heap

Native Memory

ptr

Page 17: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

17 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java Heap Native MemoryH

andl

es

Java Frame Native Frame

GC roots

Page 18: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

18 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java

Native

Java Heap

Native Memory

VM

Thread State

Anatomy of JNI call

Page 19: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

19 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java

Native

Java Heap

Native Memory

VM

Thread State

Anatomy of JNI call Safepoints

Page 20: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

20 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI

§ Pros –  seamless integration

§  looks like a Java method –  rich native API to interact with Java

§ Cons –  manual binding –  invocation overhead

Page 21: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

21 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI Victim of its own success?

Page 22: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

22 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI Sum array elements

jintJNICALLJava_...(JNIEnv*env,jclassc,jobjectarr){jintlen=(*env)->GetArrayLength(env,arr);jbyte*a=(*env)->GetPrimitiveArrayCritical(env,arr,0);…returnsum;}

empty sum 1 sum 103 sum 106 JNI 11.4±0.3 ns 178.0±7.1 ns 798±32 ns 641±51 µs

Page 23: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

23 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI /* @since 7 */

Page 24: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

24 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI Sum array elements

jintJNICALLJavaCritical_...(jintlength,jbyte*first){...returnsum;}

empty sum 1 sum 103 sum 106 JNI 11.4±0.3 ns 178.0±7.1 ns 798±32 ns 641±51 µs CriticalJNI 11.4±0.3 ns 17.2±0.8 ns 680±22 ns 636±12 µs

Page 25: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

25 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI

§ only static, non-synchronized methods supported

Limitations

Page 26: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

26 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI

§ only static, non-synchronized methods supported § no JNIEnv*

–  hence, no upcalls or access to Java heap

Limitations

Page 27: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

27 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI

§ only static, non-synchronized methods supported § no JNIEnv* § arguments: primitives or primitive arrays

–  [I => (length, I*) –  null => (0, NULL)

Limitations

Page 28: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

28 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI

§ only static, non-synchronized methods supported § no JNIEnv* § arguments: primitives or primitive arrays

–  [I => (length, I*) –  null => (0, NULL)

§ no object arguments

Limitations

Page 29: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

29 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Critical JNI

§ only static, non-synchronized methods supported § no JNIEnv* § arguments: primitives or primitive arrays

–  [I => (length, I*) –  null => (0, NULL)

§ no object arguments § used only in optimized code

–  2 versions are needed: ordinary JNI & critical JNI versions

Limitations

Page 30: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

30 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

intprintf(constchar*format,...)

Hard cases

Page 31: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

31 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

voidqsort(void*base,size_tnel,size_twidth,int(*cmp)(constvoid*,constvoid*));

Hard cases

Page 32: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

32 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNR Java Native Runtime

Page 33: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

33 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNR

public interface LibC { @pid_t long getpid(); } LibC lib = LibraryLoader .create(LibC.class) .load("c");

libc.getpid()

Usage scenario

JNRJava

Native

bindings

Interfaces

libffi

Target

User-defined

generated on-the-fly

Page 34: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

34 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

DEMO

§ native call –  getpid

§  structs –  gettimeofday

§ upcalls –  qsort

Page 35: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

35 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNR

§ Pros –  automatic binding of native methods

§ Cons –  manual interface extraction

§  doesn’t scale –  still uses JNI to perform native calls

Page 36: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

36 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Better JNI Easier, safer, faster!

Page 37: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

37 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

“If non-Java programmers find some library useful and easy to access, it should be similarly accessible to Java programmers.”

John Rose, JVM Architect,

Oracle Corporation

Page 38: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

38 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Project Panama “Bridging the gap”

Page 39: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

39 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Page 40: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

40 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Better JNI

pid_t get_pid();

Page 41: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

41 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Easier

publicinterfaceLibC{longgetpid();}LibClibc=Library .load(LibC.class,“c”);libc.getpid();

Better JNI

j.l.iJava

Native

bindings

Interfaces

JVM stubs

Target

User-defined

Library

generated on-the-fly

produced by jextract

Page 42: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

42 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Easier

publicinterfaceLibC{longgetpid();}LibClibc=Library.load(LibC.class,“c”/*lib_name*/);libc.getpid();

Better JNI

Page 43: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

43 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Faster Better JNI

callq 0x1057b2eb0 ; getpid entry

Page 44: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

44 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Faster

MethodTypemt=MethodType.methodType(int.class);//pid_tMethodHandlemh=MethodHandles.lookup().findNative("getpid",mt);intpid=(int)mh.invokeExact();

Better JNI

getpid JNI 13.7 ± 0.5 ns Direct call 3.4 ± 0.2 ns

Page 45: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

45 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Safer

§ no crashes § no leaks § no hangs § no privilege escalation § no unguarded casts

Better JNI

Page 46: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

46 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Safety vs Speed

Page 47: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

47 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Safety vs Speed

Page 48: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

48 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Safety vs Speed

Page 49: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

49 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Safety vs Speed

Page 50: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

50 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Trust Levels Better JNI

Untrusted

Page 51: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

51 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Trust Levels Better JNI

Trusted

Page 52: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

52 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Trust Levels Better JNI

Privileged

Page 53: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

53 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Usage Better JNI

Page 54: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

54 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

gettimeofday BetterJNI

/*time.h*/struct{time_ttv_sec;suseconds_ttv_usec;}timeval;

intgettimeofday(structtimeval*tv,structtimezone*tz);

struct{inttz_minuteswest;inttz_dsttime;}timezone;

Page 55: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

55 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Carrier Types

§ Javabooleanbyteshortcharintlong…

§ Ccharshortfloatintlonglonglong…

?

Page 56: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

56 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Carrier Types

§ Javaboolean(uint8_t)byte(int8_t)short(int16_t)char(uint16_t)int(int32_t)long(int64_t)…

§ Ccharshortfloatintlonglonglong…

?

Page 57: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

57 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

$ jextract time.h Better JNI

interfaceTime{interfaceTimeval{longtv_sec$get();voidtv_sec$set(long);longtv_usec$get();voidtv_usec$set(long);}

intgettimeofday(Timeval,Timezone);

interfaceTimezone{inttz_...$get();voidtz_...$set(int);inttz_...$get();voidtz_...$set(int);}

Page 58: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

58 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Foreign Layouts

§ Native data requires special address arithmetic –  Native layouts should not be built into the JVM –  Native types are unsafe, so trusted code must manage the bits

§ Solution: A metadata-driven Layout API

§ As a bonus, layouts other than C and Java are naturally supported –  Network protocols, specialized in-memory data stores, mapped files, etc.

58

Page 59: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

59 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Better JNI Data Layout

interfaceTimeval{…@Offset(offset=0L)longtv_sec$get();…@Offset(offset=64L)longtv_usec$get();…§ work on Layout Definition Language (LDL) is in progress

–  https://github.com/J9Java/panama-docs/blob/master/StateOfTheLDL.html –  http://cr.openjdk.java.net/~jrose/panama/minimal-ldl.html

Page 60: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

60 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Runtime Better JNI Librarylib=Library.create(“c”);Timetime=lib.create(Time.class);Timevaltval=lib.create(Timeval.class);intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}

Page 61: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

61 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Runtime Better JNI Librarylib=Library.create(“c”);Timetime=lib.create(Time.class);Timevaltval=lib.create(Timeval.class);intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}

Page 62: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

62 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Runtime Better JNI Librarylib=Library.create(“c”);Timetime=lib.create(Time.class);Timevaltval=lib.create(Timeval.class);intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}

Page 63: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

63 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Runtime Better JNI Librarylib=Library.create(“c”);Timetime=lib.create(Time.class);Timevaltval=lib.create(Timeval.class);intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}

Page 64: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

64 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Resources Explicit management

Timevaltval=null;try{tval=lib.create(Timeval.class);intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}}finally{if(tval!=null){lib.free(tval);tval=null;}}

Page 65: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

65 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Resources Try-with-resources

interfaceTimevalextendsAutoCloseable{…}try(Timevaltval=lib.create(Timeval.class)){intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}}

Page 66: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

66 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Resources Scoped memory

try(Scopescope=lib.createScope()){TimeValtval=scope.create(TimeVal.class);intres=time.gettimeofday(tval,null);if(res==0){longtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}else{/*errorhandling*/}}

Page 67: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

67 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Resources Scoped memory

TimeValtval=null;try(Scopescope=lib.createScope()){tval=scope.create(TimeVal.class);intres=time.gettimeofday(tval,null);}//endofscope

Page 68: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

68 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Resources Scoped memory

TimeValtval=null;try(Scopescope=lib.createScope()){tval=scope.create(TimeVal.class);intres=time.gettimeofday(tval,null);}//endofscope//Accessattempsoutofscopelongtv_sec=tval.tv_sec$get();//livenesschecks!longtv_usec=tval.tv_usec$get();//livenesschecks!

Page 69: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

69 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

“Civilizer” Better JNI

interfaceTimeval{voidgettimeofday(Timeval,Timezone)throwsErrNo;}

Page 70: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

70 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

“Civilizer” Better JNI

interfaceTimeval{voidgettimeofday(Timeval,Timezone)throwsErrNo;}try(Timevaltval=lib.create(Timeval.class)){time.gettimeofday(tval,null);//throwsexceptionlongtv_sec=tval.tv_sec$get();longtv_usec=tval.tv_usec$get();}

Page 71: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

71 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Variadic Function Better JNI

int printf(const char *format, ...)

Page 72: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

72 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

jextract + Civilizer Better JNI

//int printf(const char *format, ...) interfaceStdio{…//“Raw”intprintf(Pointer<Byte>format,byte[]args);

Page 73: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

73 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

jextract + Civilizer Better JNI

//int printf(const char *format, ...) interfaceStdio{…//“Raw”intprintf(Pointer<Byte>format,byte[]args);//“Civilized”voidprintf(Stringformat,Object…args);

Page 74: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

74 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimize checks

void run(MyClass obj) { obj.nativeFunc1(); // checks & state trans. obj.nativeFunc2(); // checks & state trans. obj.nativeFunc3(); // checks & state trans. }

74

Page 75: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

75 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimize checks

Java

Java Heap

Native Memory

VM

Native

Thread State

Page 76: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

76 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java

Java Heap

Native Memory

VM

Native

Thread State

Optimize checks

Page 77: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

77 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimize checks

void run(MyClass obj) { obj.f1(); // NPE obj.f2(); // NPE obj.f3(); // NPE }

Page 78: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

78 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimize checks

void run(MyClass obj) { if (obj == null) jump throwNPE_stub; call MyClass::f(obj); call MyClass::f1(obj); call MyClass::f3(obj); }

78

Page 79: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

79 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimize checks

void run(MyClass obj) { obj.nativeFunc1(); // checks & state trans. obj.nativeFunc2(); // checks & state trans. obj.nativeFunc3(); // checks & state trans. }

79

Page 80: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

80 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimize checks

void run(MyClass obj) { if (!performChecks()) jump failed_stub; call transJavaToNative(); MyClass::nativeFunc1(env, obj); MyClass::nativeFunc2(env, obj); MyClass::nativeFunc3(env, obj); call transNativeToJava(); }

80

Page 81: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

81 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java

Java Heap

Native Memory

VM

Native

Thread State

Page 82: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

82 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Java

Java Heap

Native Memory

VM

Native

Thread State

Page 83: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

83 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Better JNI

§ Native access between the JVM and native APIs –  Native code via FFIs –  Native data via safely-wrapped access functions –  Tooling for header file API extraction and API metadata storage

§ Wrapper interposition mechanisms, based on JVM interfaces –  add (or delete) wrappers for specialized safety invariants

§ Basic bindings for selected native APIs

Easier, Safer, Faster!

83

Page 84: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

84 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Native Data

Page 85: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

85 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Native Data

§ LAPACK 1.  invoke library code 2.  pass data into library 3.  access data from Java

B = A2

Page 86: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

86 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

JNI @since 1.1

Page 87: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

87 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

NIO @since 1.4

Page 88: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

88 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

NIO

§  Provides access to the low-level I/O operations –  Buffers for bulk memory operations

§  on-heap and off-heap –  Character set encoders and decoders –  Channels, a new primitive I/O abstraction –  File interface

§  supports locks and memory mapping of files –  Multiplexed, non-blocking I/O

“New I/O”

Page 89: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

89 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.Buffer

§  java.nio.ByteBuffer / CharBuffer / … –  MappedByteBuffer extends ByteBuffer

§  memory-mapped region of a file –  DirectByteBuffer extends MappedByteBuffer

§  malloc’ed native memory –  HeapByteBuffer

§  backed by byte[]

Page 90: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

90 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

ByteBufferdbb=ByteBuffer.allocateDirect(size);while(dbb.hasRemaining()){dbb.putInt(…);//init}LAPACK.square(dbb.address(),size);//invokedbb.rewind();//resetpositionwhile(dbb.hasRemaining()){inti=dbb.getInt();//readresult}

Usage

Page 91: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

91 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

ByteBufferdbb=ByteBuffer.allocateDirect(size);while(dbb.hasRemaining()){dbb.putInt(…);//init}LAPACK.square(dbb.address(),size);//invokedbb.rewind();//resetpositionwhile(dbb.hasRemaining()){inti=dbb.getInt();//readresult}

Usage

Page 92: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

92 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

ByteBufferdbb=ByteBuffer.allocateDirect(size);while(dbb.hasRemaining()){dbb.putInt(…);//init}LAPACK.square(dbb.address(),size);//invokedbb.rewind();//resetpositionwhile(dbb.hasRemaining()){inti=dbb.getInt();//readresult}

Usage

Page 93: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

93 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

ByteBufferdbb=ByteBuffer.allocateDirect(size);while(dbb.hasRemaining()){dbb.putInt(…);//init}LAPACK.square(dbb.address(),size);//invokedbb.rewind();//resetpositionwhile(dbb.hasRemaining()){inti=dbb.getInt();//readresult}

Usage

Page 94: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

94 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

ByteBufferdbb=ByteBuffer.allocateDirect(size);while(dbb.hasRemaining()){dbb.putInt(…);//init}LAPACK.square(dbb.address(),size);//invokedbb.rewind();//resetpositionwhile(dbb.hasRemaining()){inti=dbb.getInt();//readresult}

Usage

Page 95: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

95 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

ByteBufferdbb=ByteBuffer.allocateDirect(size);while(dbb.hasRemaining()){dbb.putInt(…);//init}LAPACK.square(dbb);//invokewhile(dbb.hasRemaining()){inti=dbb.getInt();//readresult}

Usage

Page 96: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

96 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.Buffer

§ < 2GiB –  ByteBuffer.allocateDirect(int size) –  ByteBuffer.allocate(int size)

Page 97: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

97 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.Buffer

§ < 2GiB –  ByteBuffer.allocateDirect(int size)

§ Stateful –  Buffer.position –  not thread-safe

Page 98: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

98 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.Buffer

§ < 2GiB –  ByteBuffer.allocateDirect(int size)

§ Stateful –  Buffer.position –  not thread-safe

§ Resource deallocation –  GC-based (Cleaner) memory management

Page 99: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

99 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.Buffer

§ < 2GiB –  ByteBuffer.allocateDirect(int size)

§ Stateful –  Buffer.position –  not thread-safe

§ Resource deallocation –  GC-based (Cleaner) memory management

§ Zeroing –  on initialization

Page 100: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

100 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.Buffer

§ < 2GiB –  ByteBuffer.allocateDirect(int size)

§ Stateful –  Buffer.position –  not thread-safe

§ Resource deallocation –  GC-based (Cleaner) memory management

§ Zeroing –  on initialization

§ Bounds checking

Page 101: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

101 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe Anti-JNI

Page 102: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

102 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe

Use case Example methods

Concurrency primitives compareAndSwap*

Serialization allocateInstance

Efficient memory management, layout, and access

allocateMemory/freeMemory get*/put*

Interoperate across the JVM boundary get*/put*

… …

Page 103: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

103 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe

§ Unsafe.get*/put* –  getInt(Object base, long offset) –  putInt(Object base, long offset, int value);

Page 104: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

104 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe

§ Unsafe.get*/put* –  getInt(Object base, long offset) –  putInt(Object base, long offset, int value);

§ double-register addressing mode –  getInt(o, offset) == o + offset –  getInt(null, address) == address

Page 105: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

105 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe

§ Unsafe.get*/put* –  getInt(Object base, long offset) –  putInt(Object base, long offset, int value);

§ double-register addressing mode –  getInt(o, offset) == o + offset –  getInt(null, address) == address

§  long allocateMemory(long size) void freeMemory(long address)

Page 106: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

106 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.DirectByteBuffer

longbuf=UNSAFE.allocateMemory(size);LAPACK.square(buf,size);for(longl=0;l<size;l=+4){inti=UNSAFE.getInt(null,buf+l);}

Usage

Page 107: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

107 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

UNSAFE.putInt(new Object(), 0L, 0)

Page 108: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

108 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

UNSAFE.putInt(null, 0L, 0)

Page 109: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

109 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Object UNSAFE.getObject(long address)

Page 110: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

110 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

long UNSAFE.getAddress(long address)

Page 111: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

111 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe =?= Fast

Page 112: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

112 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

Page 113: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

113 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

public native Object allocateInstance(Class<?> cls) throws …;

Page 114: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

114 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

long[]base=newlong[…];intidx=…;

Array index vs Raw offset

Page 115: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

115 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

long[]base=newlong[…];intidx=…;//“Naïve”versionlongvalue=base[idx];

Array index vs Raw offset

Page 116: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

116 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

long[]base=newlong[…];intidx=…;//“Naïve”versionlongvalue=base[idx];//Highlyoptimizedlongoffset=(((long)idx)<<SCALE+OFFSET)longvalue=Unsafe.getLong(base,offset);

Array index vs Raw offset

Page 117: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

117 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

long[]base=newlong[…];intidx=…;//“Naïve”versionlongvalue=base[idx];//Highlyoptimizedlongoffset=(((long)idx)<<SCALE+OFFSET)longvalue=Unsafe.getLong(base,offset);

Array index vs Raw offset: 32-bit platform

Page 118: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

118 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Unsafe != Fast

§ Missing optimizations –  JDK-8078629: “VM should constant fold Unsafe.get*() loads from final fields”

Page 119: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

119 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

- How many of you have used the Unsafe API? …

John Rose, JVM Architect, Oracle JVM Language Summit 2014

119

Page 120: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

120 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

- How many of you have used the Unsafe API? …

- A lot of you. Gosh. I'm sorry.

John Rose, JVM Architect, Oracle JVM Language Summit 2014

120

Page 121: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

121 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Page 122: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

122 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe

Use case Example methods

Concurrency primitives compareAndSwap*

Serialization allocateInstance (ReflectionFactory.newConstructorForSerialization)

Efficient memory management, layout, and access

allocateMemory/freeMemory get*/put*

Interoperate across the JVM boundary

get*/put*

Page 123: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

123 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

sun.misc.Unsafe

Use case Replacement

Concurrency primitives JEP 193 Variable Handles

Serialization Reboot JEP 187 Serialization Improvements

Efficient memory management, layout, and access

Project Panama, Project Valhalla, Arrays 2.0, Better GC

Interoperate across the JVM boundary

Project Panama, JEP 191 Foreign Function Interface

Page 124: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

124 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.lang.invoke.

VarHandle @since 9

JEP 193: Variable Handles

Page 125: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

125 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

VarHandle

MethodHandles.Lookup:VarHandlebyteBufferViewVarHandle(Class<?>viewArrayClass,booleanbigEndian){…}

“Produces a VarHandle giving access to elements of a ByteBuffer viewed as if it were an array of elements of a different primitive component type to that of byte, such as int[] or long[].”

ByteBuffer View

Page 126: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

126 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

VarHandle

VarHandleVH=MethodHandles.byteBufferViewVarHandle(int[].class,ByteOrder.nativeOrder()==ByteOrder.BIG_ENDIAN);ByteBuffer dbb = ByteBuffer.allocateDirect(size); int v = (int)VH.get(dbb, idx);

ByteBuffer View

Page 127: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

127 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

java.nio.ByteBuffer vs VarHandle View

DirectByteBuffer VarHandle Size < 2 GiB < 2 GiB State Yes No Resource management GC-based No (delegates to DBB) Zeroing Yes No (delegates to DBB) Atomics/Fences/… No Yes Bound checks Yes (optimized) Yes (optimized)

Page 128: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

128 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimized Bounds Checks

//nullcheck+(indexu<array.length)returnarray[index];

int[]

Page 129: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

129 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimized Bounds Checks

//boundsandnullcheckif(index<0||index>=array.length)thrownew…();longoffset=BASE+(((long)index)<<2);returnUNSAFE.getInt(array,offset);

int[]: Unsafe access

Page 130: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

130 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Optimized Bounds Checks

//bounds(u<)andnullcheckindex=Objects.checkIndex(index,array.length);longoffset=BASE+(((long)index)<<2);returnUNSAFE.getInt(array,offset);

@HotSpotIntrinsicCandidatepublicstaticintcheckIndex(intindex,intlength,…);

int[]: Unsafe access

Page 131: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

131 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Summary

§ Existing –  Java Native Interface (JNI) & JNR library –  java.nio.DirectByteBuffer –  sun.misc.Unsafe (get*/set*)

§  JDK9 –  j.l.i.VarHandle views over ByteBuffers

§ Future –  Project Panama

Page 132: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

132 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

http://openjdk.java.net

Project Panama Foreign Function Interface Data Layout Control Vector API Arrays 2.0

Page 133: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

133 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

http://openjdk.java.net

Project Panama [email protected]://hg.openjdk.java.net/panama/panama

Page 134: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

134 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Safe Harbor Statement

The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.

Page 135: Working with Native Libraries in Javacr.openjdk.java.net/~vlivanov/talks/2016_Joker_NativeCode.pdf · – Native types are unsafe, so trusted code must manage the bits § Solution

135 Copyright © 2016, Oracle and/or its affiliates. All rights reserved

Graphic Section Divider