【发布时间】:2018-12-14 21:45:45
【问题描述】:
假设 jvm 将 b.foo() 方法识别为 hot,它会尝试内联它吗?因为如果是这样,调用指令 B.bar() 将被内联在 A.main 方法中,这是禁止的,因为 bar 是私有的。 jvm 在这些情况下做了什么?
任何包含更多详细信息的文档也受到赞赏。谢谢
public class A {
public static void main(String[] args)
{
B b = new B();
for (int i=0; i<99999; i++)
b.foo();
}
}
class B {
public void foo() {
bar();
}
private void bar() { // do something. (is small method)
}
}
编辑:我之所以问,是因为当我尝试自己进行此优化时(在字节码中),我得到一个有意义的验证错误:
java.lang.VerifyError: 错误的 invokespecial 指令:当前类不可分配给引用类
EDIT2:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=5, args_size=1
0: new #13 // class B
3: dup
4: invokespecial #14 // Method B."<init>":()V
7: astore_1
8: iconst_0
9: istore_2
10: iload_2
11: ldc #15 // int 99999
13: if_icmpge 30
16: aload_1
17: astore 4
19: aload 4
21: invokespecial #18 // Method B.bar:()V // VERIFY ERROR HERE
24: iinc 2, 1
27: goto 10
30: return
StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 10
locals = [ class B, int ]
frame_type = 19 /* same */
LineNumberTable:
line 5: 0
line 6: 8
line 7: 16
line 14: 19
line 15: 24
line 6: 24
line 8: 30
【问题讨论】:
-
为什么你认为禁止内联私有方法?
-
内联的 foo 方法不是私有的,它是公共的
-
你能显示你生成的导致VerifyError的字节码吗?
-
@DavidConrad 完成
-
呃,如果将 bar 内联到 foo 中,并将 foo 内联到 main 中,它会将 makeup bar 的指令插入到 main 中。它不会在 main 中插入 对 bar 的调用。