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

Functions declared in miniboxed scopes still box #114

Closed
VladUreche opened this issue Jul 14, 2014 · 2 comments
Closed

Functions declared in miniboxed scopes still box #114

VladUreche opened this issue Jul 14, 2014 · 2 comments

Comments

@VladUreche
Copy link
Member

Technical limitation, will fix it:

$ cat gh-bug-X.scala 
package miniboxing.tests.correctness.bugX

class C[@miniboxed T](t: T) {
  def method = {
    // the body of foo is _not_ specialized since T => T is not an
    // optimized stack initiator, at least not in specialization's view:
    val foo = (x: T) => x
    foo(t)
  }
}

$ ../mb-scalac gh-bug-X.scala -Xprint:minibox-commit
[[syntax trees at end of            minibox-commit]] // gh-bug-X.scala
package miniboxing.tests.correctness.bugX {
  abstract trait C[@miniboxed T] extends Object {
    def method(): T;
    def method_D(T_TypeTag: Byte): Double;
    def method_J(T_TypeTag: Byte): Long
  };
  class C_D[Tsp] extends Object with miniboxing.tests.correctness.bugX.C[Tsp] {
    def <init>(miniboxing|tests|correctness|bugX|C_D|T_TypeTag: Byte, t: Double): miniboxing.tests.correctness.bugX.C_D[Tsp] = {
      C_D.super.<init>();
      ()
    };
    def method(): Tsp = MiniboxConversionsDouble.this.minibox2box[Tsp](C_D.this.method_D(C_D.this.miniboxing|tests|correctness|bugX|C_D|T_TypeTag), C_D.this.miniboxing|tests|correctness|bugX|C_D|T_TypeTag);
    def method_D(T_TypeTag: Byte): Double = {
      val foo: miniboxing.runtime.MiniboxedFunction1[Tsp,Tsp] = {
        final <synthetic> class $anonfun extends scala.runtime.AbstractFunction1[Tsp,Tsp] with Serializable {
          def <init>(): <$anon: Tsp => Tsp> = {
            $anonfun.super.<init>();
            ()
          };
          final def apply(x: Tsp): Tsp = x
        };
        MiniboxedFunctionBridge.this.function1_opt_bridge_double_double[Tsp, Tsp](T_TypeTag, T_TypeTag, (new <$anon: Tsp => Tsp>(): Tsp => Tsp))
      };
      foo.apply_DD(T_TypeTag, T_TypeTag, C_D.this.t)
    };
    def method_J(T_TypeTag: Byte): Long = MiniboxConversions.this.unreachableConversion[Nothing]("Double", "Long");
    <paramaccessor> private[this] val miniboxing|tests|correctness|bugX|C_D|T_TypeTag: Byte = _;
    <paramaccessor> private[this] val t: Double = _
  };
  class C_J[Tsp] extends Object with miniboxing.tests.correctness.bugX.C[Tsp] {
    def <init>(miniboxing|tests|correctness|bugX|C_J|T_TypeTag: Byte, t: Long): miniboxing.tests.correctness.bugX.C_J[Tsp] = {
      C_J.super.<init>();
      ()
    };
    def method(): Tsp = MiniboxConversionsLong.this.minibox2box[Tsp](C_J.this.method_J(C_J.this.miniboxing|tests|correctness|bugX|C_J|T_TypeTag), C_J.this.miniboxing|tests|correctness|bugX|C_J|T_TypeTag);
    def method_D(T_TypeTag: Byte): Double = MiniboxConversions.this.unreachableConversion[Nothing]("Long", "Double");
    def method_J(T_TypeTag: Byte): Long = {
      val foo: miniboxing.runtime.MiniboxedFunction1[Tsp,Tsp] = {
        final <synthetic> class $anonfun extends scala.runtime.AbstractFunction1[Tsp,Tsp] with Serializable {
          def <init>(): <$anon: Tsp => Tsp> = {
            $anonfun.super.<init>();
            ()
          };
          final def apply(x: Tsp): Tsp = x
        };
        MiniboxedFunctionBridge.this.function1_opt_bridge_long_long[Tsp, Tsp](T_TypeTag, T_TypeTag, (new <$anon: Tsp => Tsp>(): Tsp => Tsp))
      };
      foo.apply_JJ(T_TypeTag, T_TypeTag, C_J.this.t)
    };
    <paramaccessor> private[this] val miniboxing|tests|correctness|bugX|C_J|T_TypeTag: Byte = _;
    <paramaccessor> private[this] val t: Long = _
  };
  class C_L[Tsp] extends Object with miniboxing.tests.correctness.bugX.C[Tsp] {
    def <init>(t: Tsp): miniboxing.tests.correctness.bugX.C_L[Tsp] = {
      C_L.super.<init>();
      ()
    };
    def method(): Tsp = {
      val foo: miniboxing.runtime.MiniboxedFunction1[Tsp,Tsp] = {
        final <synthetic> class $anonfun extends scala.runtime.AbstractFunction1[Tsp,Tsp] with Serializable {
          def <init>(): <$anon: Tsp => Tsp> = {
            $anonfun.super.<init>();
            ()
          };
          final def apply(x: Tsp): Tsp = x
        };
        MiniboxedFunctionBridge.this.function1_bridge[Tsp, Tsp]((new <$anon: Tsp => Tsp>(): Tsp => Tsp))
      };
      foo.apply(C_L.this.t)
    };
    def method_D(T_TypeTag: Byte): Double = MiniboxConversionsDouble.this.box2minibox_tt[Tsp](C_L.this.method(), T_TypeTag);
    def method_J(T_TypeTag: Byte): Long = MiniboxConversionsLong.this.box2minibox_tt[Tsp](C_L.this.method(), T_TypeTag);
    <paramaccessor> private[this] val t: Tsp = _
  }
}

The problem is that, in all definitions, the

  final def apply(x: Tsp): Tsp = x

is not specialized. This means function definitions need to be hijacked completely, before the head for interop-coerce...

@VladUreche
Copy link
Member Author

Discovered while playing around with the miniboxed linked list...

@VladUreche
Copy link
Member Author

This will also be fixed:

  • not all function types can avoid boxing (for example, (x: (Int, Int) => x._1 + x._2)

biboudis added a commit to biboudis/scala-streams that referenced this issue Nov 23, 2014
*) Related to miniboxing/miniboxing-plugin#146
*) Will completely remove this after miniboxing/miniboxing-plugin#114 is resolved
*) Thanks @VladUreche for support and looking into miniboxing issue!

Conflicts:
	src/main/scala/benchmarks/benchmarks.scala
	src/main/scala/streams/Stream.scala
VladUreche added a commit that referenced this issue Nov 28, 2014
some tests are still failing :(
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

1 participant