JDK-8015416 : tier one should collect context-dependent split profiles
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2013-05-25
  • Updated: 2020-12-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
To avoid polluted profiles, tier one should create disjoint "split" profiles for methods that it inlines.  If a method is inlined three times, it should get three fresh copies of its global profile, initialized to no types or counts.  When a later tier re-optimizes the code and inlines the same method, the compiler should use the context-dependent profile in preference to the global profile, if one is available.

Background:

The interpreter collects type profiles for invoke receivers and type checks.  The profiles are crucial to later optimizing compilation.  Tier one currently emulates the interpreter with respect to profiling.

Profiles are created when a method is somehow noticed as relevant to execution (e.g., warm enough).  Each profile applies to one bytecode method, and is affected by all executions of that method, from whatever caller.  Each original instance of a relevant bytecode instruction (invokevirtual, checkcast, etc.) gets a ReceiverTypeData record in the profile structure, which is called MethodData.  Each record has a number (TypeProfileWidth, default 2) of rows, each of which contains a count and an exact object type.

Profiles have two failure modes:  First, a method might be compiled before its profile exists and is "mature", so that no stable conclusions can be drawn about operands in that method.  Second, a method might be used from many different contexts with independent operand types (as with ArrayList.contains), so that the profile becomes "polluted" by many independent types.  A polluted profile contains the first few (2) encountered types with low counts, and a high total count that signals that the ReceiverTypeData structure was too small.

Polluted profiles stem from the fact that a method (containing generically reusable code) has only one profile structure, but the method is reused from a variety of contexts, providing a variety of operand types.

Comments
While full caller-callee profiles might introduce too much profiling overhead for the gain, a lighter weight approach might be to attach split profiles to hot inner loops only, and then clone the loop for each sufficiently hot combination of profiled types. This could essentially allow a higher order function that contains a loop to act as a 'template': public static <T> T reduce(T[] arr, T zero, BinaryOperator<T> reducer) { T result = zero; for (T t : arr) { // cloned for every hot 'reducer' concrete type result = reducer.apply(result, t); // fully specialized loop body } return result; }
18-12-2020