-
Enhancement
-
Resolution: Fixed
-
P4
-
8u192, 11.0.2, 12, 13
-
b12
The default methods generation scans the hierarchy of classes during load to determine what default and overpass methods to generate into the class being loaded. There are a few inefficiencies:
- java.lang.Object is scanned at least once for every interface in the hierarchy
- classes that implement multiple interfaces that extend each other will visit shared interfaces multiple times
- private static methods in java.lang.Object are added in the build-up, but then explicitly filtered out later: filter them out early
Using -Xlog:defaultmethods=debug we can see some of these inefficiencies in action (X is a noop class implementing AutoCloseable, Closeable, Predicate<Integer>):
[0,655s][debug][defaultmethods] Class X requires default method processing
[0,655s][debug][defaultmethods] X
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/lang/AutoCloseable
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/io/Closeable
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/lang/AutoCloseable
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/util/function/Predicate
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] Slots that need filling:
[0,655s][debug][defaultmethods] or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,655s][debug][defaultmethods] and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,655s][debug][defaultmethods] negate()Ljava/util/function/Predicate;
[0,655s][debug][defaultmethods] <clinit>()V
[0,655s][debug][defaultmethods] registerNatives()V
[0,655s][debug][defaultmethods] Looking for default methods for slot or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Looking for default methods for slot and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Looking for default methods for slot negate()Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Looking for default methods for slot <clinit>()V
[0,656s][debug][defaultmethods] Looking for default methods for slot registerNatives()V
[0,656s][debug][defaultmethods] Creating defaults and overpasses...
[0,656s][debug][defaultmethods] for slot: or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Selected method: java/util/function/Predicate.or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] for slot: and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Selected method: java/util/function/Predicate.and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] for slot: negate()Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Selected method: java/util/function/Predicate.negate()Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Created 0 overpass methods
[0,656s][debug][defaultmethods] Created 3 default methods
[0,656s][debug][defaultmethods] Default method processing complete
With experimental optimization we resolve the issue with Object being scanned a multitude of times, along with adding <clinit> / registerNatives to the candidate list for every class considered: http://cr.openjdk.java.net/~redestad/scratch/defmeth_opt.00/
[0,657s][debug][defaultmethods] Class X requires default method processing
[0,657s][debug][defaultmethods] X
[0,657s][debug][defaultmethods] java/lang/Object
[0,657s][debug][defaultmethods] java/lang/AutoCloseable
[0,657s][debug][defaultmethods] java/io/Closeable
[0,657s][debug][defaultmethods] java/lang/AutoCloseable
[0,657s][debug][defaultmethods] java/util/function/Predicate
[0,657s][debug][defaultmethods] Slots that need filling:
[0,657s][debug][defaultmethods] or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Looking for default methods for slot or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Looking for default methods for slot and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Looking for default methods for slot negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Creating defaults and overpasses...
[0,657s][debug][defaultmethods] for slot: or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Selected method: java/util/function/Predicate.or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] for slot: and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Selected method: java/util/function/Predicate.and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] for slot: negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Selected method: java/util/function/Predicate.negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Created 0 overpass methods
[0,657s][debug][defaultmethods] Created 3 default methods
[0,657s][debug][defaultmethods] Default method processing complete
This translates to a small but scaling speedup in various startup tests.
- java.lang.Object is scanned at least once for every interface in the hierarchy
- classes that implement multiple interfaces that extend each other will visit shared interfaces multiple times
- private static methods in java.lang.Object are added in the build-up, but then explicitly filtered out later: filter them out early
Using -Xlog:defaultmethods=debug we can see some of these inefficiencies in action (X is a noop class implementing AutoCloseable, Closeable, Predicate<Integer>):
[0,655s][debug][defaultmethods] Class X requires default method processing
[0,655s][debug][defaultmethods] X
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/lang/AutoCloseable
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/io/Closeable
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/lang/AutoCloseable
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] java/util/function/Predicate
[0,655s][debug][defaultmethods] java/lang/Object
[0,655s][debug][defaultmethods] Slots that need filling:
[0,655s][debug][defaultmethods] or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,655s][debug][defaultmethods] and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,655s][debug][defaultmethods] negate()Ljava/util/function/Predicate;
[0,655s][debug][defaultmethods] <clinit>()V
[0,655s][debug][defaultmethods] registerNatives()V
[0,655s][debug][defaultmethods] Looking for default methods for slot or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Looking for default methods for slot and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Looking for default methods for slot negate()Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Looking for default methods for slot <clinit>()V
[0,656s][debug][defaultmethods] Looking for default methods for slot registerNatives()V
[0,656s][debug][defaultmethods] Creating defaults and overpasses...
[0,656s][debug][defaultmethods] for slot: or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Selected method: java/util/function/Predicate.or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] for slot: and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Selected method: java/util/function/Predicate.and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] for slot: negate()Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Selected method: java/util/function/Predicate.negate()Ljava/util/function/Predicate;
[0,656s][debug][defaultmethods] Created 0 overpass methods
[0,656s][debug][defaultmethods] Created 3 default methods
[0,656s][debug][defaultmethods] Default method processing complete
With experimental optimization we resolve the issue with Object being scanned a multitude of times, along with adding <clinit> / registerNatives to the candidate list for every class considered: http://cr.openjdk.java.net/~redestad/scratch/defmeth_opt.00/
[0,657s][debug][defaultmethods] Class X requires default method processing
[0,657s][debug][defaultmethods] X
[0,657s][debug][defaultmethods] java/lang/Object
[0,657s][debug][defaultmethods] java/lang/AutoCloseable
[0,657s][debug][defaultmethods] java/io/Closeable
[0,657s][debug][defaultmethods] java/lang/AutoCloseable
[0,657s][debug][defaultmethods] java/util/function/Predicate
[0,657s][debug][defaultmethods] Slots that need filling:
[0,657s][debug][defaultmethods] or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Looking for default methods for slot or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Looking for default methods for slot and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Looking for default methods for slot negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Creating defaults and overpasses...
[0,657s][debug][defaultmethods] for slot: or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Selected method: java/util/function/Predicate.or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] for slot: and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Selected method: java/util/function/Predicate.and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] for slot: negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Selected method: java/util/function/Predicate.negate()Ljava/util/function/Predicate;
[0,657s][debug][defaultmethods] Created 0 overpass methods
[0,657s][debug][defaultmethods] Created 3 default methods
[0,657s][debug][defaultmethods] Default method processing complete
This translates to a small but scaling speedup in various startup tests.
- relates to
-
JDK-8251990 Improve default method handling of private static methods in java.lang.Object
-
- Closed
-