DNAD 2013


DynLang Design

for the JVM

@qmx - blog.qmx.me

whoami

dynjs
# disclaimer

JVM

JVM?

Java?

I've got 99 problems

Java ain't one

CPU

movl   %eax, -36(%rbp)

register-based

JVM

stack-based

Virtual Machine

1+2 = ?

(+ 1 2)

ZOMG, lisp???

le stack

PUSH 1
  • 1
PUSH 2
  • 1
  • 2
ADD
  • 3

le stack - bytecode

iconst_1
  • 1
iconst_2
  • 1
  • 2
iadd
  • 3

bytecode?

iadd?

integer add

^^^^------

statically typed

1 + 2

is 1 an integer?

NO

					> 1.class
=> Fixnum
					

OO

taken to the next level

1+2

						1.+(2)
					

1+2

						1.send(:+, 2)
					

writing this in Java

						
IRubyObject +(IRubyObject o){}
						
					

syntax error

Java

Y U NO

OPERATOR OVERLOADING

we <3 Java

but

Java (language) is

limited

(and that's ok)

writing this in Java

						
IRubyObject op_plus(IRubyObject o){}
						
					

verbose

1 + 2

						
IRubyObject x  = // 1
IRubyObject y = // 2
x.op_plus(y);
					
					

IRubyObject?

everything is an object

Java

Virtual Machine

requires

ALL THE TYPES

during compilation

LOLJava


Yay C#?

JVM

AOT vs JIT

speaker notes remind me to troll the CLR

optimize

GUESS?

Here be Dragons

IR

flowGRAPH

we know this!?

Flattening graphs like a BOSS

S tatic S ingle

A ssignment

Maths?

E scape A nalysis

Java

Y U NO

UNSIGNED

Case Study:


Ruby Numb3rs

Ruby Numb3rs


1.9.3-p362 :010 > (2**2**5).class
=> Fixnum
1.9.3-p362 :011 > (4**2**5).class
=> Bignum
					

Java

Y U NO

V-FLAG

D ead C ode E limination

G lobal V ariable

N umbering

LICM

ERMAHGERD

back!

do you know

where

methods live?

Object.methods()

classes!

so

{:+ => #<Object:0x007f95329a4510>, ...}

map!

back to Java

let's call it

						IRubyObject x = //;
x.+(); // fails
x.callMethod(context, "+"); // works

					

what's happening here?

steps

  1. get the object
  2. hash lookup
  3. context lookup
  4. actual invocation
  5. profit?

what if...?

we could teach

the JVM

on how to reach the method instance we want?

what if...?

we could give

the JVM

more hints about the code it runs?

invokedynamic

bytecode

method handles

bootstrap method

target method

MethodHandles

int (*foo)(int)

good ol' pointers

bytecode

bytecode - standard invoke

						INVOKEVIRTUAL #39, #42
					

#39 is method name, #42 is the signature with types

bytecode - invokedynamic

						INVOKEDYNAMIC name, #42, BSM, BSM_SIG
					

Bootstrap Method

returns a CallSite

a CallSite has a

Method Handle

which points to the

TargetMethod

magic?

invokedynamic's

friends

SwitchPoint

case study: Ruby inconstants

Ruby inconstants


1.9.3-p362 :001 > THING="hello"
 => "hello"
1.9.3-p362 :002 > THING="hellow"
(irb):2: warning: already initialized constant THING
 => "hellow"
					

invokedynamic

partial solution

a new approach rises

METACIRCULAR

YO DAWG

Maxine VM

peeking on hotspot guts

Graal VM

language runtime framework

Truffle

Appendix A

Useful tools

bytecode

jitescript

internal DSL for bytecode generation

jitescript

defineMethod("main",..,sig),
new CodeBlock() {{
 ldc("helloWorld");
 getstatic(p(System.class), "out", ci(PrintStream.class));
 swap();
 invokevirtual(p(PrintStream.class), "println", sig(void.class, Object.class));
 voidreturn();
}});

invokebinder

(MethodHandle API for mortals)

rephract

JNR

Appendix B

Pain points to avoid

GC pressure

code size limits

leaks!

Appendix C

Wishlist

unsigned types

proper tail call support

V-FLAG

?

thanks!