Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline Class.getComponentType and refactor IL generation to access classDepthAndFlags field of j9Class #19558

Conversation

hzongaro
Copy link
Member

This change generates inline IL in Value Propagation for references to Class.getComponentType(). That method was previously only inlined if the Class was known at compile-time. If the Class is known to be an array class at compile-time, the generated IL will load the <componentClass> from the j9ArrayClass; otherwise, it will generate a run-time test of whether the Class is an array class before returning the <componentClass> or a null reference.

Calls to Object.getClass() are also marked as non-null during IL generation as that method is known to always return a non-null reference. That exposes opportunities to optimize uses of Class objects that require the reference to be known to be non-null, including inlining calls to Class.getComponentType() in Value Propagation.

Also, there are several places in the JIT compiler that generate IL to access the classDepthAndFlags field of j9class. This introduces methods in TR_J9VMBase to do that, as has previously been done with some methods that generate IL to access the classFlags field.

Finally, this change also deals with some typos in methods that refer to classDepthAndFlags incorrectly as classAndDepthFlags. One instance, J9::SymbolReferenceTable::findOrCreateClassAndDepthFlagsSymbolRef, will remain until its upstream use in J9_PROJECT_SPECIFIC code in OMR is removed in pull request eclipse/omr#7334.

Several methods in the JIT compiler use the name of the
classDepthAndFlags field of J9Class in their names, but they incorrectly
refer to it as classAndDepthFlags.  This commit corrects the
typographical errors in the naming of those methods, but keeps one
instance that is used upstream in J9_PROJECT_SPECIFIC code in OMR until
that can be removed.
Various places in the compiler need to generate IL to load the
classDepthAndFlags field of j9class.  Those locations need to take into
account whether the target platform is 32-bit or 64-bit, as it affects
the width of the field.  Introducing methods in TR_J9VMBase to load
the field and potentially test the settings of bits in it hides some of
that.
@hzongaro
Copy link
Member Author

@0xdaryl and @vijaysun-omr, may I ask you to review this change?

This pull request should be considered in conjunction with the upstream draft pull request eclipse/omr#7334, as that pull request uses the new TR_J9VMBase::testIsClassArrayType method.

One thing I want to point out is that TR_J9VMBase::testIsClassArrayType will produce IL that masks the relevant flags field to yield a non-zero int32 value if the class is an array type, or zero if it is not an array type. That's consistent with the existing testIsClassValueType, testIsClassPrimitiveValueType and testIsClassIdentityType methods in TR_J9VMBase. However, the places where the IL produced by testIsClassArrayType is used sometimes generate IL to compare the result to zero, compare it to the value of the mask, or right-shift it an appropriate amount to yield a result of zero or one.

The question is whether it's worthwhile continuing to use the result in all three of those ways, or whether all the places that use the result of that IL should just test whether the result of masking is equal to zero, or just test whether the result is equal to the mask. If we preserve all three, it would probably make sense to hide those possibilities inside testIsClassArrayType itself, rather than having the caller in the second and third cases worry about what mask value it should use. And if we preserve all three, it would make sense to update testIsClassValueType, testIsClassPrimitiveValueType and testIsClassIdentityType to allow for the same possibilities for consistency.

@vijaysun-omr
Copy link
Contributor

If the assert discussed is added, I will run testing and approve. Thanks

@hzongaro
Copy link
Member Author

If the assert discussed is added, I will run testing and approve. Thanks

I added that assertion in commit df1f93b. If you are OK with the change, I will squash that commit down.

One thing I want to point out is that TR_J9VMBase::testIsClassArrayType will produce IL that masks the relevant flags field to yield a non-zero int32 value if the class is an array type, or zero if it is not an array type. That's consistent with the existing testIsClassValueType, testIsClassPrimitiveValueType and testIsClassIdentityType methods in TR_J9VMBase. However, the places where the IL produced by testIsClassArrayType is used sometimes generate IL to compare the result to zero, compare it to the value of the mask, or right-shift it an appropriate amount to yield a result of zero or one.

Regarding this point, I discussed with both @0xdaryl and @vijaysun-omr off-line, and there was consensus that producing a zero/non-zero result and comparing that with zero make the most sense and likely yields the best performance. I will make that change in a follow-on pull request (possibly optionally allowing the result to be shifted to yield a result of zero or one.)

@vijaysun-omr
Copy link
Contributor

Thanks, assert looks good to me. If you squash, I will run testing and consider merge.

Check for the opportunity to inline calls to Class.getComponentType,
using the underlying j9ArrayClass.  In particular, if the Class is known
to be an array class, the test for the J9AccClassArray flag in the
classDepthAndFlags field can be skipped.

Also, mark Object.getClass() as non-null during IL Generation.  That
prevents a NULLCHK from being being generated for the Class reference in
an expression like o.getClass().getComponentType().  The presence of the
NULLCHK would inhibit this transformation.
@hzongaro hzongaro force-pushed the inline-getComponentType-access-classDepthAndFlags branch from df1f93b to c34c2b5 Compare May 30, 2024 01:41
@hzongaro
Copy link
Member Author

If you squash, I will run testing and consider merge.

Squashed. Thanks!

@vijaysun-omr
Copy link
Contributor

Jenkins test sanity.functional all jdk8,jdk21

@hzongaro
Copy link
Member Author

hzongaro commented May 30, 2024

JDK 21 aarch64 mac build failed with the following error. This has been seen in builds before, and is unrelated to this change. Restarting.

IOException caught during compilation: Server failed to initialize: Resource deadlock avoided

JDK 8 x86-64 Linux sanity.functional failure appears to be infrastructure-related. Restarting.

@hzongaro
Copy link
Member Author

Jenkins test sanity.functional jdk21 amac

@hzongaro
Copy link
Member Author

Jenkins test sanity.functional jdk8 xlinux

@hzongaro
Copy link
Member Author

Sigh! Swapped versions and platforms.

Jenkins test sanity.functional amac jdk21

@hzongaro
Copy link
Member Author

Jenkins test sanity.functional xlinux jdk8

@hzongaro
Copy link
Member Author

It looks like all recent pull request testing for x86-64 Linux JDK 8 are hitting similar infrastructure issues as were encountered for this pull request.

@vijaysun-omr
Copy link
Contributor

Given that this is a cross-platform fix, and all JDK21 testing has passed, I am going to merge this.

@vijaysun-omr vijaysun-omr merged commit ff7726e into eclipse-openj9:master May 30, 2024
29 of 31 checks passed
@pshipton
Copy link
Member

xlinux should be fixed now.

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.

3 participants