Skip to content

Fix GC crash when running portable code on PWR10 CPUs - #17964

Merged
zl-wang merged 1 commit into
eclipse-openj9:masterfrom
klangman:portable-aot-jni-fix
Aug 17, 2023
Merged

Fix GC crash when running portable code on PWR10 CPUs#17964
zl-wang merged 1 commit into
eclipse-openj9:masterfrom
klangman:portable-aot-jni-fix

Conversation

@klangman

Copy link
Copy Markdown
Contributor

When running portable code (CRIU or PortableAOT) on PWR10 CPUs and a method needs to save all non-volatile registers so that GC has access to them (i.e. methods with a Direct-to-JNI call-out) this issue can occur. 1) The portable code will be compiled for PWR8 and therefor does not save R16 since it is dedicated to the PTOC and therefore can never contain a collectible obj ref. 2) A method lower on the stack could have been compiled for PWR10 and used R16 to hold a collectible obj ref. Now if a GC cycle occurs while executing in the JNI code, the GC will retrieve the saved non-volatile registers from the frame of the portable code method (R17-R31). Then it walks the stack looking for collectible references. When it encounters a frame for a PWR10 compiled method that has marked R16 as collectible it will look at its register set and try to access R16. Since the portable code did not save R16 it gets a null reference and crashes.

This fix will force portable code that saves all non-volatile registers for the GC to save and restore R16 even when the target CPU is less then PWR10. In this way, should the portable code be executed on a PWR10 CPU, it will have saved R16 in case some frame down the stack from the portable code's frame uses R16 to hold a collectible obj reference.

When running portable code (CRIU or PortableAOT) on PWR10 CPUs and a
method needs to save all non-volatile registers so that GC has access
to them (i.e. methods with a Direct-to-JNI call-out) this issue can
occur. 1) The portable code will be compiled for PWR8 and therefor does
not save R16 since it is dedicated to the PTOC and therefore can never
contain a collectible obj ref. 2) A method lower on the stack could have
been compiled for PWR10 and used R16 to hold a collectible obj ref. Now
if a GC cycle occurs while executing in the JNI code, the GC will
retrieve the saved non-volatile registers from the frame of the portable
code method (R17-R31). Then it walks the stack looking for collectible
references. When it encounters a frame for a PWR10 compiled method that
has marked R16 as collectible it will look at its register set and try
to access R16. Since the portable code did not save R16 it gets a null
reference and crashes.

This fix will force portable code that saves all non-volatile registers
for the GC to save and restore R16 even when the target CPU is less then
PWR10. In this way, should the portable code be executed on a PWR10 CPU,
it will have saved R16 in case some frame down the stack from the
portable code's frame uses R16 to hold a collectible obj reference.

Signed-off-by: Kevin Langman <langman@ca.ibm.com>

@zl-wang zl-wang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zl-wang

zl-wang commented Aug 16, 2023

Copy link
Copy Markdown
Contributor

Jenkins test sanity plinux,aix jdk8,jdk11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants