[LW2] Q-mirror, method handle, and reflection support for Q-type

Mandy Chung mandy.chung at oracle.com
Tue Nov 27 18:57:06 UTC 2018


Summary of this patch
1. A value type has a L-mirror and Q-mirror that can be obtained
    via Class::asBoxType and Class::asValueType method

    For a non-value type, Class::asBoxType returns itself and
    Class::asValueType returns null.

2. Class::forName, Object::getClass, Member::getDeclaringClass
    returns L-mirror in this version as Point.class

3. Class::cast throws NPE if the given object is null and
    this class is Q-mirror

4. Update reflection and dynamic proxies to support Q-Type

5. Update method handles and temporarily patch ASM to
    support Q-Type descriptor

This patch fixes all test/jdk/valhalla/valuetypes and
test/jdk/java/lang/invoke tests (except a few condy test
failures that will be fixed separately because the bytecode
library in lworld is out of sync with jdk version).

It also fixes hotspot/jtreg/compiler/valhalla/valuetypes
and hotspot/jtreg/runtime/valhalla/valuetypes tests to use
Q-mirror in the method type correctly.

Below lists the open issues w.r.t the primary mirror and
Class::getName spec for value types.  I'd like to get
this initial method handle and reflection support in lworld
first and we can resolve these issues separately.


Open Issues:
1. Should the primary mirror for value instance klass be Q-mirror?

    As the above methods returns the box value type, it will need
to do the box/unbox value type to get a method handle for:
          public Point m(Point.box p);

    like this:
      MethodType.methodType(Point.class.asValueType(), Point.class)

    This is somewhat counter-intuitive. It would be more intuitive
    for a developer to code like this:

      MethodType.methodType(Point.class, Point.class.asBoxType())

    This will be consistent with the source level as "Point" in
    the method signature refers to Q-Type. [1] shows some example.

    In addition, Point[].class whose component type should be
    Q-mirror.  It's a bit confusing due to the inconsistency.

    It seems that it's more intuitive to have Q-mirror as
    the primary mirror for value class.

2. Class::getName returns the binary name of the class.

    The returned name can be used to pass to Class::forName
    and also used to create the type descriptor.

    If getName on Q-mirror returns "pkg.Val/val" (a different string
    than L-mirror), then to support the value type, existing code
    would need to do:
String cn = c.asBoxType().getName();

    It's less migration friendly.  L-mirror is needed only when
    the source code explicitly declares the box value `Point.box p;`.
    Here is an alternate proposal:

    Class::getName returns the same string for L-mirror and Q-mirror
    as it has the same instance class.

    Class::getTypeName returns an informative string for the name
    of this type.  This method returns "pkg.Val" or 'pkg.Val.val'
    if it's Q-mirror and "pkg.Val/box" if it's L-mirror.

    Class::getSimpleName returns "Val" if it's Q-mirror and
    "Val.box" if it's L-mirror.


More information about the valhalla-dev mailing list