печать кода сборки JIT точки доступа Java

Я написал очень тупой тестовый класс на Java:

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

Затем я хотел увидеть код, сгенерированный JIT-версией Java Hotspot (сборка клиентской виртуальной машины 23.7-b01). Я использовал параметр -XX: + PrintAssembly и hsdis-i386.dll из http://classparser.blogspot.dk/2010/03/hsdis-i386dll.html

Вот интересная часть сгенерированного кода (я пропустил инициализацию нового объекта. EDIT: код для метода 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.


person trunklop    schedule 11.03.2013    source источник
comment
Вы можете получить более точные ответы, если пометите свой вопрос assembly.   -  person assylias    schedule 11.03.2013
comment
Для меня этот ассемблерный код не имеет смысла. Я сомневаюсь, что это реальный исполняемый код, сгенерированный HotSpot.   -  person NPE    schedule 11.03.2013
comment
Я подозреваю, что ваш дизассемблер не может правильно интерпретировать машинный код. Код операции для LDS - 0xc5, но это также может быть 2-байтовый префикс VEX на новых процессорах x86.   -  person Michael    schedule 11.03.2013
comment
Спасибо за ответы. Напрашивается вывод, что используемый в dll дизассемблер некорректно декодирует сгенерированный код. Я попытаюсь собрать dll самостоятельно, следуя инструкциям на странице dropzone.nfshost.com/hsdis.htm   -  person trunklop    schedule 11.03.2013
comment
Пожалуйста, ответьте на решение, которое вы нашли, и примите его, чтобы люди сразу увидели, что этот вопрос решен. Это поможет другим, кто может столкнуться с подобными проблемами.   -  person nrz    schedule 11.03.2013


Ответы (1)


Мне еще раз. Я создал 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
person trunklop    schedule 12.03.2013
comment
Это выглядит намного более правдоподобным (+1) - person NPE; 12.03.2013
comment
Действительно :) Я запрограммировал простой трассировщик лучей, и мне приятно видеть, как работает JIT благодаря этой функции. Такие классы, как Vector3, полностью встроены, поскольку у них нет подклассов. Расширения SSE2 используются как своего рода супер-FPU. Что-то немного разочаровывает: в конструкторе Vector3 JIT-код всегда сначала устанавливает this.x, this.y, this.z равным 0.0, даже в новом Vector3 (x-v.x, y-v.y, z-v.z). Три ненужных доступа к памяти по 8 байт каждый. - person trunklop; 12.03.2013