2013-03-11 15 views
5

私はJavaで非常に愚かなテストクラスを書いた:印刷のJavaホットスポットJITアセンブリコード

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) ; 
    } 
} 

その後、私はJavaのホットスポットJITによって生成されたコードを見てみたかった(クライアントVMは23.7-B01を構築します)。私は "-XX:+ PrintAssembly"オプションとhsdis-i386.dllをhttp://classparser.blogspot.dk/2010/03/hsdis-i386dll.htmlから

ここでは、私は新しいオブジェクトの初期化をスキップしました。 substメソッド)。明らかに、ebxは "this"ポインタであり、edxは引数へのポインタです。

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 

正直なところ、私はx86アセンブリにはあまりよく似ていませんが、そのコードはあなたにとって理にかなっていますか? "adc BYTE PTR [edx + 8]、cl"のような奇妙な命令は何ですか?私はいくつかのFPU命令を期待していたでしょう。

+0

あなたの質問に 'assembly'タグを付けると、より良い回答が得られるかもしれません。 – assylias

+0

私には、このアセンブリコードは理にかなっていません。私はこれがHotSpotによって生成された実際の実行可能コードであるとは思わない。 – NPE

+3

逆アセンブラがマシンコードを正しく解釈できないと思われます。 'LDS'のオペコードは' 0xc5'ですが、新しいx86 CPUでは[2バイトのVEXプレフィックス](http://wiki.osdev.org/X86-64_Instruction_Encoding#VEX.2FXOP_opcodes)でもかまいません。 – Michael

答えて

6

もう一度。私は最新のbinutils 2.23を使ってhsdis-i386.dllをビルドしました。 (少なくとも、x86バージョンの64ビット版はコンパイルが、JVMは、すべてのエラーメッセージなしですぐに停止します。)私はhttp://dropzone.nfshost.com/hsdis.htm の指示のおかげで予想以上に簡単だった

出力は今非常に良く見える:

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

それは*たくさんの可能性があります*(+1) – NPE

+0

確かに私は単純なraytracerをプログラムしました。この機能のおかげでJITがどのように機能するか見てうれしいです。 Vector3のようなクラスは、サブクラスを持たないため完全にインライン化されています。 SSE2拡張は、「スーパーFPU」の一種として使用されます。もう少し残念なことに、Vector3のコンストラクタでは、JITコードは常に、 "new Vector3(xv.x、yv.y、zv.z)"であってもthis.x、this.y、this.zを0.0に設定します。 "それぞれ8バイトの3つの不要なメモリアクセス。 – trunklop

+0

答えを投稿する時間を取るためによくできました。 – NPE