Classfile API Synchronous Stack Tracking in CodeBuilder

Adam Sotona adam.sotona at oracle.com
Wed Aug 24 13:54:07 UTC 2022


Hi,
I would like to hear your comments to proposed optional stack tracking functionality integrated in CodeBuilder.

Here is the pull request proposing to add:

  *   Classfile.Option::trackStack boolean option with default to false (the new option enabling stack tracking during code build)
  *   Optional<Collection<TypeKind>> CodeBuilder::stack – a method returning view of the actual stack synchronously during the build process (if enabled)
  *   Optional<Integer> CodeBuilder::maxStackSize - a method calculating maxStackSize (if enabled)
  *   impl.StackTracker implementation – a lightweight synchronous stack tracker
  *   StackTrackerTest tests

Beside the stack tracking the pull request adds  ConstantInstruction::typeKind and LoadableConstantEntry::typeKind methods self-describing ConstantInstruction and LoadableConstantEntry (not just) for the stack tracking purpose.

Here is the pull request:
https://github.com/openjdk/jdk-sandbox/pull/34

Primary purpose of the lightweight synchronous stack tracking is to support building of complex swap functions like stack-to-locals and locals-to-stack in CodeBuilder.

Example use case can be found in the StackTrackerTest:
        Classfile.build(ClassDesc.of("Foo"), List.of(Classfile.Option.trackStack(true)), clb ->
            clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_Void), 0, cob -> {
                assertEquals(cob.stack().get(), List.of());
                cob.aload(0);
                assertEquals(cob.stack().get(), List.of(ReferenceType));
                cob.lconst_0();
                assertEquals(cob.stack().get(), List.of(LongType, ReferenceType));
                cob.trying(tryb -> {
                    assertEquals(tryb.stack().get(), List.of(LongType, ReferenceType));
                    tryb.iconst_1();
                    assertEquals(tryb.stack().get(), List.of(IntType, LongType, ReferenceType));
                    tryb.ifThen(thb -> {
                        assertEquals(thb.stack().get(), List.of(LongType, ReferenceType));
                        thb.constantInstruction(ClassDesc.of("Phee"));
                        assertEquals(thb.stack().get(), List.of(ReferenceType, LongType, ReferenceType));
                        thb.athrow();
                        assertFalse(thb.stack().isPresent());
                    });
                    assertEquals(tryb.stack().get(), List.of(LongType, ReferenceType));
                    tryb.return_();
                    assertFalse(tryb.stack().isPresent());
                }, catchb -> catchb.catching(ClassDesc.of("Phee"), cb -> {
                    assertEquals(cb.stack().get(), List.of(ReferenceType));
                    cb.athrow();
                    assertFalse(cb.stack().isPresent());
                }));
                assertTrue(cob.maxStackSize().isPresent());
                assertEquals((int)cob.maxStackSize().get(), 4);
            }));

Thanks,
Adam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220824/f68851f3/attachment-0001.htm>


More information about the classfile-api-dev mailing list