2013-03-11 29 views
5

Tôi đã viết một lớp thử nghiệm rất ngu ngốc trong Java:in Java hotspot JIT lắp ráp đang

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

Sau đó, tôi muốn nhìn thấy mã được tạo ra bởi Java Hotspot JIT (Client VM xây dựng 23,7-b01). Tôi đã sử dụng tùy chọn "-XX: + PrintAssembly" và hsdis-i386.dll từ http://classparser.blogspot.dk/2010/03/hsdis-i386dll.html

Đây là phần thú vị của mã được tạo ra (tôi đã bỏ qua việc khởi tạo đối tượng mới. EDIT: mã cho phương thức subst). Rõ ràng, ebx là con trỏ "this" và edx là con trỏ tới đối số.

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 

Thành thật mà nói, tôi không rất hài lòng với lắp ráp x86 nhưng mã đó có hợp lý với bạn không? Những hướng dẫn lạ như "adc BYTE PTR [edx + 8], cl" đang làm gì? Tôi đã mong đợi một số hướng dẫn của FPU.

+0

Bạn có thể nhận được câu trả lời tốt hơn nếu bạn gắn thẻ câu hỏi 'assembly'. – assylias

+0

Với tôi, mã lắp ráp này không có ý nghĩa gì cả. Tôi nghi ngờ đây là mã thực thi thực tế được tạo bởi HotSpot. – NPE

+3

Tôi nghi ngờ rằng bộ tách rời của bạn không thể diễn giải chính xác mã máy. Mã opcode cho 'LDS' là' 0xc5', nhưng đó cũng có thể là [tiền tố VEX 2 byte] (http://wiki.osdev.org/X86-64_Instruction_Encoding#VEX.2FXOP_opcodes) trên các CPU x86 mới hơn. – Michael

Trả lời

6

Tôi một lần nữa. Tôi đã xây dựng hsdis-i386.dll bằng cách sử dụng các binutils mới nhất 2.23. Đó là dễ dàng hơn tôi mong đợi nhờ vào sự hướng dẫn trong http://dropzone.nfshost.com/hsdis.htm

Sản lượng hiện nay trông đẹp hơn nhiều (ít nhất là trong phiên bản x86 Phiên bản 64-bit biên dịch nhưng dừng JVM ngay mà không cần bất kỳ thông báo lỗi.):

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

Điều đó có vẻ * rất nhiều * đáng tin cậy hơn (+1) – NPE

+0

Thật vậy :) Tôi đã lập trình một bộ tạo tia đơn giản và thật tuyệt khi xem JIT hoạt động như thế nào nhờ tính năng này. Các lớp như Vector3 hoàn toàn được gạch chân vì chúng không có lớp con. Các phần mở rộng SSE2 được sử dụng như một loại "siêu FPU". Một cái gì đó một chút thất vọng: trong constructor của Vector3, mã JIT luôn luôn đặt this.x, this.y, this.z thành 0.0, ngay cả trong "new Vector3 (xv.x, yv.y, zv.z) ". Ba truy cập bộ nhớ không cần thiết của 8 byte mỗi bộ nhớ. – trunklop

+0

Tuyệt vời. Thực hiện tốt việc dành thời gian để đăng câu trả lời. – NPE