为什么hotspot生成的已编译方法在执行之前将eax隐匿在堆栈的上方? [英] Why do hotspot generated compiled methods stash eax high up the stack before execution?

查看:58
本文介绍了为什么hotspot生成的已编译方法在执行之前将eax隐匿在堆栈的上方?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When looking at generated assembly code from OpenJDK's HotSpot, there is part of the prologue that copies the %eax value to a location further up the stack (rsp-0x14000), and I don't understand why it's doing that:

[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')}

这个地址似乎用于不同编译方法的许多其他赋值,而且我还没有看到从哪里读取该内存位置:

This same address seems to be used for a number of other assignments for different compiled methods, and I've not seen where that memory location is read from:

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

I'm generating this from this piece of Java code:

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

我正在用以下方法运行它:

and I'm running this with:

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

我正在使用的Java版本是:

The version of Java I'm using is:

$ 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上

and it's on 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的调用都保持不变.

Can anyone explain what this is doing, and whether it would cause contention writing to that address? I've seen different numbers used for the offset in different JVMs and with different examples, but when I have seen it being used the number has remained constant for all invocations of the JVM in the same session.

推荐答案

它称为

It's called stackbanging. I can't find much documentation on the details, but a cursory google search indicates that it serves several purposes, such as notifying the VM through a page fault handler about the need for stack growth and ensuring it has enough headroom for internal events such as method deoptimization or unwinding the stack in case of asynchronous exceptions such as SOE or OOME.

这篇关于为什么hotspot生成的已编译方法在执行之前将eax隐匿在堆栈的上方?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆