Open scabug opened 12 years ago
Imported From: https://issues.scala-lang.org/browse/SI-5490?orig=1 Reporter: @non See #5005
@magarciaEPFL said (edited on Jul 11, 2012 4:47:56 PM UTC): See if the fix for #6035 ( https://github.com/scala/scala/pull/872 ) helps with this bug.
@non said (edited on Jul 11, 2012 6:32:12 PM UTC): I merged Aleksandar's commit but unfortunately it doesn't fix either of these cases:
runDirect() is correctly getting inlining:
0: new #28; //class C$mcI$sp
3: dup
4: bipush 13
6: invokespecial #32; //Method C$mcI$sp."<init>":(I)V
9: invokevirtual #37; //Method C$mcI$sp.a:()I
12: ireturn
But runLocal() still is not:
0: new #28; //class C$mcI$sp
3: dup
4: bipush 13
6: invokespecial #32; //Method C$mcI$sp."<init>":(I)V
9: astore_1
10: aload_1
11: invokevirtual #25; //Method C.get$mcI$sp:()I
14: ireturn
Neither is runIndirect(); also, c's accessor and field are not being specialized:
0: aload_0
1: invokevirtual #20; //Method c:()LC;
4: invokevirtual #25; //Method C.get$mcI$sp:()I
7: ireturn
@magarciaEPFL said: Another suggestion (but this one might work) is trying the fixes in https://github.com/scala/scala/pull/887
@non said: I just tried the 2.10.x branch (which has pull request 887 merged) and still see the issue.
This issue was noticed in #5005. Basically, the problem here is that the typer runs before specialize, so the type of a val is never a specific specialized subclass. This means that all method calls on a specialized instance stored in a val end up using the unspecialized code instead. Here's an example that Vlad cooked up which shows the issue:
Looking at the bytecode, you'll notice that runDirect correctly calls (and inlines) C$mcI$sp.get$mcI$sp call, whereas runIndirect and runLocal both call C.get$mcI$sp, which cannot be final and thus is not inlined. Furthermore, even though the "c" val is defined as being a C[Int], the generated accessor method returns a C, not a C$mcI$sp.
Vlad thinks that type-flow analysis (TFA) might able to "fix" this in the case of local vals (or final vals which can't be overridden).