Skip to content

Commit 27118b0

Browse files
committed
Build JNI IFA switching helpers as C calls
The JNI IFA switching on and off helpers use transition assembly sequences that saves and restores all GPRs, all FPRs and volatile VRFs. This is slow and unnecessary. This commit changes builds IFA calls as C function calls, which saves only the assigned registers. Signed-off-by: Nigel Yu <[email protected]>
1 parent 2008d20 commit 27118b0

20 files changed

+1304
-795
lines changed

runtime/codert_vm/armnathelp.m4

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,6 @@ UNUSED(jitNewPackedArray)
366366
UNUSED(jitResolvePackedArrayFieldLength)
367367
UNUSED(jitResolveIsPackedFieldNested)
368368
UNUSED(jitNewObjectNoTenantInit)
369-
UNUSED(jitPostJNICallOffloadCheck)
370-
UNUSED(jitPreJNICallOffloadCheck)
371369
UNUSED(jitFindFieldSignatureClass)
372370
UNUSED(icallVMprJavaSendInvokeWithArgumentsHelperL)
373371
UNUSED(j2iInvokeWithArguments)

runtime/codert_vm/cnathelp.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,7 +2177,7 @@ old_slow_jitCallCFunction(J9VMThread *currentThread)
21772177
}
21782178

21792179
void
2180-
fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread)
2180+
fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread, J9Method *method)
21812181
{
21822182
#if defined(J9VM_OPT_JAVA_OFFLOAD_SUPPORT)
21832183
OLD_JIT_HELPER_PROLOGUE(0);
@@ -2189,12 +2189,12 @@ fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread)
21892189
els->calloutVMState = setVMState(currentThread, J9VMSTATE_JNI_FROM_JIT);
21902190
}
21912191
#endif /* J9VM_PORT_ZOS_CEEHDLRSUPPORT */
2192-
VM_VMHelpers::beforeJNICall(currentThread);
2192+
VM_VMHelpers::beforeJNICall(currentThread, method);
21932193
#endif /* J9VM_OPT_JAVA_OFFLOAD_SUPPORT */
21942194
}
21952195

21962196
void
2197-
fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread)
2197+
fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread, J9Method* method)
21982198
{
21992199
#if defined(J9VM_OPT_JAVA_OFFLOAD_SUPPORT)
22002200
OLD_JIT_HELPER_PROLOGUE(0);
@@ -2209,7 +2209,7 @@ fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread)
22092209
}
22102210
}
22112211
#endif /* J9VM_PORT_ZOS_CEEHDLRSUPPORT */
2212-
VM_VMHelpers::afterJNICall(currentThread);
2212+
VM_VMHelpers::afterJNICall(currentThread, method);
22132213
#endif /* J9VM_OPT_JAVA_OFFLOAD_SUPPORT */
22142214
}
22152215

runtime/codert_vm/pnathelp.m4

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,6 @@ UNUSED(jitNewPackedArray)
411411
UNUSED(jitResolvePackedArrayFieldLength)
412412
UNUSED(jitResolveIsPackedFieldNested)
413413
UNUSED(jitNewObjectNoTenantInit)
414-
UNUSED(jitPostJNICallOffloadCheck)
415-
UNUSED(jitPreJNICallOffloadCheck)
416414
UNUSED(jitFindFieldSignatureClass)
417415
UNUSED(icallVMprJavaSendInvokeWithArgumentsHelperL)
418416
UNUSED(j2iInvokeWithArguments)

runtime/codert_vm/xnathelp.m4

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,6 @@ UNUSED(jitNewPackedArray)
465465
UNUSED(jitResolvePackedArrayFieldLength)
466466
UNUSED(jitResolveIsPackedFieldNested)
467467
UNUSED(jitNewObjectNoTenantInit)
468-
UNUSED(jitPostJNICallOffloadCheck)
469-
UNUSED(jitPreJNICallOffloadCheck)
470468
UNUSED(jitFindFieldSignatureClass)
471469
UNUSED(icallVMprJavaSendInvokeWithArgumentsHelperL)
472470
UNUSED(j2iInvokeWithArguments)

runtime/codert_vm/znathelp.m4

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -422,38 +422,6 @@ BEGIN_FUNC(jitRunOnJavaStack)
422422
BRANCH_VIA_VMTHREAD(J9TR_VMThread_tempSlot)
423423
END_CURRENT
424424

425-
dnl When the offload helpers are called,
426-
dnl the java SP is already stored in the J9VMThread.
427-
428-
BEGIN_HELPER(jitPreJNICallOffloadCheck)
429-
ifdef({ASM_J9VM_PORT_ZOS_CEEHDLRSUPPORT},{
430-
std fpr8,JIT_FPR_SAVE_OFFSET(8)(CSP)
431-
std fpr9,JIT_FPR_SAVE_OFFSET(9)(CSP)
432-
std fpr10,JIT_FPR_SAVE_OFFSET(10)(CSP)
433-
std fpr11,JIT_FPR_SAVE_OFFSET(11)(CSP)
434-
std fpr12,JIT_FPR_SAVE_OFFSET(12)(CSP)
435-
std fpr13,JIT_FPR_SAVE_OFFSET(13)(CSP)
436-
std fpr14,JIT_FPR_SAVE_OFFSET(14)(CSP)
437-
std fpr15,JIT_FPR_SAVE_OFFSET(15)(CSP)
438-
stfpc CEEHDLR_FPC_SAVE_OFFSET(CSP)
439-
})
440-
SAVE_ALL_REGS(jitPreJNICallOffloadCheck)
441-
LR_GPR CARG1,J9VMTHREAD
442-
LOAD_LABEL_CONSTANT($1, fast_jitPreJNICallOffloadCheck, CARG2)
443-
CALL_INDIRECT(CARG2)
444-
RESTORE_ALL_REGS_AND_SWITCH_TO_JAVA_STACK(jitPreJNICallOffloadCheck)
445-
br r14
446-
END_CURRENT
447-
448-
BEGIN_HELPER(jitPostJNICallOffloadCheck)
449-
SAVE_ALL_REGS(jitPostJNICallOffloadCheck)
450-
LR_GPR CARG1,J9VMTHREAD
451-
LOAD_LABEL_CONSTANT($1, fast_jitPostJNICallOffloadCheck, CARG2)
452-
CALL_INDIRECT(CARG2)
453-
RESTORE_ALL_REGS_AND_SWITCH_TO_JAVA_STACK(jitPostJNICallOffloadCheck)
454-
br r14
455-
END_CURRENT
456-
457425
dnl When the VM access helpers are called,
458426
dnl the java SP is already stored in the J9VMThread.
459427

runtime/compiler/build/files/target/z.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ JIT_PRODUCT_SOURCE_FILES+=\
6565
compiler/z/codegen/J9MemoryReference.cpp \
6666
compiler/z/codegen/J9S390CHelperLinkage.cpp \
6767
compiler/z/codegen/J9S390PrivateLinkage.cpp \
68+
compiler/z/codegen/J9S390JNILinkage.cpp \
6869
compiler/z/codegen/J9S390Snippet.cpp \
6970
compiler/z/codegen/J9S390SystemLinkage.cpp \
7071
compiler/z/codegen/J9TreeEvaluator.cpp \

runtime/compiler/runtime/Runtime.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ extern "C" void mcc_reservationAdjustment_unwrapper(void **argsPtr, void **resPt
195195
extern "C" void mcc_lookupHelperTrampoline_unwrapper(void **argsPtr, void **resPtr);
196196
#endif
197197

198+
extern "C" void fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread, J9Method *method);
199+
extern "C" void fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread, J9Method *method);
200+
198201
JIT_HELPER(icallVMprJavaSendNativeStatic);
199202
JIT_HELPER(icallVMprJavaSendStatic0);
200203
JIT_HELPER(icallVMprJavaSendStatic1);
@@ -623,8 +626,6 @@ JIT_HELPER(_nativeStaticHelper);
623626
JIT_HELPER(jitLookupInterfaceMethod);
624627
JIT_HELPER(jitMethodIsNative);
625628
JIT_HELPER(jitMethodIsSync);
626-
JIT_HELPER(jitPreJNICallOffloadCheck);
627-
JIT_HELPER(jitPostJNICallOffloadCheck);
628629
JIT_HELPER(jitResolveClass);
629630
JIT_HELPER(jitResolveClassFromStaticField);
630631
JIT_HELPER(jitResolveField);
@@ -1592,8 +1593,8 @@ void initializeCodeRuntimeHelperTable(J9JITConfig *jitConfig, char isSMP)
15921593
SET(TR_S390arrayORHelper, (void *) 0, TR_Helper);
15931594
SET(TR_S390arrayANDHelper, (void *) 0, TR_Helper);
15941595
SET(TR_S390collapseJNIReferenceFrame, (void *) jitCollapseJNIReferenceFrame, TR_Helper);
1595-
SET(TR_S390jitPreJNICallOffloadCheck, (void *) jitPreJNICallOffloadCheck, TR_Helper);
1596-
SET(TR_S390jitPostJNICallOffloadCheck, (void *) jitPostJNICallOffloadCheck, TR_Helper);
1596+
SET(TR_S390jitPreJNICallOffloadCheck, (void *) fast_jitPreJNICallOffloadCheck, TR_CHelper);
1597+
SET(TR_S390jitPostJNICallOffloadCheck, (void *) fast_jitPostJNICallOffloadCheck, TR_CHelper);
15971598
SET(TR_S390jitCallCFunction, (void *) jitCallCFunction, TR_Helper);
15981599
SET(TR_S390OutlinedNew, (void *) outlinedNewObject, TR_Helper);
15991600
SET(TR_S390OutlinedNewArray, (void *) outlinedNewArray, TR_Helper);

runtime/compiler/runtime/Runtime.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2017 IBM Corp. and others
2+
* Copyright (c) 2000, 2018 IBM Corp. and others
33
*
44
* This program and the accompanying materials are made available under
55
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -87,6 +87,12 @@ inline uint32_t getJitEntryOffset(TR_LinkageInfo *linkageInfo)
8787
#define OFFSET_COUNTING_BRANCH_FROM_JITENTRY 36
8888
#endif
8989

90+
#ifdef J9ZOS390
91+
#define TRS390_TOC_UNWRAP_ENV(wrappedPointer) (((J9FunctionDescriptor_T *) (wrappedPointer))->ada)
92+
#else
93+
#define TRS390_TOC_UNWRAP_ENV(wrappedPointer) (void*)0xdeafbeef
94+
#endif
95+
9096
/* Functions used by AOT runtime to fixup recompilation info for AOT */
9197
#if defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || (defined(TR_HOST_ARM))
9298
uint32_t *getLinkageInfo(void * startPC);

runtime/compiler/runtime/asmprotos.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ JIT_HELPER(jitNewArray); // asm calling-convention helper
8686
JIT_HELPER(jitNewInstanceImplAccessCheck); // asm calling-convention helper
8787
JIT_HELPER(jitNewObject); // asm calling-convention helper
8888
JIT_HELPER(jitObjectHashCode); // asm calling-convention helper
89-
JIT_HELPER(jitPostJNICallOffloadCheck); // asm calling-convention helper
90-
JIT_HELPER(jitPreJNICallOffloadCheck); // asm calling-convention helper
9189
JIT_HELPER(jitReleaseVMAccess); // asm calling-convention helper
9290
JIT_HELPER(jitReportMethodEnter); // asm calling-convention helper
9391
JIT_HELPER(jitReportMethodExit); // asm calling-convention helper

runtime/compiler/z/codegen/J9CodeGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@
3939
#include "env/jittypes.h"
4040
#include "il/Node.hpp"
4141
#include "il/Node_inlines.hpp"
42+
#include "z/codegen/J9S390JNILinkage.hpp"
4243
#include "z/codegen/J9S390PrivateLinkage.hpp"
4344
#include "z/codegen/J9S390SystemLinkage.hpp"
4445
#include "z/codegen/J9S390CHelperLinkage.hpp"
4546
#include "z/codegen/S390GenerateInstructions.hpp"
4647
#include "z/codegen/S390Recompilation.hpp"
4748
#include "z/codegen/S390Register.hpp"
48-
#include "z/codegen/J9S390PrivateLinkage.hpp"
4949
#include "z/codegen/ReduceSynchronizedFieldLoad.hpp"
5050

5151
#define OPT_DETAILS "O^O CODE GENERATION: "

runtime/compiler/z/codegen/J9S390CHelperLinkage.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -259,21 +259,17 @@ class RealRegisterManager
259259
TR::CodeGenerator* _cg;
260260
};
261261

262-
/** \brief Build a JIT helper call.
263-
* \details
264-
* It generates sequence that prepares parameters for the JIT helper function and generate a helper call.
265-
* \param callNode The node for which you are generating a heleper call
266-
* \param deps The pre register dependency conditions that will be filled by this function to attach within ICF
267-
* \param returnReg TR::Register* allocated by consumer of this API to hold the result of the helper call,
268-
* If passed, this function uses it to store return value from helper instead of allocating new register
269-
* \return TR::Register *helperReturnResult, gets the return value of helper function and return to the evaluator.
270-
*/
271-
TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode, TR::RegisterDependencyConditions **deps, TR::Register *returnReg)
262+
TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode,
263+
TR::RegisterDependencyConditions **deps,
264+
TR::Register *returnReg,
265+
bool forceFastPath)
272266
{
273267
RealRegisterManager RealRegisters(cg());
274268
bool isHelperCallWithinICF = deps != NULL;
275-
// TODO: Currently only jitInstanceOf is fast path helper. Need to modify following condition if we add support for other fast path only helpers
276-
bool isFastPathOnly = callNode->getOpCodeValue() == TR::instanceof;
269+
// TODO: Currently only jitInstanceOf and IFA helper calls are fast path helpers. Need to modify following condition if we add support for other fast path only helpers
270+
// Having a fast path helper call also implies that there is no environment pointer setup in GPR5
271+
bool isFastPathOnly = callNode->getOpCodeValue() == TR::instanceof || forceFastPath;
272+
277273
traceMsg(comp(),"%s: Internal Control Flow in OOL : %s\n",callNode->getOpCode().getName(),isHelperCallWithinICF ? "true" : "false" );
278274
for (int i = TR::RealRegister::FirstGPR; i <= TR::RealRegister::LastHPR; i++)
279275
{
@@ -344,6 +340,7 @@ TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode,
344340
// Storing Java Stack Pointer
345341
javaStackPointerRegister = cg()->getStackPointerRealRegister();
346342
cursor = generateRXInstruction(cg(), TR::InstOpCode::getStoreOpCode(), callNode, javaStackPointerRegister, generateS390MemoryReference(vmThreadRegister, offsetJ9SP, cg()));
343+
347344
#if defined(J9ZOS390)
348345
padding += 2;
349346
// Loading DSAPointer Register
@@ -364,6 +361,21 @@ TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode,
364361
}
365362
TR::SymbolReference * callSymRef = callNode->getSymbolReference();
366363
void * destAddr = callNode->getSymbolReference()->getSymbol()->castToMethodSymbol()->getMethodAddress();
364+
365+
#if defined(J9ZOS390)
366+
// Fast path helper calls are real C function calls, whereas non-fast-path calls jump to picBuilder glue code
367+
// glue code does its own environment handling and does not need a environment loading here.
368+
if(isFastPathOnly)
369+
{
370+
TR_RuntimeHelper helperIndex = static_cast<TR_RuntimeHelper>(callNode->getSymbolReference()->getReferenceNumber());
371+
TR_ASSERT_FATAL(helperIndex < TR_S390numRuntimeHelpers, "Invalid helper index in c helper node\n");
372+
373+
// XPLINK GPR5 is an environment register.
374+
intptrj_t environment = reinterpret_cast<intptrj_t>(TOC_UNWRAP_ENV(runtimeHelpers.getFunctionPointer(helperIndex)));
375+
genLoadAddressConstant(cg(), callNode, environment, javaStackPointerRegister);
376+
}
377+
#endif
378+
367379
cursor = new (cg()->trHeapMemory()) TR::S390RILInstruction(TR::InstOpCode::BRASL, callNode, regRA, destAddr, callSymRef, cg());
368380
cursor->setDependencyConditions(preDeps);
369381
if (isFastPathOnly)

runtime/compiler/z/codegen/J9S390CHelperLinkage.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2017 IBM Corp. and others
2+
* Copyright (c) 2000, 2018 IBM Corp. and others
33
*
44
* This program and the accompanying materials are made available under
55
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -122,6 +122,21 @@ class S390CHelperLinkage : public TR::Linkage
122122
return buildDirectDispatch(callNode, NULL, returnReg);
123123
}
124124

125-
TR::Register *buildDirectDispatch(TR::Node *callNode, TR::RegisterDependencyConditions** deps, TR::Register *returnReg=NULL);
125+
/** \brief
126+
* It generates a sequence that prepares parameters for the JIT helper function and generate a
127+
* direct call to a C helper function.
128+
*
129+
* \param callNode The node for which you are generating a heleper call
130+
* \param deps The pre register dependency conditions that will be filled by this function to attach within ICF
131+
* \param returnReg TR::Register* allocated by consumer of this API to hold the result of the helper call,
132+
* If passed, this function uses it to store return value from helper instead of allocating new register
133+
* \param forceFastPath A flag to indicate that the given TR_RuntimeHelper should be built with fast path. Fast path
134+
* helpers have no internal control flow.
135+
* \return TR::Register *helperReturnResult, gets the return value of helper function and return to the evaluator.
136+
*/
137+
TR::Register *buildDirectDispatch(TR::Node *callNode,
138+
TR::RegisterDependencyConditions** deps,
139+
TR::Register *returnReg=NULL,
140+
bool forceFastPath = false);
126141
};
127142
}

0 commit comments

Comments
 (0)