2013-03-11 1 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 Hotspot JIT (Client VM построить 23,7-b01). Я использовал опцию «-XX: + PrintAssembly» и hsdis-i386.dll от http://classparser.blogspot.dk/2010/03/hsdis-i386dll.html

Вот интересная часть сгенерированного кода (я пропустил инициализацию нового объекта. EDIT: код для subst). Очевидно, ebx является «этим» указателем, а 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', но это также может быть [2-байтовый префикс VEX] (http://wiki.osdev.org/X86-64_Instruction_Encoding#VEX.2FXOP_opcodes) на новых процессорах x86. – Michael

ответ

6

Me again. Я построил hsdis-i386.dll, используя последнюю версию binutils 2.23. Это было легче, чем я ожидал, благодаря инструкциям в http://dropzone.nfshost.com/hsdis.htm

Выход теперь выглядит намного лучше (по крайней мере, для версии x86 64-разрядная версия компилирует, но сразу же останавливает JVM без сообщения об ошибке.):

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 всегда сначала устанавливает this.x, this.y, this.z в 0.0, даже в «new Vector3 (xv.x, yv.y, zv.z) ». Три ненужных обращения к памяти по 8 байт. – trunklop

+0

Удивительный. Хорошо сделано, чтобы найти время, чтобы опубликовать ответ. – NPE