Javaforum indy
description
Transcript of Javaforum indy
1
2
The following 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.
<Insert Picture Here>
invokedynamic på 20 minuter
Joel Borggrén-Franck <[email protected]>
Java Platform Group
4
<Insert Picture Here>
Intro till JSR-292: invokedynamic,
MethodHandle och dynamiskt typade
språk på JVM:en
• Varför JSR-292/invokedynamic?
• Vad erbjuder JSR-292?
• Dynamiskt typade exempel och jämförelser med vad
JVM:en kan göra av Java
5
Warning!
The following slides may contain traces of:
- x86 assembler
- Ruby, and
- Common Lisp
6
• Det finns en mängd intressanta programmeringsspråk
• JVM:en är långt mycket mer avancerad än andra
VM:ar/runtimes
• Java är inte allas favoritspråk
• Naturligvis vill man köra alla nya spännande språk på
JVM:en
7
• Dynamiskt typade språk:
– Modifierar klasser vid körtid
– Alternativt, saknar klasser och lägger till properties i körtid
class ExampleClass
def exampleMethod
5
end
end
exampleObject.class.send(:define_method,
"aNewMethod") do
10
end
8
• Motsvarigheten i Java finns egentligen inte
– Den naiva implementationen blir istället en Map<String,
TargetMethodObject>
• Mer eller mindre avancerade sätt att optimera
ovanstående
– JRuby har sina fält i en Object[] och en Map<String, Integer>
där du slår upp vilket index du ska använda in i arrayen
9
• Dynamiskt typade språk:
– har ofta inkompatibla sätt att definera/anropa metoder
(defun foo
(var...
&optional (var initform svar)...
&rest var
&key ((keyword var) initform svar)...
&aux (var initform)...))
10
• Man kan arbeta runt problemen
• Ett av de få verktyg man har är
klassladdning/klassurladdning
– leder till permgen-problem på HotSpot
• Det tar tid att implementera
– om man vill få det att gå fort
11
Invokedynamic, en språkimplementatörs räddare i
nöden
• Invokedynamic är en brygga mellan
språkimplementatören och JVM:en
• Invokedynamic består av 3 delar
– en ny bytekod som markerar ett dynamiskt CallSite
– ett protokoll/API för livscykeln av dynamiska CallSites
– MethodHandle
• funktionspekare på sterodier
12
• Första gången JVM:en exekverar en invokedynamic
bytekod kommer den:
– Hitta och köra den bootstrapmetod som skaparen av
klassfilen angett
• resulterar i ett CallSite-objekt som har ett MethodHandle
som target
– Länka CallSite-objektet
• Ovanstående görs bara en gång
• Efterföljande körningar av samma invokedynamic
kommer helt skippa bootstrap och länkning
• == Snabbt!!
13
aload 0x25
dup
invokedynamic 0x22 0x23
getfield 0xba 0xdd
Bootstrap methodCallSite object
target MethodHandle
14
• En invokedynamic kommer alltid att motsvaras av
samma CallSite
• Ett CallSite kan ändra target till att peka på en ny
MethodHandle
• Om du kan uttrycka ditt språks semantik som CallSite
+ en utbytbar MethodHandle kommer det gå fort!
15
MethodHandles is the kitchen sink of the JVM
- Dan Heidinga, JVM Lang 2010
• MethodHandle är i grund och botten en
funktionspekare
• Pekas normalt ut som target i en CallSite
• Kan också köras genom ett Java-API
• Hjälpklassen ”MethodHandles” har metoder för att
– Wrappa MethodHandle i andra MethodHandle
– Transformera argumenten på ett MethodHandle
– Köra kod runt en MethodHandle
16
• MethodHandle kan också peka ut fält
• Användbart för lat initialisering av en gigantisk array
– Wrappa arrayaccessen i ett MethodHandle som transparent
initialiserar den
– Generera bytecode som kör MethodHandlet för den
wrappade arrayen istället för den vanliga ”aref”-bytekoden
17
• MethodHandle kan också transformera argument
– asCollector(…)
– asFixedArity(…)
– asSpreader(…)
– …
• Och byta returtyp
– asType(newType)
18
• MethodHandles.Lookup har också stöd för att
reflektera över typer
• Användbart för det mesta man vill göra med reflection
• Fast snabbt
19
• JVM:en vet hur den skall optimera MethodHandle
• Igen: Kan du bara uttrycka ditt språks semantik som
CallSite + en utbytbar MethodHandle kommer det gå
fort!
20
• Ett call i Java kommer kompileras till:
– Slå upp objektets vtable (en del av klassen)
– Kör koden som pekas ut på en vid just-in-time-kompilering
känd plats i vtablen
• 2 instruktioner + ev. några cachemissar
• == Snabbt!
moveq r12, [rdi + 0x128] ;get vtable for ”this”
callq [r12+0x12] ;call 3:rd method
Exempel: ett vanligt metodanrop i Java
21
• Motsvarande logik för ett dynamiskt typat språk utan
invokedynamic:
String methodName;
CallTarget t;
for(RubyClazz clz : o.getClzAndSuperClzs()) {
if ((t = clz.hasMethod(methodName)) != null)
break;
}
if (t == null) throw new NoSuchRubyMethod();
Exempel: ett metodanrop i fiktiv Ruby på JVM:en
22
• Låt bootstrapmetoden returnera ett MethodHandle:MethodHandle lastCalled;
int rubyClzId;
if (receiver.currentRubyClzId == rubyClzId) {
return lastCalled.invoke(args …);
} else {
missCount++;
MethodHandle t = doFulLookup(mName, args…);
if (missCount > MISS_LIMIT) {
relinkThisCallSite(t);
}
return t.invoke();
}
Exempel: med invokedynamic …
23
• Bootstrapmetoden får leta reda på den
implementerande ruby-metoden
• Wrappa i ett MethodHandle som
– Testar om det är samma implementerande ruby-klass
– Testar om det är samma version av ruby-klassen
• Så länge det är samma implementerande klass
kommer JVM:en kunna kompilera till en handfull
instruktioner
• Det är nästan alltid samma implementerande klass!
• Om det inte är samma klass kan din ruby-VM begära
omlänkning via CallSite-objektet!
Exempel: med invokedynamic …
24
• == Snabbt!!
25
• Invokedynamic hjälper dig som språkimplementatör:
– Kommunicera ditt språks speciella semantik till VM:en
– Återanvända VM:ens maskineri för
• Optimeringar
• Deoptimeringar
– Hjälper dig att transformera semantiken i ditt språks
objektsystem till något som JVM:en kan använda
26