8303431: [JVMCI] libgraal annotation API#12810
8303431: [JVMCI] libgraal annotation API#12810dougxc wants to merge 14 commits intoopenjdk:masterfrom
Conversation
|
👋 Welcome back dnsimon! A progress list of the required criteria for merging this PR into |
Webrevs
|
|
This PR still needs work. I'll re-open it when ready. |
|
@dougxc this pull request can not be integrated into git checkout JDK-8303431
git fetch https://git.openjdk.org/jdk master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
| } | ||
| @SuppressWarnings("unchecked") | ||
| @Test | ||
| public void encodeDecodeTest2() throws Exception { | ||
| Throwable throwable = new ExceptionInInitializerError(new InvocationTargetException(new Untranslatable("test exception", new NullPointerException()), "invoke")); | ||
| for (int i = 0; i < 10; i++) { | ||
| throwable = new ExceptionInInitializerError(new InvocationTargetException(new RuntimeException(String.valueOf(i), throwable), "invoke")); | ||
| } | ||
| encodeDecode(throwable); | ||
| } | ||
|
|
There was a problem hiding this comment.
Because it does exactly the same thing as encodeDecodeTest. It should have been cleaned up in the original PR that introduced this test.
vnkozlov
left a comment
There was a problem hiding this comment.
I looked on Hotspot, JVMCI and VMSupport.java changes. But you need to ask Tom to look on JVMCI changes in details. And someone from core-libs who familiar with Annotations have to comment on your implementation in general because I am not expert.
|
@dougxc This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 26 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
tkrodriguez
left a comment
There was a problem hiding this comment.
The JVMCI changes look ok to me.
|
|
||
| typeArrayOop ba = typeArrayOop(res); | ||
| int ba_len = ba->length(); | ||
| if (ba_len <= 256) { |
There was a problem hiding this comment.
Is this really necessary? Resource allocation is very cheap.
There was a problem hiding this comment.
Ok, good point. I'll remove the optimization.
| * initialized. Class initialization is not triggered for enum types referenced by other | ||
| * annotations of this element. | ||
| * | ||
| * If this element is a class, then {@link Inherited} annotations are included in set of |
|
@jddarcy would you be able to help review this PR? Based on git log, you are knowledgeable in |
| /** | ||
| * Encodes a list of annotations to a byte array. The byte array can be decoded with {@link #decodeAnnotations(byte[], AnnotationDecoder)}. | ||
| */ | ||
| public static byte[] encodeAnnotations(Collection<Annotation> annotations) { |
There was a problem hiding this comment.
I don't think it matters much in this use case, but it looks like encodeAnnotations could be changed to take a List rather than a Collection, as the comment implies.
There was a problem hiding this comment.
Just above (line 228) you can see a call to this method where the argument comes from Map.values() whose type is Collection so I'd prefer to leave it as is rather than have to convert the argument to a List.
There was a problem hiding this comment.
In that case, I think the comment on line 232 should be updated to not say "list".
There was a problem hiding this comment.
I changed the comment to "Encodes annotations to a byte array."
| * @param <E> type of the object representing a decoded enum constant | ||
| * @param <X> type of the object representing a decoded error | ||
| */ | ||
| public interface AnnotationDecoder<T, A, E, X> { |
There was a problem hiding this comment.
I think it would be better to include some bound on the type parameters to better capture their intention
A extends java.lang.Annotatoin
E extends java.lang.Enum
etc.
There was a problem hiding this comment.
These types are alternatives to java.lang.Annotation, java.lang.Enum etc. That's the primary motivation for this PR, i.e. to be able to represent annotations without having to reify them as java.lang.Annotation objects.
|
A few higher-level comments: From the long-term perspective, it is likely that the set of kinds of elements that can occur in an annotation will be expanded, for example, method references are a repeated request. Easing future maintenance to gives more inter-source linkage in this situation and error handling for this case in the libgraal code would be prudent IMO. The java.lang.reflect.AnnotatedElement API (https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/reflect/AnnotatedElement.html) defines different ways an annotation can be affiliated with an element: "The terms directly present, indirectly present, present, and associated are used throughout this interface to describe precisely which annotations are returned by methods: " tl;dr these terms relate to which of inheriting annotations and looking through repeated annotations the methods do on behalf of the caller. I think the methods should phrase their operations in terms of these concepts, such as "Construct the annotations present..." since inheritance is taken into account. |
I'm not sure what you're suggesting in terms of how I should update this PR. Do you mean |
I think this is what you're suggesting: 362738a |
Let me explain my concerns in more detail. We have (at least) two separate annotations implementations in the JDK, one in javac for compile-time and other in core reflection for runtime. Due to various technical constraints, the implementations are necessarily separate (although the annotation objects constructed by javac do also implement the java.lang.annotation.Annotation interface also used by core reflection). This work is proposing to add another partial implementation to satisfy other technical goals, reusing portions of the existing core reflection machinery. If at some point the universe of objects that can be encoded as annotation is expanded, e..g method literals as mentioned previously, it is well-understood that core reflection and javac will need to be updated. I think it would be relatively easy to overlook the need to make corresponding updates to libgraal API and all regression tests might still pass. As a concrete suggestion, if such an unknown annotation was handed over to libgraal, I think the code should reject it (AssertionError("unexpected annotation component") etc.) in hope of the omission getting corrected sooner. Also, leaving some bread crumb comments to future maintainers of core reflection annotations in that implementation package would be helpful too, e.g. "// used by libgraal". HTH |
…ew annotation element types be added
The
Done here: bad23a0 |
|
Thanks for the reviews @turbanoff , @vnkozlov and @jddarcy. /integrate |
|
Going to push as commit 48fd4f2.
Your commit was automatically rebased without conflicts. |
|
@dougxc I see next 2 JVMCI tests failed when run with |
|
I can reproduce this locally as well but really don't know where to start in terms of debugging this. Can you please provide hints as to what may cause this failure C1 compiled code? |
|
Filed JDK-8306581 |
This PR extends JVMCI with new API (
jdk.vm.ci.meta.Annotated) for accessing annotations. The main differences fromjava.lang.reflect.AnnotatedElementare:Annotatedinterface explicitly specify requested annotation type(s). That is, there is no equivalent ofAnnotatedElement.getAnnotations().jdk.vm.ci.meta.AnnotationData) instead of in anAnnotationobject. This works better for libgraal as it avoids the need for annotation types to be loaded and included in libgraal.To demonstrate the new API, here's an example in terms
java.lang.reflect.AnnotatedElement(whichResolvedJavaTypeimplements):The same code using the new API:
The implementation relies on new methods in
jdk.internal.vm.VMSupportfor parsing annotations and serializing/deserializing to/from a byte array. This allows the annotation data to be passed from the HotSpot heap to the libgraal heap.Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/12810/head:pull/12810$ git checkout pull/12810Update a local copy of the PR:
$ git checkout pull/12810$ git pull https://git.openjdk.org/jdk.git pull/12810/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 12810View PR using the GUI difftool:
$ git pr show -t 12810Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/12810.diff
Webrev
Link to Webrev Comment