关于“Inside the Java Virtual Machine - Chapter 5 The Java Virtual Machine - The Java Stack”的疑问

2020-09-02 11:43:38 +08:00
 JasonLaw

在“Possible Implementations of the Java Stack”中,它给出了如下的 class:

class Example3c {

    public static void addAndPrint() {
        double result = addTwoTypes(1, 88.88);
        System.out.println(result);
    }

    public static double addTwoTypes(int i, double d) {
        return i + d;
    }
}

然后它说:

Note that the addAndPrint() method uses the constant pool to identify the addTwoTypes() method, even though it is part of the same class. Like references to fields and methods of other classes, references to the fields and methods of the same class are initially symbolic and must be resolved before they are used.

The resolved constant pool entry points to information in the method area about the addTwoTypes() method. The virtual machine uses this information to determine the sizes required by addTwoTypes() for the local variables and operand stack. In the class file generated by Sun's javac compiler from the JDK 1.1, addTwoTypes() requires three words in the local variables and four words in the operand stack. (As mentioned earlier, the size of the frame data portion is implementation dependent.) The virtual machine allocates enough memory for the addTwoTypes() frame from a heap. It then pops the double and int parameters (88.88 and one) from addAndPrint()'s operand stack and places them into addTwoType()'s local variable slots one and zero.

operand stack 只会存储一个 int 和一个 double,就像 local variables 一样。那么为什么 operand stack 需要 four words ? three words 不是够了吗?剩余的一个 word 是用来干嘛的?

1043 次点击
所在节点    Java
2 条回复
zsdroid
2020-09-02 11:48:45 +08:00
“和”不需要保存吗?
JasonLaw
2020-09-02 12:04:08 +08:00
我明白了,我 javac Example3c.java 之后,`javap -c Example3c.class `的输出结果如下所示:

Compiled from "Example3c.java"
class Example3c {
Example3c();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void addAndPrint();
Code:
0: iconst_1
1: ldc2_w #2 // double 88.88d
4: invokestatic #4 // Method addTwoTypes:(ID)D
7: dstore_0
8: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
11: dload_0
12: invokevirtual #6 // Method java/io/PrintStream.println:(D)V
15: return

public static double addTwoTypes(int, double);
Code:
0: iload_0
1: i2d
2: dload_1
3: dadd
4: dreturn
}

注意“1: i2d”,https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html 中的对 i2d 的描述是“Convert int to double”,这也就是为什么 operand stack 需要 four words 的原因。因为不是存储一个 int 和一个 double,是要存储两个 double 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/703460

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX