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

Use standardized branch range queries on Power #4959

Merged
merged 1 commit into from
Mar 6, 2019
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
46 changes: 21 additions & 25 deletions runtime/compiler/p/codegen/CallSnippet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,7 @@ uint8_t *TR::PPCCallSnippet::emitSnippetBody()
TR::SymbolReference *methodSymRef = (_realMethodSymbolReference)?_realMethodSymbolReference:callNode->getSymbolReference();
TR::MethodSymbol *methodSymbol = methodSymRef->getSymbol()->castToMethodSymbol();
TR::SymbolReference *glueRef;
intptrj_t distance;
bool isNativeStatic = false;
void *trmpln=NULL;
TR::Compilation *comp = cg()->comp();
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());

Expand All @@ -356,17 +354,18 @@ uint8_t *TR::PPCCallSnippet::emitSnippetBody()
methodSymbol->isSynchronised(), isNativeStatic, cg());
glueRef = cg()->symRefTab()->findOrCreateRuntimeHelper(runtimeHelper, false, false, false);

distance = (intptrj_t)glueRef->getMethodAddress() - (intptrj_t)cursor;
if (!(distance<=BRANCH_FORWARD_LIMIT && distance>=BRANCH_BACKWARD_LIMIT))
intptrj_t helperAddress = (intptrj_t)glueRef->getMethodAddress();
if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)cursor))
{
distance = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor) - (intptrj_t)cursor;
TR_ASSERT(distance<=BRANCH_FORWARD_LIMIT && distance>=BRANCH_BACKWARD_LIMIT,
"CodeCache is more than 32MB.\n");
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor);
TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)cursor),
"Helper address is out of range");
}

// 'b glueRef' for jitInduceOSRAtCurrentPC, 'bl glueRef' otherwise
// we use "b" for induceOSR because we want the helper to think that it's been called from the mainline code and not from the snippet.
int32_t branchInstruction = (glueRef->isOSRInductionHelper()) ? 0x48000000 : 0x48000001;
*(int32_t *)cursor = branchInstruction | (distance & 0x03fffffc);
*(int32_t *)cursor = branchInstruction | ((helperAddress - (intptrj_t)cursor) & 0x03fffffc);
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor,(uint8_t *)glueRef,TR_HelperAddress, cg()),
__FILE__, __LINE__, callNode);

Expand Down Expand Up @@ -542,7 +541,6 @@ uint8_t *TR::PPCVirtualUnresolvedSnippet::emitSnippetBody()
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());
TR::Node *callNode = getNode();
TR::SymbolReference *glueRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_PPCvirtualUnresolvedHelper, false, false, false);
intptrj_t distance;
void *thunk = fej9->getJ2IThunk(callNode->getSymbolReference()->getSymbol()->castToMethodSymbol()->getMethod(), comp);
uint8_t *j2iThunkRelocationPoint;

Expand All @@ -553,18 +551,18 @@ uint8_t *TR::PPCVirtualUnresolvedSnippet::emitSnippetBody()
cursor += 4;
}

distance = (intptrj_t)glueRef->getMethodAddress() - (intptrj_t)cursor;
getSnippetLabel()->setCodeLocation(cursor);

if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT))
intptrj_t helperAddress = (intptrj_t)glueRef->getMethodAddress();
if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)cursor))
{
distance = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor) - (intptrj_t)cursor;
TR_ASSERT(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT,
"CodeCache is more than 32MB.\n");
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor);
TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)cursor),
"Helper address is out of range");
}

// bl glueRef
*(int32_t *)cursor = 0x48000001 | (distance & 0x03fffffc);
*(int32_t *)cursor = 0x48000001 | ((helperAddress - (intptrj_t)cursor) & 0x03fffffc);
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor,(uint8_t *)glueRef,TR_HelperAddress, cg()),
__FILE__, __LINE__, callNode);
cursor += 4;
Expand All @@ -574,7 +572,7 @@ uint8_t *TR::PPCVirtualUnresolvedSnippet::emitSnippetBody()
* This is used to have 'blr's return to their corresponding 'bl's when handling private nestmate calls.
* Ideally, 'blr's return to their corresponding 'bl's in other cases as well but currently that does not happen.
*/
distance = (intptrj_t)getReturnLabel()->getCodeLocation() - (intptrj_t)cursor;
intptrj_t distance = (intptrj_t)getReturnLabel()->getCodeLocation() - (intptrj_t)cursor;
*(int32_t *)cursor = 0x48000000 | (distance & 0x03fffffc);

TR_ASSERT(gcMap().isGCSafePoint() && gcMap().getStackMap(), "Virtual call snippets must have GC maps when preserving the link stack");
Expand Down Expand Up @@ -662,7 +660,6 @@ uint8_t *TR::PPCInterfaceCallSnippet::emitSnippetBody()
TR::Compilation *comp = cg()->comp();
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());
TR::SymbolReference *glueRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_PPCinterfaceCallHelper, false, false, false);
intptrj_t distance;
void *thunk = fej9->getJ2IThunk(callNode->getSymbolReference()->getSymbol()->castToMethodSymbol()->getMethod(), comp);
uint8_t *j2iThunkRelocationPoint;

Expand All @@ -676,27 +673,26 @@ uint8_t *TR::PPCInterfaceCallSnippet::emitSnippetBody()
cursor += 4;
}

distance = (intptrj_t)glueRef->getMethodAddress() - (intptrj_t)cursor;

getSnippetLabel()->setCodeLocation(cursor);

if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT))
intptrj_t helperAddress = (intptrj_t)glueRef->getMethodAddress();
if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)cursor))
{
distance = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor) - (intptrj_t)cursor;
TR_ASSERT(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT,
"CodeCache is more than 32MB.\n");
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor);
TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)cursor),
"Helper address is out of range");
}

// bl glueRef
*(int32_t *)cursor = 0x48000001 | (distance & 0x03fffffc);
*(int32_t *)cursor = 0x48000001 | ((helperAddress - (intptrj_t)cursor) & 0x03fffffc);
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, (uint8_t *)glueRef, TR_HelperAddress, cg()),
__FILE__, __LINE__, callNode);
blAddress = cursor;
cursor += PPC_INSTRUCTION_LENGTH;

// Rather than placing the return address as data after the 'bl', place a 'b' back to main line code
// This insures that all 'blr's return to their corresponding 'bl's
distance = (intptrj_t)getReturnLabel()->getCodeLocation() - (intptrj_t)cursor;
intptrj_t distance = (intptrj_t)getReturnLabel()->getCodeLocation() - (intptrj_t)cursor;
*(int32_t *)cursor = 0x48000000 | (distance & 0x03fffffc);

TR_ASSERT(gcMap().isGCSafePoint() && gcMap().getStackMap(), "Interface call snippets must have GC maps when preserving the link stack");
Expand Down
13 changes: 6 additions & 7 deletions runtime/compiler/p/codegen/ForceRecompilationSnippet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@

uint8_t *TR::PPCForceRecompilationSnippet::emitSnippetBody()
{
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg()->fe());
uint8_t *buffer = cg()->getBinaryBufferCursor();
TR::SymbolReference *induceRecompilationSymRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_PPCinduceRecompilation, false, false, false);
intptrj_t startPC = (intptrj_t)((uint8_t*)cg()->getCodeStart());
Expand Down Expand Up @@ -119,16 +118,16 @@ uint8_t *TR::PPCForceRecompilationSnippet::emitSnippetBody()
buffer += PPC_INSTRUCTION_LENGTH;
}

intptrj_t distance = (intptrj_t)induceRecompilationSymRef->getMethodAddress() - (intptrj_t)buffer;
if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT))
intptrj_t helperAddress = (intptrj_t)induceRecompilationSymRef->getMethodAddress();
if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)buffer))
{
distance = TR::CodeCacheManager::instance()->findHelperTrampoline(induceRecompilationSymRef->getReferenceNumber(), (void *)buffer) - (intptrj_t)buffer;
TR_ASSERT(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT,
"CodeCache is more than 32MB.\n");
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(induceRecompilationSymRef->getReferenceNumber(), (void *)buffer);
TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)buffer),
"Helper address is out of range");
}

// b distance
*(int32_t *)buffer = 0x48000000 | (distance & 0x03ffffff);
*(int32_t *)buffer = 0x48000000 | ((helperAddress - (intptrj_t)buffer) & 0x03ffffff);

cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer,(uint8_t *)induceRecompilationSymRef,TR_HelperAddress, cg()),
__FILE__,
Expand Down
38 changes: 25 additions & 13 deletions runtime/compiler/p/codegen/InterfaceCastSnippet.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corp. and others
* Copyright (c) 2000, 2019 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 @@ -116,14 +116,16 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)getReStartLabel()->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)getReStartLabel()->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;

opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_doneLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_doneLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand All @@ -139,14 +141,16 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)getDoneLabel()->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)getDoneLabel()->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;

opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_callLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_callLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand Down Expand Up @@ -256,7 +260,8 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)getReStartLabel()->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)getReStartLabel()->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand All @@ -272,7 +277,8 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_callLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_callLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand Down Expand Up @@ -312,14 +318,16 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_trueLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_trueLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;

opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_falseLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_falseLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand All @@ -328,7 +336,8 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_doneLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_doneLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand Down Expand Up @@ -361,14 +370,16 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_trueLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_trueLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;

opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_falseLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_falseLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand All @@ -377,7 +388,8 @@ TR::PPCInterfaceCastSnippet::emitSnippetBody()
opcode.setOpCodeValue(TR::InstOpCode::b);
cursor = opcode.copyBinaryToBuffer(cursor);
branchDistance = (intptrj_t)_doneLabel->getCodeLocation() - (intptrj_t)cursor;
TR_ASSERT(branchDistance>=BRANCH_BACKWARD_LIMIT, "backward jump in Interface Cache is too long\n");
TR_ASSERT(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)_doneLabel->getCodeLocation(), (intptrj_t)cursor),
"backward jump in Interface Cache is too long\n");
*(int32_t *)cursor |= (branchDistance & 0x03fffffc);
cursor += PPC_INSTRUCTION_LENGTH;
}
Expand Down
Loading