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

Build JNI IFA switching helpers as C calls #2044

Merged
merged 1 commit into from
Aug 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 \
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we'll need to modify the CMake builds as well.

Copy link
Contributor Author

@NigelYiboYu NigelYiboYu Jun 4, 2018

Choose a reason for hiding this comment

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

I don't see CMake lists contain these cpp file names. It seems to operate on directories for z codegen.

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;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we leave this TODO around? This is definitely something we still want to do once we refactor the runtime helpers into a sane table with properties.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO is added back

// 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)
Copy link
Contributor

Choose a reason for hiding this comment

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

@NigelYiboYu I think my previous comment was for this section. For now we need this part for calling out helpers written in C that means we need to load environment for instanceOf as well. Is that covered? Looking through your other changes.
I am going through your changes now.

Copy link
Contributor

@r30shah r30shah Jul 31, 2018

Choose a reason for hiding this comment

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

@fjeremic I am thinking of moving some of the context switching code from helper Glue code to in body and see the effect. I expect a small effect on the method footprint. If the effect is not much then we can move this inlined. I believe x86 already do this. We can make our helper linkage more generic this way.
Though it is something we can do later, should not affect this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

@r30shah let's give it a try and see if it has any negative effects on performance.

Copy link
Contributor Author

@NigelYiboYu NigelYiboYu Aug 1, 2018

Choose a reason for hiding this comment

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

InstanceOf is not covered in this PR. This whole pull request is for JNI and IFA switching. We can come back and change instanceOf helper to load environment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually good point @r30shah. Thinking about this again we have duplicate information here. The helper index is already stored in callNode->getSymbolReference()->getReferenceNumber() so we shouldn't need to pass it as an argument to the CHelper linkage buildDirectDispatch.

This information is already available through the callNode. @NigelYiboYu are we able to get rid of this extra parameter? Once this is done we can remove the below check for if (helperIndex != TR_S390numRuntimeHelpers) since a helper index must always be available. This will fix the instanceOf helper as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The extra helper index is removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Update:

Environment pointer is now only loaded if the C helper is fast-path. Non-fastPath helpers jump to glue code, which does its own environment handling.

// 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