JDK-8305895 proposes using oopDesc::klass_offset_in_bytes() "as a placeholder/identifier of the special memory slice that only LoadNKlass uses" [1] and recovering and adjusting the original OOP from the input memory address to the LoadNKlass node at code emission time.
This use of klass_offset_in_bytes() is problematic, because no value of it can reflect accurately the position of the klass pointer within the mark word when using compact headers. This solution is fragile, unintuitive, and hard to maintain and reason about.
While faking the value of klass_offset_in_bytes() may be acceptable in the context of JEP 450 (an experimental feature) as a way of getting klass loading working in C2 with relatively low effort; a more accurate, robust, and maintainable model independent of klass_offset_in_bytes() should be developed for the non-experimental version of compact headers [2].
A possible alternative is to hide the object header klass pointer extraction and make it part of the LoadNKlass node semantics, as illustrated in the attached example. LoadNKlass nodes can then be expanded into more primitive operations (load and shift for compact headers, load with klass_offset_in_bytes() for original headers) within C2's back-end or even during code emission as sketched here [3].
[1] https://github.com/openjdk/jdk/pull/20677#issue-2480813371
[2] https://github.com/openjdk/jdk/pull/20677#issuecomment-2360756796
[3] https://github.com/robcasloz/jdk/commit/6cb4219f101e3be982264071c2cb1d0af1c6d754