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

Split zOS system linkage call dependencies #1307

Merged
merged 2 commits into from
Apr 3, 2018

Conversation

NigelYiboYu
Copy link
Contributor

@NigelYiboYu NigelYiboYu commented Feb 28, 2018

Split the zOS system linkage call dependencies by attaching the
pre-dependencies to the BASR call instruction, and attaching the
post-dependencies to the function call descriptor instruction.

The C XPLINK return will need a NOP after the BASR for entry to valid
instructions. If they are separated by spills, returning from C code can
cause exceptions. Having a post-dependency group after the NOP ensures
that no such spill can happen.

This pull request also contains miscellaneous zOS system linkage code simplifications

1. Simplify NOP and call descriptor generation for zOS system linkage.

2. Use the insetPad() API to insert NOP after the BASR call in system
linkage.

3. Remove the oneliner createCallDescriptor() function.  Do the same thing inline.

4. genCallNOPAndDescriptor() does not have to be virtual. Remove the virtual
keyword.

Signed-off-by: Nigel Yu yunigel@ca.ibm.com

@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch 3 times, most recently from b599808 to 76ae8ba Compare February 28, 2018 21:02
@NigelYiboYu NigelYiboYu closed this Mar 2, 2018
@NigelYiboYu NigelYiboYu reopened this Mar 2, 2018
@NigelYiboYu NigelYiboYu changed the title WIP: Split zOS system linkage call dependencies Split zOS system linkage call dependencies Mar 2, 2018
@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch from 76ae8ba to c46185e Compare March 2, 2018 22:54
@NigelYiboYu
Copy link
Contributor Author

@fjeremic Tested and ready for review.
Travis CI seems to be failing with gzip problems.

@fjeremic fjeremic self-assigned this Mar 2, 2018
@@ -395,24 +395,35 @@ TR::J9S390zOSSystemLinkage::generateInstructionsForCall(TR::Node * callNode, TR:
}
}

gcPoint = generateRRInstruction(codeGen, TR::InstOpCode::BASR, callNode, systemReturnAddressRegister, systemEntryPointRegister, deps);
// NOP padding is needed because return from C function will skip the XPLink eyecatcher and
// always return to a point that's 4 bytes after the return address.
Copy link
Contributor

@fjeremic fjeremic Mar 2, 2018

Choose a reason for hiding this comment

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

This is incorrect. It is 2 bytes after the call instruction BASR (which is itself 2 bytes). SO 4 bytes after the call instruction address, not the return address. The NOP we generate is 2 bytes in length. Can you fix this comment?

Copy link
Contributor Author

@NigelYiboYu NigelYiboYu Mar 2, 2018

Choose a reason for hiding this comment

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

Currently, the JIT generates this for the JNI:

 0d 76                       BASR    GPR7,GPR6  
 47 00 00 51              NOP

The BASR is 2 bytes. And the XPLINK return address in GPR7 is loaded by BASR, and should be pointing at the NOP, which is really a 4-byte branch on condition instruction that does not jump.

As an example, this is what xlc produces when I compile C++ with XPLINK option:

   207 15650ZOS V2.3 z/OS XL C++                                     SimpleCall.cpp: Java_com_jni_c...   02/20/18 12:28:59            5
    208
    209  OFFSET OBJECT CODE        LINE#  FILE#    P S E U D O   A S S E M B L Y   L I S T I N G
    210
    211  000124  987F  480C        000029 |                   LM       r7,r15,2060(r4)
    212  000128  4140  4080        000029 |                   LA       r4,128(,r4)
    213  00012C  47F0  7004        000029 |                   B        4(,r7)

The B 4(,7) instruction is 0x47f07004. It's branch on condition instruction with an unconditional jump mask 0xF. The offset is 4, in bytes.

Copy link
Contributor

@fjeremic fjeremic Mar 3, 2018

Choose a reason for hiding this comment

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

But a few lines below we generate a 2 byte NOP:

//In 64 bit XPLINK, the caller returns at RetAddr+2, so add 2 byte nop
cursor = new (trHeapMemory()) TR::S390NOPInstruction(TR::InstOpCode::NOP, 2, callNode, codeGen);

https://github.com/eclipse/openj9/pull/1307/files#diff-bd656156fc34aa9cbcf33d25dba26a0eR417

So one of these comments has to be incorrect. Looking at the documentation for XPLINK [1] it is indeed 4 bytes in length. We have 0x470XYYYY where X represents the call type which should be 0 as we're generating a BASR and YYYY should technically point to the entry point but this is not an XPLINK frame but a private JIT linkage frame so it too should be 0.

[1] https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.ceev100/cee1v283.htm

Copy link
Contributor Author

@NigelYiboYu NigelYiboYu Mar 4, 2018

Choose a reason for hiding this comment

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

64bit XPLINK uses 2-byte NOP; and 31-bit XPLINK uses 4-byte NOP.
See TR::J9S390zOSSystemLinkage::genCallNOPAndDescriptor()

Copy link
Contributor

@fjeremic fjeremic Mar 5, 2018

Choose a reason for hiding this comment

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

64bit XPLINK uses 2-byte NOP; and 31-bit XPLINK uses 4-byte NOP.

So if XPLINK 64-bit uses a 2 byte NOP and we branch "to a point that's 4 bytes after the return address" wouldn't we branch in the middle of an instruction?

Copy link
Contributor Author

@NigelYiboYu NigelYiboYu Mar 5, 2018

Choose a reason for hiding this comment

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

Sorry, I wasn't clear about this.

The B 4(,7) example I showed you was 31-bit C++ epilogue in XPLINK.
64-bit C++ XPLINK return has a 2-byte offset:

    193  0000F4                    Start of Epilog
    194  0000F4  E370  4818  0004  000029 |                   LG       r7,2072(,r4)
    195  0000FA  4140  4100        000029 |                   LA       r4,256(,r4)
    196  0000FE  47F0  7002        000029 |                   B        2(,r7)

So in our JIT'ed system call, the padding should be 2-byte for 64bit and 4-byte for 31-bit.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, we need to properly document this as it is non-obvious. Could you amend the comment with some of the details regarding 31-bit vs. 64-bit XPLINK and what is expected as well as what the NOP is really supposed to represent (call type, call descriptor, etc.)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated comments in SystemLinkage and CHelperLinkage classes.

if (TR::Compiler->target.is64Bit())
{
//In 64 bit XPLINK, the caller returns at RetAddr+2, so add 2 byte nop
TR::Instruction * cursor = new (trHeapMemory()) TR::S390NOPInstruction(TR::InstOpCode::NOP, 2, callNode, codeGen);
cursor = new (trHeapMemory()) TR::S390NOPInstruction(TR::InstOpCode::NOP, 2, callNode, codeGen);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you use the OMR::Z::CodeGenerator::insertPad API here instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK. I'll try insertPad API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I refactored and simplified the BASR padding function in system linkage class to use insertPad() API. I'm currently running tests.

@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch from c46185e to 23f218f Compare March 5, 2018 15:55
@NigelYiboYu NigelYiboYu changed the title Split zOS system linkage call dependencies WIP: Split zOS system linkage call dependencies Mar 5, 2018
@NigelYiboYu
Copy link
Contributor Author

Re-testing my changes. Marking this as WIP.

@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch 2 times, most recently from bed4bd7 to 5f51f3a Compare March 5, 2018 18:22
@NigelYiboYu NigelYiboYu changed the title WIP: Split zOS system linkage call dependencies Split zOS system linkage call dependencies Mar 6, 2018
//In 31 bit XPLINK, the caller returns at RetAddr+4, so add 4 byte nop with last two bytes
// as signed offset in doublewords at or preceding NOP
uint32_t padSize = TR::Compiler->target.is64Bit() ? 2 : 4;
cursor = nop = new (trHeapMemory()) TR::S390NOPInstruction(TR::InstOpCode::NOP, padSize, node, codeGen);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use the insertPad API here? Also spaces between // and the comment.

@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch from 5f51f3a to 3210262 Compare March 6, 2018 18:28
@NigelYiboYu NigelYiboYu changed the title Split zOS system linkage call dependencies WIP: Split zOS system linkage call dependencies Mar 6, 2018
@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch from 3210262 to 488f09e Compare March 7, 2018 23:27
@NigelYiboYu NigelYiboYu changed the title WIP: Split zOS system linkage call dependencies Split zOS system linkage call dependencies Mar 7, 2018
@NigelYiboYu
Copy link
Contributor Author

Re-tested my changes after using insertPad(). Test passed. @fjeremic

Split the zOS system linkage call dependencies by attaching the
pre-dependencies to the BASR call instruction, and attaching the
post-dependencies to the function call descriptor instruction.

The C XPLINK return will need a NOP after the BASR for entry to valid
instructions. If they are separated by spills, returning from C code can
cause exceptions. Having a post-dependency group after the NOP ensures
that no such spill can happen.

Signed-off-by: Nigel Yu <yunigel@ca.ibm.com>
1. Simplify NOP and call descriptor generation for zOS system linkage.

2. Use the insetPad() API to insert NOP after the BASR call in system
linkage.

3. Remove createCallDescriptor() function and do the same thing inline.

4. genCallNOPAndDescriptor() does not have to be virtual. Remove the virtual
keyword.

Signed-off-by: Nigel Yu <yunigel@ca.ibm.com>
@NigelYiboYu NigelYiboYu force-pushed the system-link-break-deps branch from 488f09e to cc5dc68 Compare March 25, 2018 22:07
@fjeremic
Copy link
Contributor

fjeremic commented Apr 2, 2018

Jenkins test all

@fjeremic
Copy link
Contributor

fjeremic commented Apr 3, 2018

Failures seem infrastructure issues cloning the repos. The Linux s390 passed though which is all that should matter for this change.

@fjeremic fjeremic merged commit 45c7cee into eclipse-openj9:master Apr 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants