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

Change Class.isAssignableFrom to use CHelper instead of JNI call on Z #20590

Merged

Conversation

matthewhall2
Copy link
Contributor

@matthewhall2 matthewhall2 commented Nov 13, 2024

Calls to Class.isAssignableFrom will now use CHelper instead of a JNI call.

note: as discussed (@r30shah ), this change is not enabled yet on Z. It will be enabled when the inlined tests are added to checkAssignabeEvaluator.
vmfarm sanity check for this branch

The following tests were run on a branch with the change enabled:
vmfarm
personal s390x
personal s390x (unstable re-run)

@matthewhall2 matthewhall2 force-pushed the assignableFrom_useCHelper branch 2 times, most recently from 4c9f74e to 87ce953 Compare November 13, 2024 18:30
@matthewhall2
Copy link
Contributor Author

extended.openjdk failure looks like its #12807

bool J9::Z::CodeGenerator::supportsInliningOfIsAssignableFrom()
{
return false; // will be taken out once new inlined tests are added
static const bool disableInliningOfIsAssignableFrom = feGetEnv("TR_DisableInliningOfIsAssignableFrom") != NULL;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you need this ? Parent Codegenerator class implementation will return false. As you are not yet enabling this, We should take this override out of this PR.

@@ -11627,6 +11626,60 @@ static bool inlineIsAssignableFrom(TR::Node *node, TR::CodeGenerator *cg)
return true;
}

static TR::Register* checkAssignableEvaluator(TR::Node *node, TR::CodeGenerator *cg)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would rename this to inlineCheckAssignableFromEvaluator.

return resultReg;
}

TR::Register *J9::Z::TreeEvaluator::directCallEvaluator(TR::Node *node, TR::CodeGenerator *cg)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you need this ? directCallEvaluator will call the code-generator's inline direct call function which is where you should check and call checkAssignableFromEvaluator.

[1]. https://github.com/eclipse-omr/omr/blob/3da49aa3aaed9217fb02d5ab3d069aa7142f89ba/compiler/z/codegen/OMRTreeEvaluator.cpp#L11171

static bool getIsFastPathOnly(TR::Node * callNode, TR::CodeGenerator * cg) {
auto opCode = callNode->getOpCodeValue();

if (opCode == 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.

Please match the braces with rest of the code style

@matthewhall2 matthewhall2 force-pushed the assignableFrom_useCHelper branch 9 times, most recently from edd3d3e to 2742494 Compare November 13, 2024 21:43
return true;
}

TR::MethodSymbol * methodSymbol = callNode->getSymbol()->getMethodSymbol();
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the use if methodSymbol?

@@ -250,6 +250,19 @@ class RealRegisterManager
TR::CodeGenerator* _cg;
};

static bool getIsFastPathOnly(TR::Node * callNode, TR::CodeGenerator * cg)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consumer of this function should be the S390CHelperLinkage only. Can you make this member and private?

@@ -11479,13 +11479,12 @@ J9::Z::TreeEvaluator::VMarrayCheckEvaluator(TR::Node *node, TR::CodeGenerator *c
/////////////////////////////////////////////////////////////////////////////////
static bool inlineIsAssignableFrom(TR::Node *node, TR::CodeGenerator *cg)
{
static char *disable = feGetEnv("TR_disableInlineIsAssignableFrom");
static char *disable = feGetEnv("TR_DisableInliningOfIsAssignableFrom");
Copy link
Contributor

Choose a reason for hiding this comment

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

This change is not relevant unless you are using TR_DisableInliningOfIsAssignableFrom somehow.
Can you remove it ?

TR::LabelSymbol *helperCallLabel = generateLabelSymbol(cg);
TR::LabelSymbol *doneLabel = generateLabelSymbol(cg);

int8_t numOfPostDepConditions = (thisClassReg == checkClassReg)? 2 : 3;
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you encounter case where thisClassReg and checkClassReg are same ? I would prefer to call addPostConditionIfNotAlreadyInserted in that case.

I would like to move your comment from closer to OOL call to here as a TODO highlighting that there are incremental changes coming in to add more inlined tests. Or comment on why you chose to make call in the Out of line.

Copy link
Contributor

Choose a reason for hiding this comment

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

You haven't addressed the first part of the comment. Please respond or fix this.

}
deps->addPostCondition(resultReg, TR::RealRegister::AssignAny);

generateRIInstruction(cg, TR::InstOpCode::LHI, node, resultReg, 1); // load initial value for result
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to load initial value in resultReg ? You need to only allocate it and pass it to dispatch call.

Copy link
Contributor Author

@matthewhall2 matthewhall2 Nov 21, 2024

Choose a reason for hiding this comment

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

that's for the inlined tests being added later. Those tests won't set the value, but jump to the "done" section on true (or fallthrough to the next test on fail). It's not the only way to do it (I could load 1 in the done/pass section), but it's what checkCast does so I went with that

Copy link
Contributor

Choose a reason for hiding this comment

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

I would like this changes to be as performant as possible and we do not need this setting of result value - in this code.

If you take a look at other evaluators, we do have tendency to write long evaluators which I think we should avoid and break them into a smaller functions which are easy to maintain. For this PR, I think it is OK, but as we start adding incremental changes to improve this, keep this in mind - InstanceOf and CheckCast evaluators does call out separate functions to generate specific tests.

generateS390LabelInstruction(cg, TR::InstOpCode::label, node, helperCallLabel);
resultReg = TR::TreeEvaluator::performCall(node, false, cg);

generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, doneLabel); // skip over fail label
Copy link
Contributor

Choose a reason for hiding this comment

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

What is failLabel?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

similar to above, when inlining is doable and the inlined tests fail, we want to set the value in resultReg to 0 under a failLabel. I'll take it out for now but it will be added back for the inlined tests

@matthewhall2 matthewhall2 force-pushed the assignableFrom_useCHelper branch 6 times, most recently from 7127cc4 to 91ec6f6 Compare November 21, 2024 18:08
Copy link
Contributor

@r30shah r30shah left a comment

Choose a reason for hiding this comment

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

One nitpick - Overall this incremental changes looks good to me.

TR::LabelSymbol *helperCallLabel = generateLabelSymbol(cg);
TR::LabelSymbol *doneLabel = generateLabelSymbol(cg);

int8_t numOfPostDepConditions = (thisClassReg == checkClassReg)? 2 : 3;
Copy link
Contributor

Choose a reason for hiding this comment

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

You haven't addressed the first part of the comment. Please respond or fix this.

@r30shah
Copy link
Contributor

r30shah commented Nov 22, 2024

@matthewhall2 Please squash the commits to single, I do not think it logically makes sense to separate into two commits here.

Copy link
Contributor

@r30shah r30shah left a comment

Choose a reason for hiding this comment

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

Last nitpick, LGTM

@@ -4326,6 +4326,7 @@ genInstanceOfOrCheckCastNullTest(TR::Node* node, TR::CodeGenerator* cg, TR::Regi
}
}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove extra new line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

- took out inlined tests
- call CHelper in OOL code section
- note: while only  calling the CHelper does improve perfance over
  inlined + JNI call,  more inlined tests will added in a later PR to
further improve performance

Signed-off-by: Matthew Hall <[email protected]>

- enables transformation of call to Class.isAssignableFrom to

Signed-off-by: Matthew Hall <[email protected]>
@r30shah
Copy link
Contributor

r30shah commented Nov 25, 2024

Jenkins test sanity zlinux jdk21

@r30shah
Copy link
Contributor

r30shah commented Nov 25, 2024

Merging this one as test has passed.

@r30shah r30shah merged commit fc778d6 into eclipse-openj9:master Nov 25, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants