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

Provide a consistent interface for asking if trampolines are required #3479

Merged
merged 4 commits into from
Jan 31, 2019

Conversation

0xdaryl
Copy link
Contributor

@0xdaryl 0xdaryl commented Jan 20, 2019

  • Add CPU-specific tests for relative branch reachability
  • Remove unused AlwaysUseTrampoline CodeGenerator option
  • Add directCallRequiresTrampoline CodeGenerator query
  • Use directCallRequiresTrampoline CodeGenerator query

@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 20, 2019

This is a WIP while further testing completes.

In the meantime, I'd appreciate a review from @fjeremic @ymanton @0dvictor @knn-k for the platform-specific changes please.

@0xdaryl 0xdaryl force-pushed the cpubranchdisp branch 2 times, most recently from bd6ec27 to 49e13ad Compare January 20, 2019 01:42
@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 20, 2019

@genie-omr build all

@0xdaryl 0xdaryl force-pushed the cpubranchdisp branch 2 times, most recently from 84ce1bd to 168b3a5 Compare January 20, 2019 04:16
@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 20, 2019

@genie-omr build aarch64

@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 20, 2019

@genie-omr build all

{
intptrj_t range = targetAddress - sourceAddress;
return (range <= self()->maxUnconditionalBranchImmediateForwardOffset() &&
range >= self()->maxUnconditionalBranchImmediateBackwardOffset()) ? true : false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need the ternary operator here? Omitting ? true : false accomplishes the exact same thing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly elsewhere in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed it is not necessary. I'll fix up everywhere.

*/
bool directCallRequiresTrampoline(intptrj_t targetAddress, intptrj_t sourceAddress)
{
TR_ASSERT(0, "An architecture specialization of this function must be provided.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds like a fatal assert. Can we make it as such?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'm ok with that suggestion. However, the idea behind returning true was that it should force the user of this API to do the right thing because the target is not apparently reachable (i.e., its a fail safe). A fatal assert, however, would make it more clear to an implementation that it should be overriding this function.

@@ -149,7 +149,8 @@ OMR::Z::Snippet::generatePICBinary(TR::CodeGenerator * cg, uint8_t * cursor, TR:
}
#endif

TR_ASSERT(CHECK_32BIT_TRAMPOLINE_RANGE(destAddr, cursor), "Helper Call is not reachable.");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinBranchRelativeRILRange(destAddr, (intptrj_t)cursor),
"Helper Call is not reachable.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make this a fatal assert. I'd rather have a compile time assert failure than unpredictable runtime crash.

Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly elsewhere in Z codegen where asserts were touched.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed.

*
* @return : true if a trampoline is required; false otherwise.
*/
bool directCallRequiresTrampoline(intptrj_t targetAddress, intptrj_t sourceAddress);
Copy link
Contributor

Choose a reason for hiding this comment

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

How do you feel about making the sourceAddress parameter not be ISA-specific? Rather than having the caller be responsible for knowing what the relative base is and having +4s in some places and not in others might we be better off just passing the call address and target address and letting either the code generator or OMRCPU figure it out? The only down side I can think of is that if the base depends on the type of instruction being used we'd have to also pass that in, but I can't imagine any ISA doing that sort of thing. The upside is that it's just plain easier to understand and use and consistent across code generators.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does make sense to have a parameter with a clearly defined definition. The CodeGenerator implementation on each platform should be able to determine what adjustments are needed. In theory, all platforms except x86 should be passing in the instruction address already based on my understanding of how the displacements are calculated for their respective branch instructions. X86 will be require a bit of rework that may reach into downstream projects. I'll look into this deeper and report back.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've made changes to the PR where the sourceAddress of the directCallRequiresTrampoline is the address of the call instruction. For the most part, no changes were required except on x86, and even in that case the changes were minimal. I'll push those changes shortly.

@fjeremic : in the process of doing this I discovered a couple of places in the Z codegen where I believe the wrong source address is being used already to calculate whether a trampoline is needed. Here are the two places that I found in the current code base:

https://github.com/eclipse/omr/blob/7a0ff628cb5c514ebaa88c1bb3d884fd8b4ca6fb/compiler/z/codegen/OMRSnippet.cpp#L142

https://github.com/eclipse/omr/blob/7a0ff628cb5c514ebaa88c1bb3d884fd8b4ca6fb/compiler/z/codegen/S390HelperCallSnippet.cpp#L113

In both cases, I believe cursor is two bytes off because it has already been advanced once the instruction opcode was written. If you confirm this is an issue then I'll fix up as part of this work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should point out that in both of the Z cases above the cursor was correctly adjusted during the actual encoding of the instruction (it was just the trampoline test where it is different).

"CodeCache is more than 32MB.\n");

TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinBranchImmediateRange(target, (intptrj_t)cursor),
"Target address is out of range. CodeCache is more than 32MB.");
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems the asserting condition does not have any indication that CodeCache must not be more than 32MB. It may be more clear removing "CodeCache is more than 32MB."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@knn-k
Copy link
Contributor

knn-k commented Jan 24, 2019

For AArch64, TR::ARM64ImmSymInstruction::generateBinaryEncoding() and TR::ARM64LabelInstruction::generateBinaryEncoding() in ARM64BinaryEncoding.cpp can be rewritten using directCallRequiresTrampoline().

@0xdaryl 0xdaryl force-pushed the cpubranchdisp branch 3 times, most recently from 3546280 to ebf40ba Compare January 24, 2019 15:07
0xdaryl added a commit to 0xdaryl/omr that referenced this pull request Jan 24, 2019
To prevent downstream project breakages, introduce empty extensions
to the CPU hierarchy for ARM and AArch64.  Once merged, downstream
projects can make changes to their build systems to accommodate the new
files before new CPU functionality is added in eclipse-omr#3479.

Signed-off-by: Daryl Maier <maier@ca.ibm.com>
@0xdaryl 0xdaryl force-pushed the cpubranchdisp branch 2 times, most recently from e19e295 to 30e44d7 Compare January 29, 2019 00:09
Add tests to each CPU class to answer whether the distance between
a source address and a target address falls within the range of
a relative, immediate branch instruction on the given CPU type.

This is useful, for example, to determine whether a trampoline is
required to reach a target method address or helper function
directly.

These functions deprecate the platform-specific macros and functions
currently in use.  They will be cleaned up once downstream projects
have been modified.

Signed-off-by: Daryl Maier <maier@ca.ibm.com>
The option has the same functionality as the StressTrampolines option.

Signed-off-by: Daryl Maier <maier@ca.ibm.com>
Add a CodeGenerator query to answer whether a trampoline is required
to branch from some source address to a target address.  Each platform
provides its own specialized implementation of this function.

Signed-off-by: Daryl Maier <maier@ca.ibm.com>
* Use the standard query on each platform to determine the need for trampolines
for direct calls and helpers.

* Use platform-specific CPU queries to test call or branch instrution ranges.
Existing macros will be left in place until downstream projects are converted
to use the CPU queries.

Signed-off-by: Daryl Maier <maier@ca.ibm.com>
@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 30, 2019

@genie-omr build all

@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 30, 2019

I'm running some final, private stress tests now. All look good so far. I'll un-WIP this when they're done so hopefully this can be merged then (merge conflicts are killing me!)

@fjeremic fjeremic self-assigned this Jan 30, 2019
@0xdaryl 0xdaryl changed the title WIP: Provide a consistent interface for asking if trampolines are required Provide a consistent interface for asking if trampolines are required Jan 30, 2019
@0xdaryl
Copy link
Contributor Author

0xdaryl commented Jan 30, 2019

Un-WIPing as my internal stress testing is clean. I believe I've addressed all the comments.

@fjeremic fjeremic merged commit de6dd94 into eclipse-omr:master Jan 31, 2019
knn-k added a commit to knn-k/omr that referenced this pull request Feb 20, 2019
…ange

This is a follow-up of eclipse-omr#3479 for aarch64.
Two functions in ARM64BinaryEncoding.cpp to use
cg->directCallRequiresTrampoline() for checking the range of branch
instructions.

Signed-off-by: knn-k <konno@jp.ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants