Assembly 为什么热点生成的编译方法在执行前将eax隐藏在堆栈的较高位置?

Assembly 为什么热点生成的编译方法在执行前将eax隐藏在堆栈的较高位置?,assembly,jvm,jvm-hotspot,Assembly,Jvm,Jvm Hotspot,当查看从OpenJDK的热点生成的汇编代码时,序言中有一部分将%eax值复制到堆栈更高的位置(rsp-0x14000),我不明白它为什么这样做: [Disassembling for mach='i386:x86-64'] [Entry Point] [Verified Entry Point] [Constants] # {method} {0x0000000120f0f410} 'add' '(JJ)J' in 'Test' # parm0: rsi:rsi = long

当查看从OpenJDK的热点生成的汇编代码时,序言中有一部分将
%eax
值复制到堆栈更高的位置
(rsp-0x14000)
,我不明白它为什么这样做:

[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')}
相同的地址似乎用于不同编译方法的许多其他赋值,我还没有看到从何处读取该内存位置:

# {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代码生成:

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;
  }
}
我使用的Java版本是:

$ 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)
在OSX 10.11.4上

$ 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

有人能解释一下这是在做什么,以及它是否会引起对该地址的争用?我在不同的JVM和不同的示例中看到了用于偏移量的不同数字,但当我看到它被使用时,同一会话中JVM的所有调用的数字都保持不变

它被称为。我找不到太多关于细节的文档,但粗略的谷歌搜索表明它有多种用途,例如,通过页面错误处理程序通知VM堆栈增长的需要,并确保它有足够的空间来处理内部事件,如方法去优化或在出现SOE或OOME等异步异常时展开堆栈。

我只能猜测它正试图出于任何原因预增长堆栈。这不太可能引起争论(和什么?)。线程不共享堆栈。术语:在x86上,堆栈向下增长,因此
%rsp
下面的地址未使用。因此,
rsp-0x14000
位于堆栈指针的“下方”,而不是上方。还要注意。我知道OP是在OSX上运行的。好吧,jvm安装了保护页并有一个sigsegv处理程序。所以我想这两种方法都有效。
$ 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