scala

MbReflection

object MbReflection

The MiniboxingReflection object allows reflecting on the type parameters of miniboxed classes. For example, given class C[@miniboxed T], reflection can determine at run-time whether a type parameter is miniboxed, its instantiation and what type is used to store this value. These methods do not incur any overhead, since they are compiled away by the miniboxing plugin.

Let's see an example:

scala> import MbReflection._
import MbReflection._

scala> class C[@miniboxed T] {
     |   override def toString: String =
     |     s"C[T = ${reifiedType[T]}, miniboxed into a ${storageType[T]}]"
     | }
defined class C

scala> new C[Int]
res4: C[Int] = C[T = int, miniboxed into a long]

scala> new C[Unit]
res5: C[Unit] = C[T = unit, miniboxed into a long]

scala> new C[Float]
res6: C[Float] = C[T = float, miniboxed into a double]

Yet, it's still possible to instantiate the class in an erased context, leading to suboptimal storage. Still, the miniboxing plugin will slap you on the wrist for doing so, and reflection will tell you you're doing it wrong:

scala> def newC[T] = new C[T]
<console>:11: warning: The following code could benefit from miniboxing
specialization if the type parameter T of method newC would be marked
as "@miniboxed T" (it would be used to instantiate miniboxed type
parameter T of class C)
       def newC[T] = new C[T]
                     ^
newC: [T]=> C[T]

scala> newC[Int]
<console>:13: warning: The method newC would benefit from miniboxing
type parameter T, since it is instantiated by a primitive type.
              newC[Int]
                  ^
 res3: C[Int] = C[T = reference, miniboxed into a reference]

Finally, there's a good use case for this, if the class is always supposed to be miniboxed:

scala> class D[@miniboxed T] {
     |   assert(isMiniboxed[T], "Idiot!")
     | }
define class D

scala> new D[String]
java.lang.AssertionError: assertion failed: Idiot!
  at scala.Predef$.assert(Predef.scala:165)
  ... 34 elided

The "isMiniboxed" method is also partially evaluated away by the compiler:

scala> def foo[@miniboxed T]: Unit = {
     |   if (isMiniboxed[T])
     |     println("foo[miniboxed]")
     |   else
     |     println("foo[reference]")
     | }
foo: [T]=> Unit

scala> foo[Byte]
foo[miniboxed]

In the low-level bytecode you will have:

def foo(): Unit = println("foo[reference]")
def foo_J(...): Unit = println("foo[miniboxed]")
def foo_D(...): Unit = println("foo[miniboxed]")

So there is 0 overhead in using the isMiniboxed method. Still, reifiedType and storageType are not partially evaluated and do incur a small overhead.

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By inheritance
Inherited
  1. MbReflection
  2. AnyRef
  3. Any
  1. Hide All
  2. Show all
Learn more about member selection
Visibility
  1. Public
  2. All

Value Members

  1. final def !=(arg0: AnyRef): Boolean

    Definition Classes
    AnyRef
  2. final def !=(arg0: Any): Boolean

    Definition Classes
    Any
  3. final def ##(): Int

    Definition Classes
    AnyRef → Any
  4. final def ==(arg0: AnyRef): Boolean

    Definition Classes
    AnyRef
  5. final def ==(arg0: Any): Boolean

    Definition Classes
    Any
  6. object SimpleConv

  7. object SimpleType extends Enumeration

  8. final def asInstanceOf[T0]: T0

    Definition Classes
    Any
  9. def clone(): AnyRef

    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  10. final def eq(arg0: AnyRef): Boolean

    Definition Classes
    AnyRef
  11. def equals(arg0: Any): Boolean

    Definition Classes
    AnyRef → Any
  12. def finalize(): Unit

    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  13. final def getClass(): Class[_]

    Definition Classes
    AnyRef → Any
  14. def hashCode(): Int

    Definition Classes
    AnyRef → Any
  15. final def isInstanceOf[T0]: Boolean

    Definition Classes
    Any
  16. def isMiniboxed[T]: Boolean

    Is this type parameter miniboxed?

  17. final def ne(arg0: AnyRef): Boolean

    Definition Classes
    AnyRef
  18. final def notify(): Unit

    Definition Classes
    AnyRef
  19. final def notifyAll(): Unit

    Definition Classes
    AnyRef
  20. def reifiedType[T]: SimpleType

    If miniboxed, what is the actual type of a type parameter? It can be any of the scala miniboxing types.

  21. def storageType[T]: SimpleType

    If miniboxed, what is the storage type of a type parameter?

    If miniboxed, what is the storage type of a type parameter?

    The storage type of a miniboxed type parameter can be one of the following three types: * Object for instantiations with AnyRef-based types, erased generic types and value classes * Long for instantiations with Unit, Boolean, Byte, Char, Short, Int and Long * Double for instantiations with Float and Double

  22. final def synchronized[T0](arg0: ⇒ T0): T0

    Definition Classes
    AnyRef
  23. def toString(): String

    Definition Classes
    AnyRef → Any
  24. final def wait(): Unit

    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  25. final def wait(arg0: Long, arg1: Int): Unit

    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  26. final def wait(arg0: Long): Unit

    Definition Classes
    AnyRef
    Annotations
    @throws( ... )

Inherited from AnyRef

Inherited from Any

Ungrouped