RFR: 8325467: Support methods with many arguments in C2 [v24]

Emanuel Peter epeter at openjdk.org
Mon Sep 1 07:37:00 UTC 2025


On Fri, 29 Aug 2025 09:38:58 GMT, Daniel Lundén <dlunden at openjdk.org> wrote:

>> If a method has a large number of parameters, we currently bail out from C2 compilation.
>> 
>> ### Changeset
>> 
>> Allowing C2 compilation of methods with a large number of parameters requires fundamental changes to the register mask data structure, used in many places in C2. In particular, register masks currently have a statically determined size and cannot represent arbitrary numbers of stack slots. This is needed if we want to compile methods with arbitrary numbers of parameters. Register mask operations are present in performance-sensitive parts of C2, which further complicates changes.
>> 
>> Changes:
>> - Add functionality to dynamically grow/extend register masks. I experimented with a number of design choices to achieve this. To keep the common case (normal number of method parameters) quick and also to avoid more intrusive changes to the current `RegMask` interface, I decided to leave the "base" statically allocated memory for masks unchanged and only use dynamically allocated memory in the rare cases where it is needed.
>> - Generalize the "chunk"-logic from `PhaseChaitin::Select()` to allow arbitrary-sized chunks, and also move most of the logic into register mask methods to separate concerns and to make the `PhaseChaitin::Select()` code more readable.
>> - Remove all `can_represent` checks and bailouts.
>> - Performance tuning. A particularly important change is the early-exit optimization in `RegMask::overlap`, used in the performance-sensitive method `PhaseChaitin::interfere_with_live`.
>> - Add a new test case `TestManyMethodArguments.java` and extend an old test `TestNestedSynchronize.java`.
>> 
>> ### Testing
>> 
>> - [GitHub Actions](https://github.com/dlunde/jdk/actions/runs/10178060450)
>> - `tier1` to `tier4` (and additional Oracle-internal testing) on Windows x64, Linux x64, Linux aarch64, macOS x64, and macOS aarch64.
>> - Standard performance benchmarking. No observed conclusive overall performance degradation/improvement.
>> - Specific benchmarking of C2 compilation time. The changes increase C2 compilation time by, approximately and on average, 1% for methods that could also be compiled before this changeset (see the figure below). The reason for the degradation is further checks required in performance-sensitive code (in particular `PhaseChaitin::remove_bound_register_from_interfering_live_ranges`). I have tried optimizing in various ways, but changes I found that lead to improvement also lead to less readable code (and are, in my opinion, no...
>
> Daniel Lundén has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 35 commits:
> 
>  - Restore modified java/lang/invoke tests
>  - Sort includes (new requirement)
>  - Merge remote-tracking branch 'upstream/master' into many-arguments-8325467+pr-updates
>  - Add clarifying comments at definitions of register mask sizes
>  - Fix implicit zero and nullptr checks
>  - Add deep copy comment
>  - Merge remote-tracking branch 'upstream/master' into many-arguments-8325467+pr-updates
>  - Fix typo
>  - Updates after Emanuel's comments
>  - Refactor and improve TestNestedSynchronize.java
>  - ... and 25 more: https://git.openjdk.org/jdk/compare/b39c7369...80c6cf47

Nice, looks like the old test issues are now gone. Great to see that 😊 

I was looking for tests that verify what your PR title promises: that we successfully compile methods with many arguments.

The test you have looks like a good start: `TestMaxMethodArguments.java`

Do you think it would make sense to have more tests? I'm imagining something like this:
- Generate tests with 0-255 arguments. You could use the template framework.
- Take different types (e.g. various primitive types, also those that take 2 stack slots like long and double). You could use the template library `PrimitiveType` if you want.
- Test that we actually get the method compiled. Maybe an IR rule could be used here?
- And do some rudamentary result verification
- Make sure it does not just work with `Xcomp` but also under "normal" circumstances (tiered, profiling, etc).

I'll look a bit at your VM changes now ;)

test/hotspot/jtreg/compiler/arguments/TestMaxMethodArguments.java line 57:

> 55:         try {
> 56:             test(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217
 , 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255);
> 57:         } catch (TestException e) {

This seems to be the only test that actually tests what your PR title promises: it has a method with many arguments.

-------------

Changes requested by epeter (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/20404#pullrequestreview-3172429642
PR Review Comment: https://git.openjdk.org/jdk/pull/20404#discussion_r2313120394


More information about the hotspot-compiler-dev mailing list