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

Add full support for calls on z/OS and enable corresponding tests #4907

Merged
merged 17 commits into from
Apr 2, 2020

Conversation

fjeremic
Copy link
Contributor

@fjeremic fjeremic commented Mar 6, 2020

This PR contains a series of commits which enables full support for JIT <-> native calls on z/OS. The change appears rather large due to the amount of test code that was enhanced to validate the support. There was also other issues encountered during development which were fixed. Please see the commit descriptions for details on what each change does and why.

The "meat" of the support can be found in the two commits titled:

  • "Create the XPLINK Function Descriptor for OMR compiled bodies on z/OS"
  • "Use method symbol address to get the entry point in Tril and JitBuilder"

These two commits give us the support and are not very large changes all in all.

Issue: #4719

@fjeremic
Copy link
Contributor Author

fjeremic commented Mar 6, 2020

Leaving this in draft mode as I still need to validate that I haven't broken OpenJ9 on z/OS, which I most certainly have, but the fix will be simple as soon as I test it. In the mean while this should be ready for review. I'll proceed and self-review the change to note the most important design decisions which we can discuss here.

@genie-omr build all

@@ -379,7 +379,7 @@ compileMethodFromDetails(
// not ready yet...
//OMR::MethodMetaDataPOD *metaData = fe.createMethodMetaData(&compiler);

startPC = compiler.cg()->getCodeStart();
startPC = (uint8_t*)compiler.getMethodSymbol()->getMethodAddress();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was the main change in thinking here. See the commit body (ab6d6a4) for a full description of why we made this change.

Copy link
Contributor Author

@fjeremic fjeremic Mar 6, 2020

Choose a reason for hiding this comment

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

To be explicit this is a design decision which I'd like @mstoodle and @aviansie-ben to comment on, and perhaps @Leonardo2718 as well. It is unfortunate we don't have a public API, because in that case getCodeStart would likely be a private API internal to the compiler, and we would only provide one public API to extract the "pointer to a function" we compiled with OMR.

Do we agree with this approach? If not, any suggestions on an alternative?

Copy link
Contributor

Choose a reason for hiding this comment

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

This approach seems fine to me.

I agree that having a single public API to extract the function pointer would be ideal. But I don't think that's a problem that needs to be solved here. The approach you've taken is reasonable given what we currently have, IMHO.

Comment on lines 592 to 596
genLoadAddressConstant(cg(), callNode, reinterpret_cast<uintptrj_t>(fd), epReg);
generateRSInstruction(cg(), TR::InstOpCode::getLoadMultipleOpCode(), callNode, aeReg, epReg, generateS390MemoryReference(epReg, 0, cg()));

TR::Instruction* callInstr = new (cg()->trHeapMemory()) TR::S390RILInstruction(TR::InstOpCode::BRASL, callNode, raReg, fd->func, callSymRef, cg());
callInstr->setDependencyConditions(preDeps);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Loads the function's address from the function descriptor and dispatches the call.

Comment on lines -192 to -204
#if defined(J9ZOS390)
struct FunctionDescriptor
{
uint64_t environment;
void* func;
};

FunctionDescriptor* fd = new FunctionDescriptor();
fd->environment = 0;
fd->func = *entry;

*entry = (void*) fd;
#elif defined(AIXPPC)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Finally! This hack is now removed and we don't need to do anything special for z/OS. Once AIX gets support we can also remove the AIX piece as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sweet!

Comment on lines +342 to +347

// The file we generate here is in the PPM image format which has a simple header describing how to interpret the
// buffer. This string needs to be encoded as ASCII in the file generated, however on platforms such as z/OS whose
// native encoding is not ASCII this is problematic.
//
// TODO (#4901): Use the port library to output the header bytes for PPM image file format
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Linking this PR with #4901 so GitHub notes the link for future whenever we fix this.

@fjeremic
Copy link
Contributor Author

fjeremic commented Mar 6, 2020

Also suggesting @aviansie-ben for review as well as I cannot tag him on the GitHub interface.

Comment on lines -199 to -202
if (comp->getCurrentMethod() == NULL)
{
comp->getMethodSymbol()->setMethodAddress(cg->getBinaryBufferStart());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This piece of code was alarming to me. Does anyone know why this exists? And why is it guarded by a getCurrentMethod null check? When would this value ever be NULL?

}
cg->getAheadOfTimeCompile()->dumpRelocationData();
traceMsg(comp, "</relocatableDataCG>\n");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

any chance you could split these changes into a separate commit? they interfere with appreciating the setup you've made here for a much better solution to the FD issue.

Copy link
Contributor Author

@fjeremic fjeremic Mar 6, 2020

Choose a reason for hiding this comment

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

The reason this formatting change was made is because the indentation in it's current state is very confusing [1], and at first sight one may think the:

     if (comp->getCurrentMethod() == NULL)
        {
        comp->getMethodSymbol()->setMethodAddress(cg->getBinaryBufferStart());
        }

piece of code is guarded by the if (cg->getAheadOfTimeCompile() && check, which is what I first thought, but upon a more careful inspection the indentation was hiding this is not the case.

If you wish to view that commit without whitespace changes GitHub can help here:
ab6d6a4?w=1

[1] https://github.com/eclipse/omr/blob/31db81f3d84a431736ac7a9ff1b3980158fae258/compiler/codegen/OMRCodeGenPhase.cpp#L182-L202

Copy link
Contributor Author

@fjeremic fjeremic Mar 6, 2020

Choose a reason for hiding this comment

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

On second thought, I think I agree. For history of commits it would be beneficial to split up formatting from actual changes.

I've split up the actual change into 6e902d5, where it belongs, and the formatting change into 27349e8. Hope that helps!

@fjeremic
Copy link
Contributor Author

fjeremic commented Mar 6, 2020

@genie-omr build all

@fjeremic
Copy link
Contributor Author

fjeremic commented Mar 9, 2020

Just remembered my comment [1] to myself to revert some tests we disabled because of the lack of support for callouts. Now that we have them we can re-enable the tests.

[1] #4719 (comment)

@fjeremic
Copy link
Contributor Author

fjeremic commented Mar 9, 2020

@genie-omr build all

@fjeremic
Copy link
Contributor Author

Leaving this in draft mode as I still need to validate that I haven't broken OpenJ9 on z/OS, which I most certainly have, but the fix will be simple as soon as I test it.

Much to my surprise I was wrong. OpenJ9 works fine with this change. The reason is because generateInstructionsForCall is a virtual method [1] and OpenJ9 overrides this in it's JNI linkage, which inherits the XPLINK system linkage on z/OS [2].

I've validated OpenJ9 works perfectly fine with this change, hence I'm marking this PR as ready for review/merging.

[1] https://github.com/eclipse/omr/blob/b03105e81b1b020900afbb2871cbd45aaaf8048c/compiler/z/codegen/SystemLinkage.hpp#L118-L120
[2] https://github.com/eclipse/openj9/blob/e8215634090734f30ba084a83089b58dbe579a3b/runtime/compiler/z/codegen/J9SystemLinkagezOS.cpp#L65-L218

@fjeremic fjeremic marked this pull request as ready for review March 10, 2020 19:55
In this change we rewrite the Call sample with a few enhancements to
introduce all call types:

- JIT to JIT
- JIT to native
- JIT to computed native
- Native to JIT

The test computation is still the same, i.e. we still compute a double
sum, however we do it in several different ways so as to test calls
both to and from JIT/native to ensure all paths are working as expected.

This is particularly useful for platforms which have special handling
of function pointers, such as AIX and z/OS.

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
Now that we have full support for calls on z/OS we can safely enable
all Tril tests which were previously disabled.

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
OMR nor any downstream projects support 31-bit XPLINK to OS linkage,
and the support is also not present in the rest of the compiler. This
code block is slated for deprecation as we don't anticipate it being
used.

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
The path for loading double arguments for outgoing calls was disabled
within the `J9_PROJECT_SPECIFIC` ifdef, and as such double arguments
were not being loaded for outgoing calls.

We fix this by moving the case label outside of the ifdef. In addition
there is no need to check for `getNumIntegerArgumentRegisters` before
incrementing the GPR index, similarly to the integer cases since the
`getIntegerArgumentRegister` API will already return the default value
if the register index does not participate in the calling convention.

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
@fjeremic
Copy link
Contributor Author

I had to rebase to absorb the changes in #4821 to use the new SKIP_ON_<ARCH> helpers in LinkageTest.cpp and MinimalTest.cpp. Rest of the change is as before.

@genie-omr build all

@fjeremic fjeremic requested a review from mstoodle March 13, 2020 16:43
Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
@fjeremic
Copy link
Contributor Author

I had to rebase again to fix conflicts introduced by removal of uintptrj_t in #4931. Launching builds again:

@genie-omr build all

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
@fjeremic
Copy link
Contributor Author

@genie-omr build all

@fjeremic
Copy link
Contributor Author

@mstoodle @0xdaryl @Leonardo2718 any takers for a committer for this one?

@fjeremic
Copy link
Contributor Author

As per comment by @mstoodle (#4964 (comment)) I've added the patch from #4909 to this PR in 2e7226c so we have test coverage. Launching builds again.

@genie-omr build all

@fjeremic
Copy link
Contributor Author

Looks like there are issues on the following builds:
https://ci.eclipse.org/omr/job/PullRequest-linux_x86-64/2027/
https://ci.eclipse.org/omr/job/PullRequest-osx_x86-64/1581/

I'm going to back out 2e7226c from this PR and reopen #4909 for further investigation.

Copy link
Contributor

@Leonardo2718 Leonardo2718 left a comment

Choose a reason for hiding this comment

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

I'm not done reviewing this yet, but here are some comments I have so far. Mostly minor stuff that doesn't necessarily have to be addressed here. I just wanted to write down my thoughts so far so I don't forget.

compiler/z/codegen/OMRLinkage.cpp Outdated Show resolved Hide resolved
fvtest/compilertriltest/LinkageTest.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@Leonardo2718 Leonardo2718 left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@fjeremic I'm fine with the changes as they are. I did have a few questions but they are minor enough they don't need to be addressed here. I'll let you decide what to do with them.

fvtest/compilertriltest/LinkageTest.cpp Outdated Show resolved Hide resolved
TypeToString<TypeParam>::type, // args
TypeToString<TypeParam>::prefix, // return
TypeToString<TypeParam>::prefix, //call
reinterpret_cast<uintmax_t>(static_cast<TypeParam(*)(TypeParam)>(callee_entry_point)), // address
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm.... I'm not completely sure if that inner static_cast is needed.

As I recall, that cast is needed to work around a bug in MSVC (I think) involving incorrect handling of pointers to template functions. Technically, callee_entry_point is not a template function. However, it's type is template type dependent. So, I'm not sure if it triggers the same bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right. All the builds passed. Fixed in 11c8008

Copy link
Contributor

Choose a reason for hiding this comment

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

If it worked in this one location, I would think that it should also work for every other test that uses callee_entry_point.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. I've force pushed the fix to cover all uses in fa96327

}

template <typename T>
T (*getJitCompiledMethodReturning1stArgument())(T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Man, gotta love that function signature 😝

@@ -379,7 +379,7 @@ compileMethodFromDetails(
// not ready yet...
//OMR::MethodMetaDataPOD *metaData = fe.createMethodMetaData(&compiler);

startPC = compiler.cg()->getCodeStart();
startPC = (uint8_t*)compiler.getMethodSymbol()->getMethodAddress();
Copy link
Contributor

Choose a reason for hiding this comment

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

This approach seems fine to me.

I agree that having a single public API to extract the function pointer would be ideal. But I don't think that's a problem that needs to be solved here. The approach you've taken is reasonable given what we currently have, IMHO.

@fjeremic
Copy link
Contributor Author

@Leonardo2718 thanks for the review. I still want to address your earlier points. I think there is no better time do implement such work than now. I'll have fixes for those in the next day. Apologies for the slow progress.

@Leonardo2718
Copy link
Contributor

Apologies for the slow progress.

Well, if we're going to apologize for slow progress, I should apologies for taking so long to review. 😅

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
@fjeremic fjeremic force-pushed the jitbuilder-native branch 2 times, most recently from 6ea5f84 to 13a5b43 Compare March 31, 2020 16:43
@fjeremic
Copy link
Contributor Author

@genie-omr build all

@fjeremic
Copy link
Contributor Author

fjeremic commented Mar 31, 2020

All review comments addressed. Please see each review for a reference to a commit which addresses the review concern. @Leonardo2718 do you want to be a committer for this one?

@Leonardo2718 Leonardo2718 self-assigned this Mar 31, 2020
Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
These helper macros will skip tests based on architecture and operating
system combinations.

Signed-off-by: Filip Jeremic <fjeremic@ca.ibm.com>
Copy link
Contributor

@Leonardo2718 Leonardo2718 left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@Leonardo2718
Copy link
Contributor

@genie-omr build all

I want to merge this tomorrow by EOD. If anyone still wants to review this change, please speak up before then.

@Leonardo2718
Copy link
Contributor

Times up! Merging now.

@Leonardo2718 Leonardo2718 merged commit 3240dfd into eclipse-omr:master Apr 2, 2020
@fjeremic fjeremic deleted the jitbuilder-native branch April 2, 2020 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants