2016-04-08 20 views
3

OpenJDK en HotSpot oluşturulan derleme kodu bakarak, o daha da yığının (rsp-0x14000) kadar kopyalar bir konuma %eax değerini prolog parçası olduğunu, ve bunun böyle yapıyor anlamıyorum niye:Neden hotspot, derlenmiş yöntemler derlenmiş?

[Disassembling for mach='i386:x86-64'] 
[Entry Point] 
[Verified Entry Point] 
[Constants] 
    # {method} {0x0000000120f0f410} 'add' '(JJ)J' in 'Test' 
    # parm0: rsi:rsi = long 
    # parm1: rdx:rdx = long 
    #   [sp+0x40] (sp of caller) 
    0x000000010cd8a3e0: mov %eax,-0x14000(%rsp) 
    0x000000010cd8a3e7: push %rbp 
    0x000000010cd8a3e8: sub $0x30,%rsp 
    0x000000010cd8a3ec: movabs $0x120f0f5d0,%rax 
    ; {metadata(method data for {method} {...} 'add' '(JJ)J' in 'Test')} 

Bu aynı adres farklı derlenmiş yöntemleri için diğer atamaları bir dizi için kullanılacak gibi görünüyor ve bu bellek konumu okunur nerede görmedim:

# {method} {0x0000000120000090} 'indexOf' '(I)I' in 'java/lang/String' 
[Verified Entry Point] 
0x000000010c29bfa0: mov DWORD PTR [rsp-0x14000],eax 
... 
# {method} {0x00000001203fb410} 'add' '(JJ)J' in 'Test' 
[Verified Entry Point] 
0x000000010c29c3a0: mov DWORD PTR [rsp-0x14000],eax 

Java kod parçası bu üretme ediyorum :

public class Test { 
    public static void main(String args[]) { 
    long total = 0; 
    for(int i=0;i<20_000;i++) { 
     total = add(total,i); 
    } 
    System.out.println("Total is: " + total); 
    } 
    public static long add(long a, long b) { 
    return a+b; 
    } 
} 

ve ben birlikte bu çalıştırıyorum:

$ java -XX:CompileCommand=print,*.* Test 

kullanıyorum Java sürümü:

$ java -version 
java version "1.8.0_74" 
Java(TM) SE Runtime Environment (build 1.8.0_74-b02) 
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode) 

ve OSX 10.11.4 üzerinde

$ uname -a 
Darwin alblue.local 15.4.0 Darwin Kernel Version 15.4.0: Fri Feb 26 22:08:05 PST 2016; root:xnu-3248.40.184~3/RELEASE_X86_64 x86_64 
var

Bunun ne yaptığını ve bu eklenti için çekişme yazmasına neden olup olmayacağını açıklayabilir mi? ess? Farklı JVM'lerde ofset için farklı sayılar kullandım ve farklı örnekler gördüm, fakat kullanıldığını gördüğümde, aynı oturumda JVM'nin tüm çağrışımları için sayı sabit kalmıştır.

+0

Sadece yığını neden her ne olursa olsun önceden büyütmeye çalıştığını tahmin edebilirim. Bir çekişmeye neden olması olası değil (ne ile?). Konular yığın paylaşmaz. – Jester

+2

terminoloji: x86'da yığın aşağı doğru büyür, bu nedenle aşağıdaki '% rsp' adresleri kullanılmaz. Böylece "rsp-0x14000", üstündeki değil, yığın işaretçisinin "altında" dır. –

cevap

1

O stackbanging denir. Ayrıntılar hakkında fazla doküman bulamıyorum, ancak çirkin bir google araması, yığın büyümesi gereksinimi hakkında VM'yi bir sayfa hata işleyicisi aracılığıyla bilgilendirmek ve iç olaylara ilişkin iç mekan etkinlikleri için yeterli alan olmasını sağlamak gibi çeşitli amaçlara hizmet ettiğini gösterir. SOE veya OOME gibi asenkron istisnalar durumunda yığının deoptimizasyonu veya istendiğinde çözülmesi.

+1

da [Linux bu, yığın gelişmez bunun yerine, arızalar] dikkat (https://github.com/torvalds/linux/blob/643ad15d47410d37d43daf3ef1c8ac52c281efa5/arch/x86/mm/fault.c#L1320). OP'nin muhtemelen çalıştığı OSX'de olduğunu anlıyorum. – Jester

+1

iyi, jvm güvenlik sayfalarını yükler ve bir sigsegv işleyicisi vardır. Yani sanırım her iki şekilde çalışıyor. – the8472

İlgili konular