aconst_init

John Rose john.r.rose at oracle.com
Wed Dec 1 20:34:35 UTC 2021


On Dec 1, 2021, at 7:58 AM, Dan Heidinga <heidinga at redhat.com> wrote:
> 
> Splitting a new thread off from Dan's email about the jep draft to
> talk about the `aconst_init` bytecode:
> 
>> aconst_init, with a CONSTANT_Class operand, produces an instance of the named value class, with all fields set to their default values. This operation always has private access: a linkage error occurs if anyone other than the value class or its nestmates attempts an aconst_init operation.
> 
> Can you confirm if this is purely a rename of the previous
> defaultvalue / initialvalue bytecodes?

I can confirm this, with one important exception:   The defaultvalue
bytecode has no access restrictions, while the aconst_init/initialvalue
bytecode does.

> I'm wondering how the name fits the eventual primitive values and
> their uses.  Will they also use this bytecode or will they continue to
> use a defaultvalue version?

For this reason, aconst_init/initialvalue is not useful for B3 types.
I think there is no need for yet another bytecode to cover the B3
types.  Instead, Class::__InitialValue should return either null for
B1/B2 types (or any reference types: polys and arrays), and should
return the (boxed) zero for primitives, starting with int.class.

assert Integer.class.__InitialValue() == null;
assert int.class.__InitialValue() == 0;
assert Point.class.__InitialValue() == (new Point[1])[0];
assert Point.ref.class.__InitialValue() == null;

(__InitialValue is not really the eventual method name.)

> The expected bytecode pattern for a "<new>" factory method is something like:
>  aconst_init MyValue
>  iconst1
>  withfield MyValue.x:I
>  areturn
> Correct?

Yes, although it’s likely there are intervening astore_0 and
aload_0 instructions, since ’this’ is probably modeled by the
compiler as local[0].

By the way, this raises the question of how vigorously
the JVM should perform structural checks on the new
features, to ensure they are only used in the ways we
expect.  I think in general such checks should be
justified individually, rather than be applied by default.

Since <new> is just a static factory method, I would prefer
(though I understand reasons to the contrary) to have the
JVMS be agnostic about where <new> methods can occur.
In other words, treat <new> like a plain identifier; maybe
require that it be marked ACC_STATIC but allow it to
work like a nameless factory method in any context
where a classfile generator might choose to make use of it.

Taking an agnostic stance now would let us experiment
with translation strategies (in the future) which replace
uses of <init> (which have problematic security
characteristics, even recently) with uses of <new>.

(Reflection might omit off-label uses of <new>, just
like it omits <clinit>.  But the “guts” of MH reflection
can see <init> today and would see all such <new>s
tomorrow, so exposing it becomes a library issue,
not a JVMS decision.)

— John


More information about the valhalla-spec-observers mailing list