Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inject fields once at the root of the type hierarchy #2007

Merged
merged 2 commits into from
Oct 20, 2020

Conversation

richardstartin
Copy link
Member

does field injection in the highest concrete type still a subtype of the context store key class, which prevents from adding a field to every class in the hierarchy.

@richardstartin richardstartin requested a review from a team as a code owner October 19, 2020 19:40
@richardstartin richardstartin force-pushed the rgs/targeted-field-injection branch 4 times, most recently from e4b8620 to 30f0783 Compare October 19, 2020 20:59
KEY_TYPE_IS_CLASS.put(keyType, true);
return keyType;
}
for (TypeDescription.Generic iface : superClass.getInterfaces()) {
Copy link
Contributor

@mcculls mcculls Oct 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll still miss a chance to optimize if the class hierarchy implements an interface that extends the key type and doesn't implement the key type directly (since this only checks directly declared interfaces, and not the interfaces they extend) but I think that's OK as widening the search to include transitive interfaces could be expensive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, but this should work for all the types we're interested in injecting (we need to stop doing this for Runnable for other reasons). This kind of matching is done repetitively, and I think the structure of the types we care about, at least for the purpose of field injection, could be memoized cheaply so we don't need to do so many traversals. The result is also correct no matter what, it's just a missed optimisation opportunity (both in space and transformation time).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having said that, I would be amazed if traversing the hierarchy when we already know there's a subtype relationship outweighs the cost of unnecessary transformation, or the long term cost of carrying extra fields around.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true - if you do extend the search to cover transitive interfaces then you might want to consider a local cache to track which interfaces you've seen

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For more context to anyone else reviewing, the single case that I considered making this for is ForkJoinTask. Whether you're using the streams API or RecursiveAction etc. the API depends on being able fork lots of tiny objects but there are often at least two levels of class inheritance. This won't make much difference to wide interface inheritance hierarchies.

Copy link
Contributor

@bantonsson bantonsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea. Have some questions that I would like answered.

* fields before is being transformed again. Note: here we assume that Class#getInterfaces()
* returns list of interfaces defined immediately on a given class, not inherited from its
* parents. It looks like current JVM implementation does exactly this but javadoc is not
* explicit about that.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the javadoc is very clear:

Returns the interfaces directly implemented by the class or interface represented by this object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an existing comment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still broken...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree. There are also a few missing articles which certainly justifies a cleanup.

@richardstartin
Copy link
Member Author

@bantonsson it's not clear which changes you are requesting.

@bantonsson
Copy link
Contributor

I just wanted to get a chance to review again, and this is the only way 😉

Copy link
Contributor

@bantonsson bantonsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// false: the key type is an interface, so we need to find the class
// closes to java.lang.Object which implements the key type
// null: we don't know yet because we haven't seen the key type before
Boolean keyTypeIsClass = KEY_TYPE_IS_CLASS.get(keyType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very slim edge case that is probably not worth considering: It is possible for this result to be different on different classloaders within a single jvm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly sure there would be a ClassCastException in any instrumentation using a context store if your edge case existed in practice.

@richardstartin richardstartin merged commit c778566 into master Oct 20, 2020
@richardstartin richardstartin deleted the rgs/targeted-field-injection branch October 20, 2020 14:44
@github-actions github-actions bot added this to the 0.66.0 milestone Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants