-
Notifications
You must be signed in to change notification settings - Fork 277
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
Iterate type interfaces without materialising a list during super type matching #1578
Iterate type interfaces without materialising a list during super type matching #1578
Conversation
4ae4e0a
to
a550113
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement - it is even better in relative percentage (from 4% to 3% is 25% save).
I have a few comments - mostly clarification questions and nits but there is one thing I am a bit concerned in SafeInterfaceIterator
.
if (!checkedInterfaces.contains(type)) { | ||
checkedInterfaces.add(type); | ||
if (checkedInterfaces.add(type)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
...ing/src/main/java/datadog/trace/agent/tooling/bytebuddy/matcher/SafeHasSuperTypeMatcher.java
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
public void remove() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about throwing UnsupportedOperationException
to make it totally clear that this method is not supposed to be called at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
...ent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/matcher/TypeComparators.java
Outdated
Show resolved
Hide resolved
...ent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/matcher/TypeComparators.java
Outdated
Show resolved
Hide resolved
...src/test/groovy/datadog/trace/agent/tooling/bytebuddy/matcher/HasInterfaceMatcherTest.groovy
Outdated
Show resolved
Hide resolved
a550113
to
6801e71
Compare
Regarding percentage, I think percentage of total is the number to focus on because we happen to allocate four |
6801e71
to
b2bd5e1
Compare
This provokes an interesting failure detected by the netty tests:
Why are we trying to resolve a type description for |
* | ||
* <p>The caller MUST call hasNext() before calling next(). | ||
* | ||
* <p>This wrapper exists to allow getting interfaces even if the lookup on one fails. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that this comment and behavior is the same as the old one, but maybe clarify that it stops at the first exception.
b2bd5e1
to
b5ca36b
Compare
The handling of this case does turn out to be important here. ByteBuddy first constructs a lazy TypeDescriptor without loading the underlying class file. If later, it needs to load the class file, but cannot -- then an exception is raised. I'd previously done an experiment with creating a custom Iterator that catches the exception to avoid the extra ArrayList-s while handling the exception. At that the time, we were mostly focused on start-up, so I don't end up putting the change in. |
|
||
@Override | ||
public int compare(TypeDescription o1, TypeDescription o2) { | ||
return o1.getSimpleName().compareTo(o2.getSimpleName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched to getName
and the :dd-java-agent:instrumentation:netty-4.1:testJava11Generated
succeeded locally, while getSimpleName
fails.
public int compare(TypeDescription o1, TypeDescription o2) {
if (o1 == o2) {
return 0;
}
return o1.getName().compareTo(o2.getName());
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is name sufficient here? We have to be a bit carefully about duplicates being loaded across different ClassLoaders, but in a limited context, name should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll just change this back to HashSet
to avoid edge cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice change!
bf43a07
to
e8302ef
Compare
e8302ef
to
9527c77
Compare
reduces allocation during type matching at startup.
Evaluation:
run spring pet-clinic with
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -mx1G -XX:+HeapDumpOnOutOfMemoryError
to capture every allocated object in the first GB allocated. Results in reduction inArrayList
allocations by 1% of total (4th most commonly allocated object during startup)Some tests weren't actually testing handling of an exception thrown during iteration, but simulated this by throwing on the
getInterfaces()
call - I fixed those.