Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@specialize vs. @inline: @specialize still wins #8247

Open
scabug opened this issue Feb 6, 2014 · 4 comments
Open

@specialize vs. @inline: @specialize still wins #8247

scabug opened this issue Feb 6, 2014 · 4 comments

Comments

@scabug
Copy link

scabug commented Feb 6, 2014

steps

class C[U]() {
  @inline final def apply(x: U): U = x
}

class C2[@specialized(Boolean) U]() {
  @inline final def apply(x: U): U = x
}

class B {
  private val cNormal = new C[Boolean]()
  private val cSpec   = new C2[Boolean]()
  
  final def m1 = cNormal(true)
  final def m2 = cSpec(true)
  // ./a.scala:14: warning: Could not inline required method apply$mcZ$sp because it can be overridden.
  //   final def m2 = cSpec(true)
  //                       ^
  // one warning found

  // however, here it inlines
  cNormal(true)
  cSpec(true)
}

problem

m2 is not inlined.

   0: aload_0
   1: new           #94                 // class C
   4: dup
   5: invokespecial #105                // Method C."<init>":()V
   8: putfield      #69                 // Field cNormal:LC;
  11: aload_0
  12: new           #107                // class C2$mcZ$sp
  15: dup
  16: invokespecial #108                // Method C2$mcZ$sp."<init>":()V
  19: putfield      #73                 // Field cSpec:LC2;
  22: aload_0
  23: invokespecial #77                 // Method cNormal:()LC;
  26: iconst_1
  27: invokestatic  #83                 // Method scala/runtime/BoxesRunTime.boxToBoolean:(Z)Ljava/lang/Boolean;
  30: astore_2
  31: dup
  32: ifnonnull     37
  35: aconst_null
  36: athrow
  37: astore_1
  38: aload_2
  39: astore_3
  40: goto          43
  43: aload_3
  44: pop
  45: aload_0
  46: invokespecial #97                 // Method cSpec:()LC2;
  49: iconst_1
  // **Not inlined**
  50: invokevirtual #103                // Method C2.apply$mcZ$sp:(Z)Z
  53: pop
  54: return

expectation

The bytecode of methods m1 and m2 both are constant true.

original report

I'm not sure I understand what happened in #5005. It's clearly a bug, I opened it with a clear description of the bug, but it ended up being closed because it had become "confused". Okay, I will unconfuse things. Here is the same report again. One should not have to choose between @specialized working and @inline working.

@scabug
Copy link
Author

scabug commented Feb 6, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8247?orig=1
Reporter: @paulp
Affected Versions: 2.11.0
See #5005

@SethTisue
Copy link
Member

can someone verify if this is still an issue in Scala 2.12.x?

@neonxray
Copy link

neonxray commented Jun 7, 2019

@SethTisue In Scala 2.12, it requires option switch -opt:inline or -opt:l:inline and -opt-inline-from:** to enable inlining. But either way it does not seem to work with specialized generic classes.

-opt-inline:

   0: aload_0
   1: new           #94                 // class C
   4: dup
   5: invokespecial #105                // Method C."<init>":()V
   8: putfield      #69                 // Field cNormal:LC;
  11: aload_0
  12: new           #107                // class C2$mcZ$sp
  15: dup
  16: invokespecial #108                // Method C2$mcZ$sp."<init>":()V
  19: putfield      #73                 // Field cSpec:LC2;
  22: aload_0
  23: invokespecial #77                 // Method cNormal:()LC;
  26: iconst_1
  27: invokestatic  #83                 // Method scala/runtime/BoxesRunTime.boxToBoolean:(Z)Ljava/lang/Boolean;
  30: astore_2
  31: dup
  32: ifnonnull     37
  35: aconst_null
  36: athrow
  37: astore_1
  38: aload_2
  39: astore_3
  40: goto          43
  43: aload_3
  44: pop
  45: aload_0
  46: invokespecial #97                 // Method cSpec:()LC2;
  49: iconst_1
  // **Not inlined**
  50: invokevirtual #103                // Method C2.apply$mcZ$sp:(Z)Z
  53: pop
  54: return

-opt:l:inline:

   0: aload_0
   1: new           #89                 // class C
   4: dup
   5: invokespecial #90                 // Method C."<init>":()V
   8: putfield      #69                 // Field cNormal:LC;
  11: aload_0
  12: new           #92                 // class C2$mcZ$sp
  15: dup
  16: invokespecial #93                 // Method C2$mcZ$sp."<init>":()V
  19: putfield      #73                 // Field cSpec:LC2;
  22: aload_0
  23: invokespecial #77                 // Method cNormal:()LC;
  26: ifnonnull     31
  29: aconst_null
  30: athrow
  31: aload_0
  32: invokespecial #80                 // Method cSpec:()LC2;
  35: iconst_1
  // **Not inlined**
  36: invokevirtual #86                 // Method C2.apply$mcZ$sp:(Z)Z
  39: pop
  40: return

@eed3si9n
Copy link
Member

eed3si9n commented Jun 9, 2019

@texasbruce Thanks for the verification.

I edited the description of this issue to steps, problem, expectation format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants