2013-03-11 16 views
5

Napisałem bardzo głupiego klasę testową w Javie:druk Java hotspot JIT kod montaż

public class Vector3 { 
    public double x,y,z ; 

    public Vector3(double x, double y, double z) { 
     this.x=x ; this.y=y ; this.z=z ; 
    } 

    public Vector3 subst(Vector3 v) { 
     return new Vector3(x-v.x,y-v.y,z-v.z) ; 
    } 
} 

Potem chciałem zobaczyć kod wygenerowany przez Java Hotspot VM JIT (klient zbudować 23,7-B01). Użyłem opcji "-XX: + PrintAssembly" i pliku hsdis-i386.dll z http://classparser.blogspot.dk/2010/03/hsdis-i386dll.html

Oto interesująca część wygenerowanego kodu (pominąłem inicjalizację nowego obiektu. EDYCJA: kod dla metoda subst). Oczywiście ebx jest "tym" wskaźnikiem, a edx jest wskaźnikiem do argumentu.

lds edi,(bad) 
sti  
adc BYTE PTR [ebx+8],al ;*getfield x 
mov edx,DWORD PTR [esp+56] 
lds edi,(bad)   ; implicit exception: dispatches to 0x02611f2d 
sti  
adc BYTE PTR [edx+8],cl ;*getfield x 
lds edi,(bad) 
sti  
adc BYTE PTR [ebx+16],dl ;*getfield y 
lds edi,(bad) 
sti  
adc BYTE PTR [edx+16],bl ;*getfield y 
lds edi,(bad) 
sti  
adc BYTE PTR [ebx+24],ah ;*getfield z 
lds edi,(bad) 
sti  
adc BYTE PTR [edx+24],ch ;*getfield z 
lds edi,(bad) 
sti  
pop esp 
rol ebp,0xfb 
adc DWORD PTR [eax+8],eax ;*putfield x 
lds ebp,(bad) 
jmp 0x02611f66 
rol ebp,cl 
sti  
adc DWORD PTR [eax+16],edx ;*putfield y 
lds ebx,(bad) 
fistp DWORD PTR [ebp-59] 
sti  
adc DWORD PTR [eax+24],esp ;*putfield z 

Szczerze mówiąc, nie jestem bardzo znany z montażu x86, ale czy ten kod ma dla ciebie sens? Co robią te dziwne instrukcje, takie jak "adc BYTE PTR [edx + 8], cl"? Spodziewałbym się niektórych instrukcji FPU.

+0

Możesz uzyskać lepsze odpowiedzi, jeśli otagujesz swoje pytanie "montaż". – assylias

+0

Dla mnie ten kod montażu nie ma sensu. Wątpię, czy jest to rzeczywisty kod wykonywalny generowany przez HotSpot. – NPE

+3

Podejrzewam, że twój dezasembler nie jest w stanie prawidłowo interpretować kodu maszyny. Opodem dla 'LDS' jest' 0xc5', ale może to być również [2-bajtowy prefiks VEX] (http://wiki.osdev.org/X86-64_Instruction_Encoding#VEX.2FXOP_opcodes) na nowszych procesorach x86. – Michael

Odpowiedz

6

Ja znowu. Zbudowałem hsdis-i386.dll przy użyciu najnowszej wersji binutils 2.23. Było łatwiej niż się spodziewałem dzięki instrukcję http://dropzone.nfshost.com/hsdis.htm

Wyjście wygląda teraz znacznie lepiej (przynajmniej dla wersji x86 w wersji 64-bitowej kompiluje ale zatrzymuje JVM natychmiast bez żadnego komunikatu o błędzie.):

vmovsd xmm0,QWORD PTR [ebx+0x8] ;*getfield x 
mov edx,DWORD PTR [esp+0x40] 
vmovsd xmm1,QWORD PTR [edx+0x8] ;*getfield x 
vmovsd xmm2,QWORD PTR [ebx+0x10] ;*getfield y 
vmovsd xmm3,QWORD PTR [edx+0x10] ;*getfield y 
vmovsd xmm4,QWORD PTR [ebx+0x18] ;*getfield z 
vmovsd xmm5,QWORD PTR [edx+0x18] ;*getfield z 
vsubsd xmm0,xmm0,xmm1 
vmovsd QWORD PTR [eax+0x8],xmm0 ;*putfield x 
vsubsd xmm2,xmm2,xmm3 
vmovsd QWORD PTR [eax+0x10],xmm2 ;*putfield y 
vsubsd xmm4,xmm4,xmm5 
vmovsd QWORD PTR [eax+0x18],xmm4 ;*putfield z 
+0

To wygląda * dużo * bardziej wiarygodne (+1) – NPE

+0

Rzeczywiście :) Zaprogramowałem prosty raytracer i miło jest zobaczyć, jak działa JIT dzięki tej funkcji. Klasy takie jak Vector3 są całkowicie inline, ponieważ nie mają podklas. Rozszerzenia SSE2 są używane jako rodzaj "super FPU". Coś trochę rozczarowującego: w konstruktorze Vector3, kod JIT zawsze ustawia najpierw ten.x, this.y, this.z na 0.0, nawet w "nowym Vector3 (xv.x, yv.y, zv.z) ". Trzy niepotrzebne dostępy do pamięci po 8 bajtów. – trunklop

+0

Awesome. Dobra robota za poświęcenie czasu na opublikowanie odpowiedzi. – NPE