Skip to content

Commit

Permalink
Build JNI IFA switching helpers as C calls
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
NigelYiboYu committed Aug 1, 2018
1 parent 2008d20 commit 27118b0
Show file tree
Hide file tree
Showing 20 changed files with 1,304 additions and 795 deletions.
2 changes: 0 additions & 2 deletions runtime/codert_vm/armnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,6 @@ UNUSED(jitNewPackedArray)
UNUSED(jitResolvePackedArrayFieldLength)
UNUSED(jitResolveIsPackedFieldNested)
UNUSED(jitNewObjectNoTenantInit)
UNUSED(jitPostJNICallOffloadCheck)
UNUSED(jitPreJNICallOffloadCheck)
UNUSED(jitFindFieldSignatureClass)
UNUSED(icallVMprJavaSendInvokeWithArgumentsHelperL)
UNUSED(j2iInvokeWithArguments)
Expand Down
8 changes: 4 additions & 4 deletions runtime/codert_vm/cnathelp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2177,7 +2177,7 @@ old_slow_jitCallCFunction(J9VMThread *currentThread)
}

void
fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread)
fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread, J9Method *method)
{
#if defined(J9VM_OPT_JAVA_OFFLOAD_SUPPORT)
OLD_JIT_HELPER_PROLOGUE(0);
Expand All @@ -2189,12 +2189,12 @@ fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread)
els->calloutVMState = setVMState(currentThread, J9VMSTATE_JNI_FROM_JIT);
}
#endif /* J9VM_PORT_ZOS_CEEHDLRSUPPORT */
VM_VMHelpers::beforeJNICall(currentThread);
VM_VMHelpers::beforeJNICall(currentThread, method);
#endif /* J9VM_OPT_JAVA_OFFLOAD_SUPPORT */
}

void
fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread)
fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread, J9Method* method)
{
#if defined(J9VM_OPT_JAVA_OFFLOAD_SUPPORT)
OLD_JIT_HELPER_PROLOGUE(0);
Expand All @@ -2209,7 +2209,7 @@ fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread)
}
}
#endif /* J9VM_PORT_ZOS_CEEHDLRSUPPORT */
VM_VMHelpers::afterJNICall(currentThread);
VM_VMHelpers::afterJNICall(currentThread, method);
#endif /* J9VM_OPT_JAVA_OFFLOAD_SUPPORT */
}

Expand Down
2 changes: 0 additions & 2 deletions runtime/codert_vm/pnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,6 @@ UNUSED(jitNewPackedArray)
UNUSED(jitResolvePackedArrayFieldLength)
UNUSED(jitResolveIsPackedFieldNested)
UNUSED(jitNewObjectNoTenantInit)
UNUSED(jitPostJNICallOffloadCheck)
UNUSED(jitPreJNICallOffloadCheck)
UNUSED(jitFindFieldSignatureClass)
UNUSED(icallVMprJavaSendInvokeWithArgumentsHelperL)
UNUSED(j2iInvokeWithArguments)
Expand Down
2 changes: 0 additions & 2 deletions runtime/codert_vm/xnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,6 @@ UNUSED(jitNewPackedArray)
UNUSED(jitResolvePackedArrayFieldLength)
UNUSED(jitResolveIsPackedFieldNested)
UNUSED(jitNewObjectNoTenantInit)
UNUSED(jitPostJNICallOffloadCheck)
UNUSED(jitPreJNICallOffloadCheck)
UNUSED(jitFindFieldSignatureClass)
UNUSED(icallVMprJavaSendInvokeWithArgumentsHelperL)
UNUSED(j2iInvokeWithArguments)
Expand Down
32 changes: 0 additions & 32 deletions runtime/codert_vm/znathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -422,38 +422,6 @@ BEGIN_FUNC(jitRunOnJavaStack)
BRANCH_VIA_VMTHREAD(J9TR_VMThread_tempSlot)
END_CURRENT

dnl When the offload helpers are called,
dnl the java SP is already stored in the J9VMThread.

BEGIN_HELPER(jitPreJNICallOffloadCheck)
ifdef({ASM_J9VM_PORT_ZOS_CEEHDLRSUPPORT},{
std fpr8,JIT_FPR_SAVE_OFFSET(8)(CSP)
std fpr9,JIT_FPR_SAVE_OFFSET(9)(CSP)
std fpr10,JIT_FPR_SAVE_OFFSET(10)(CSP)
std fpr11,JIT_FPR_SAVE_OFFSET(11)(CSP)
std fpr12,JIT_FPR_SAVE_OFFSET(12)(CSP)
std fpr13,JIT_FPR_SAVE_OFFSET(13)(CSP)
std fpr14,JIT_FPR_SAVE_OFFSET(14)(CSP)
std fpr15,JIT_FPR_SAVE_OFFSET(15)(CSP)
stfpc CEEHDLR_FPC_SAVE_OFFSET(CSP)
})
SAVE_ALL_REGS(jitPreJNICallOffloadCheck)
LR_GPR CARG1,J9VMTHREAD
LOAD_LABEL_CONSTANT($1, fast_jitPreJNICallOffloadCheck, CARG2)
CALL_INDIRECT(CARG2)
RESTORE_ALL_REGS_AND_SWITCH_TO_JAVA_STACK(jitPreJNICallOffloadCheck)
br r14
END_CURRENT

BEGIN_HELPER(jitPostJNICallOffloadCheck)
SAVE_ALL_REGS(jitPostJNICallOffloadCheck)
LR_GPR CARG1,J9VMTHREAD
LOAD_LABEL_CONSTANT($1, fast_jitPostJNICallOffloadCheck, CARG2)
CALL_INDIRECT(CARG2)
RESTORE_ALL_REGS_AND_SWITCH_TO_JAVA_STACK(jitPostJNICallOffloadCheck)
br r14
END_CURRENT

dnl When the VM access helpers are called,
dnl the java SP is already stored in the J9VMThread.

Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/build/files/target/z.mk
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ JIT_PRODUCT_SOURCE_FILES+=\
compiler/z/codegen/J9MemoryReference.cpp \
compiler/z/codegen/J9S390CHelperLinkage.cpp \
compiler/z/codegen/J9S390PrivateLinkage.cpp \
compiler/z/codegen/J9S390JNILinkage.cpp \
compiler/z/codegen/J9S390Snippet.cpp \
compiler/z/codegen/J9S390SystemLinkage.cpp \
compiler/z/codegen/J9TreeEvaluator.cpp \
Expand Down
9 changes: 5 additions & 4 deletions runtime/compiler/runtime/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ extern "C" void mcc_reservationAdjustment_unwrapper(void **argsPtr, void **resPt
extern "C" void mcc_lookupHelperTrampoline_unwrapper(void **argsPtr, void **resPtr);
#endif

extern "C" void fast_jitPreJNICallOffloadCheck(J9VMThread *currentThread, J9Method *method);
extern "C" void fast_jitPostJNICallOffloadCheck(J9VMThread *currentThread, J9Method *method);

JIT_HELPER(icallVMprJavaSendNativeStatic);
JIT_HELPER(icallVMprJavaSendStatic0);
JIT_HELPER(icallVMprJavaSendStatic1);
Expand Down Expand Up @@ -623,8 +626,6 @@ JIT_HELPER(_nativeStaticHelper);
JIT_HELPER(jitLookupInterfaceMethod);
JIT_HELPER(jitMethodIsNative);
JIT_HELPER(jitMethodIsSync);
JIT_HELPER(jitPreJNICallOffloadCheck);
JIT_HELPER(jitPostJNICallOffloadCheck);
JIT_HELPER(jitResolveClass);
JIT_HELPER(jitResolveClassFromStaticField);
JIT_HELPER(jitResolveField);
Expand Down Expand Up @@ -1592,8 +1593,8 @@ void initializeCodeRuntimeHelperTable(J9JITConfig *jitConfig, char isSMP)
SET(TR_S390arrayORHelper, (void *) 0, TR_Helper);
SET(TR_S390arrayANDHelper, (void *) 0, TR_Helper);
SET(TR_S390collapseJNIReferenceFrame, (void *) jitCollapseJNIReferenceFrame, TR_Helper);
SET(TR_S390jitPreJNICallOffloadCheck, (void *) jitPreJNICallOffloadCheck, TR_Helper);
SET(TR_S390jitPostJNICallOffloadCheck, (void *) jitPostJNICallOffloadCheck, TR_Helper);
SET(TR_S390jitPreJNICallOffloadCheck, (void *) fast_jitPreJNICallOffloadCheck, TR_CHelper);
SET(TR_S390jitPostJNICallOffloadCheck, (void *) fast_jitPostJNICallOffloadCheck, TR_CHelper);
SET(TR_S390jitCallCFunction, (void *) jitCallCFunction, TR_Helper);
SET(TR_S390OutlinedNew, (void *) outlinedNewObject, TR_Helper);
SET(TR_S390OutlinedNewArray, (void *) outlinedNewArray, TR_Helper);
Expand Down
8 changes: 7 additions & 1 deletion runtime/compiler/runtime/Runtime.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -87,6 +87,12 @@ inline uint32_t getJitEntryOffset(TR_LinkageInfo *linkageInfo)
#define OFFSET_COUNTING_BRANCH_FROM_JITENTRY 36
#endif

#ifdef J9ZOS390
#define TRS390_TOC_UNWRAP_ENV(wrappedPointer) (((J9FunctionDescriptor_T *) (wrappedPointer))->ada)
#else
#define TRS390_TOC_UNWRAP_ENV(wrappedPointer) (void*)0xdeafbeef
#endif

/* Functions used by AOT runtime to fixup recompilation info for AOT */
#if defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || (defined(TR_HOST_ARM))
uint32_t *getLinkageInfo(void * startPC);
Expand Down
2 changes: 0 additions & 2 deletions runtime/compiler/runtime/asmprotos.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ JIT_HELPER(jitNewArray); // asm calling-convention helper
JIT_HELPER(jitNewInstanceImplAccessCheck); // asm calling-convention helper
JIT_HELPER(jitNewObject); // asm calling-convention helper
JIT_HELPER(jitObjectHashCode); // asm calling-convention helper
JIT_HELPER(jitPostJNICallOffloadCheck); // asm calling-convention helper
JIT_HELPER(jitPreJNICallOffloadCheck); // asm calling-convention helper
JIT_HELPER(jitReleaseVMAccess); // asm calling-convention helper
JIT_HELPER(jitReportMethodEnter); // asm calling-convention helper
JIT_HELPER(jitReportMethodExit); // asm calling-convention helper
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/z/codegen/J9CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
#include "env/jittypes.h"
#include "il/Node.hpp"
#include "il/Node_inlines.hpp"
#include "z/codegen/J9S390JNILinkage.hpp"
#include "z/codegen/J9S390PrivateLinkage.hpp"
#include "z/codegen/J9S390SystemLinkage.hpp"
#include "z/codegen/J9S390CHelperLinkage.hpp"
#include "z/codegen/S390GenerateInstructions.hpp"
#include "z/codegen/S390Recompilation.hpp"
#include "z/codegen/S390Register.hpp"
#include "z/codegen/J9S390PrivateLinkage.hpp"
#include "z/codegen/ReduceSynchronizedFieldLoad.hpp"

#define OPT_DETAILS "O^O CODE GENERATION: "
Expand Down
36 changes: 24 additions & 12 deletions runtime/compiler/z/codegen/J9S390CHelperLinkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,21 +259,17 @@ class RealRegisterManager
TR::CodeGenerator* _cg;
};

/** \brief Build a JIT helper call.
* \details
* It generates sequence that prepares parameters for the JIT helper function and generate a helper call.
* \param callNode The node for which you are generating a heleper call
* \param deps The pre register dependency conditions that will be filled by this function to attach within ICF
* \param returnReg TR::Register* allocated by consumer of this API to hold the result of the helper call,
* If passed, this function uses it to store return value from helper instead of allocating new register
* \return TR::Register *helperReturnResult, gets the return value of helper function and return to the evaluator.
*/
TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode, TR::RegisterDependencyConditions **deps, TR::Register *returnReg)
TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode,
TR::RegisterDependencyConditions **deps,
TR::Register *returnReg,
bool forceFastPath)
{
RealRegisterManager RealRegisters(cg());
bool isHelperCallWithinICF = deps != NULL;
// TODO: Currently only jitInstanceOf is fast path helper. Need to modify following condition if we add support for other fast path only helpers
bool isFastPathOnly = callNode->getOpCodeValue() == TR::instanceof;
// 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
// Having a fast path helper call also implies that there is no environment pointer setup in GPR5
bool isFastPathOnly = callNode->getOpCodeValue() == TR::instanceof || forceFastPath;

traceMsg(comp(),"%s: Internal Control Flow in OOL : %s\n",callNode->getOpCode().getName(),isHelperCallWithinICF ? "true" : "false" );
for (int i = TR::RealRegister::FirstGPR; i <= TR::RealRegister::LastHPR; i++)
{
Expand Down Expand Up @@ -344,6 +340,7 @@ TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode,
// Storing Java Stack Pointer
javaStackPointerRegister = cg()->getStackPointerRealRegister();
cursor = generateRXInstruction(cg(), TR::InstOpCode::getStoreOpCode(), callNode, javaStackPointerRegister, generateS390MemoryReference(vmThreadRegister, offsetJ9SP, cg()));

#if defined(J9ZOS390)
padding += 2;
// Loading DSAPointer Register
Expand All @@ -364,6 +361,21 @@ TR::Register * TR::S390CHelperLinkage::buildDirectDispatch(TR::Node * callNode,
}
TR::SymbolReference * callSymRef = callNode->getSymbolReference();
void * destAddr = callNode->getSymbolReference()->getSymbol()->castToMethodSymbol()->getMethodAddress();

#if defined(J9ZOS390)
// Fast path helper calls are real C function calls, whereas non-fast-path calls jump to picBuilder glue code
// glue code does its own environment handling and does not need a environment loading here.
if(isFastPathOnly)
{
TR_RuntimeHelper helperIndex = static_cast<TR_RuntimeHelper>(callNode->getSymbolReference()->getReferenceNumber());
TR_ASSERT_FATAL(helperIndex < TR_S390numRuntimeHelpers, "Invalid helper index in c helper node\n");

// XPLINK GPR5 is an environment register.
intptrj_t environment = reinterpret_cast<intptrj_t>(TOC_UNWRAP_ENV(runtimeHelpers.getFunctionPointer(helperIndex)));
genLoadAddressConstant(cg(), callNode, environment, javaStackPointerRegister);
}
#endif

cursor = new (cg()->trHeapMemory()) TR::S390RILInstruction(TR::InstOpCode::BRASL, callNode, regRA, destAddr, callSymRef, cg());
cursor->setDependencyConditions(preDeps);
if (isFastPathOnly)
Expand Down
19 changes: 17 additions & 2 deletions runtime/compiler/z/codegen/J9S390CHelperLinkage.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -122,6 +122,21 @@ class S390CHelperLinkage : public TR::Linkage
return buildDirectDispatch(callNode, NULL, returnReg);
}

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

0 comments on commit 27118b0

Please sign in to comment.