-
Notifications
You must be signed in to change notification settings - Fork 738
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
Split zOS system linkage call dependencies #1307
Conversation
b599808
to
76ae8ba
Compare
76ae8ba
to
c46185e
Compare
@fjeremic Tested and ready for review. |
@@ -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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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()
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is true. @NigelYiboYu Padding is 2 Bytes for 64-Bit zOS and 4 Bytes for 31-bit zOS.
https://github.com/eclipse/openj9/blob/26f8c7edb1fe37253d001243c0ce14473334d07f/runtime/compiler/trj9/z/codegen/J9S390CHelperLinkage.cpp#L348
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
c46185e
to
23f218f
Compare
Re-testing my changes. Marking this as WIP. |
bed4bd7
to
5f51f3a
Compare
//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); |
There was a problem hiding this comment.
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.
5f51f3a
to
3210262
Compare
3210262
to
488f09e
Compare
Re-tested my changes after using |
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>
488f09e
to
cc5dc68
Compare
Jenkins test all |
Failures seem infrastructure issues cloning the repos. The Linux s390 passed though which is all that should matter for this change. |
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
Signed-off-by: Nigel Yu yunigel@ca.ibm.com