[lworld] RFR: 8278390: [lworld] Scalarization of nullable inline types in the calling convention
Tobias Hartmann
thartmann at openjdk.java.net
Thu Apr 21 12:08:48 UTC 2022
This is a large and complex change that extends the calling convention optimization to support nullable types. B2 (value classes) and B3.ref (nullable primitive classes) in arguments and return values are now scalarized, i.e., passed and returned as fields instead of as references. They should now behave like B3.val with the overhead of null-handling.
**Major changes:**
- Use information from the preload attribute to set up the scalarized calling convention at method link time and support it in the interpreter, adapters, stubs, C1 and C2 on x86_64 and aarch64.
- An additional `IsInit` field is passed for each argument to keep track of null. This field will later be re-used to also pass the buffer oop if the value is non-null and buffered (see Limitations section below).
- No additional field is required for returns. Instead, the first register is re-used to hold the `IsInit` information. It now contains either (i) all zero if the value is null, (ii) an oop if the value is non-null and heap buffered or (iii) a tagged klass pointer if the value is non-null and not heap buffered. Since the GC wouldn't be happy to observe a value that can be an oop or a tagged klass pointer, we need to clean it up right after the call. We do this by setting it to zero if it's tagged and extracting the IsInit information into another register. Both can then be used by compiled code. If all registers are occupied by the return values, we put the IsInit information into a reserve stack slot (see logic in the `enc_class call_epilog` in the `.ad` files).
- Many bug fixes (also unrelated ones), new correctness and IR verification tests.
- The long term goal is to get rid of the `InlineTypeNode` / `InlineTypePtrNode` duality in C2. This change makes another step in that direction but there is significant work left.
**Limitations:**
- Similar to scalarization of B3.val in arguments, the buffer oop is currently not passed as "souvenir". This is non-trivial because it requires some effort to ensure that buffer allocations are not kept alive when "escaping" through arguments at calls and will be addressed by a future change.
- Preload attribute mismatches are not yet handled.
- Above issues and all the `// TODO 8284443` comments, will be addressed by the follow-up enhancement [JDK-8284443](https://bugs.openjdk.java.net/browse/JDK-8284443).
Thanks,
Tobias
-------------
Commit messages:
- More fixes
- Fixed null checks on aarch64
- Fixed wrong stack offset on aarch64
- Several bug fixes and corresponding tests
- Initial aarch64 port - still seeing some failures. Added more tests and some refactoring
- Merged with lworld
- Enabled IR verification for a test
- Fixed safepoint poll at return and several other ToDos
- Enabled IR verification for scalarized returns, added more tests, fixed stack allocation of isInit projection
- Restored verifier method
- ... and 18 more: https://git.openjdk.java.net/valhalla/compare/9b9365df...7e94b7e1
Changes: https://git.openjdk.java.net/valhalla/pull/685/files
Webrev: https://webrevs.openjdk.java.net/?repo=valhalla&pr=685&range=00
Issue: https://bugs.openjdk.java.net/browse/JDK-8278390
Stats: 3334 lines in 67 files changed: 2828 ins; 202 del; 304 mod
Patch: https://git.openjdk.java.net/valhalla/pull/685.diff
Fetch: git fetch https://git.openjdk.java.net/valhalla pull/685/head:pull/685
PR: https://git.openjdk.java.net/valhalla/pull/685
More information about the valhalla-dev
mailing list