diff --git a/runtime/compiler/p/codegen/CallSnippet.cpp b/runtime/compiler/p/codegen/CallSnippet.cpp index 03a76f33822..8708fa25d09 100644 --- a/runtime/compiler/p/codegen/CallSnippet.cpp +++ b/runtime/compiler/p/codegen/CallSnippet.cpp @@ -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()); @@ -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); @@ -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; @@ -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; @@ -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"); @@ -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; @@ -676,19 +673,18 @@ 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; @@ -696,7 +692,7 @@ uint8_t *TR::PPCInterfaceCallSnippet::emitSnippetBody() // 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"); diff --git a/runtime/compiler/p/codegen/ForceRecompilationSnippet.cpp b/runtime/compiler/p/codegen/ForceRecompilationSnippet.cpp index a1c8431c058..e1b7a9e9cbe 100644 --- a/runtime/compiler/p/codegen/ForceRecompilationSnippet.cpp +++ b/runtime/compiler/p/codegen/ForceRecompilationSnippet.cpp @@ -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()); @@ -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__, diff --git a/runtime/compiler/p/codegen/InterfaceCastSnippet.cpp b/runtime/compiler/p/codegen/InterfaceCastSnippet.cpp index 0387c1f5e5f..e9f4281eb21 100644 --- a/runtime/compiler/p/codegen/InterfaceCastSnippet.cpp +++ b/runtime/compiler/p/codegen/InterfaceCastSnippet.cpp @@ -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 @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/runtime/compiler/p/codegen/J9PPCInstruction.cpp b/runtime/compiler/p/codegen/J9PPCInstruction.cpp index dc706018fd9..0a2973e5b22 100644 --- a/runtime/compiler/p/codegen/J9PPCInstruction.cpp +++ b/runtime/compiler/p/codegen/J9PPCInstruction.cpp @@ -25,6 +25,7 @@ #include "codegen/CodeGenerator.hpp" #include "codegen/Relocation.hpp" #include "compile/ResolvedMethod.hpp" +#include "env/CompilerEnv.hpp" #include "env/jittypes.h" #include "env/VMJ9.h" #include "il/Node.hpp" @@ -41,7 +42,6 @@ uint8_t *TR::PPCDepImmSymInstruction::generateBinaryEncoding() uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = getOpCode().copyBinaryToBuffer(instructionStart); intptrj_t imm = getAddrImmediate(); - intptrj_t distance = imm - (intptrj_t)cursor; if (getOpCodeValue() == TR::InstOpCode::bl || getOpCodeValue() == TR::InstOpCode::b) { @@ -103,16 +103,16 @@ uint8_t *TR::PPCDepImmSymInstruction::generateBinaryEncoding() } else { - if (distance <= BRANCH_FORWARD_LIMIT && - distance >= BRANCH_BACKWARD_LIMIT) + if (TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(imm, (intptrj_t)cursor)) { - *(int32_t *)cursor |= distance & 0x03fffffc; + *(int32_t *)cursor |= (imm - (intptrj_t)cursor) & 0x03fffffc; } else { + intptrj_t targetAddress; if (refNum < TR_PPCnumRuntimeHelpers) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(refNum, (void *)cursor) - (intptrj_t)cursor; + targetAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(refNum, (void *)cursor); } else if (refNum >= cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol) && refNum <= cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::lastPerCodeCacheHelperSymbol)) @@ -120,20 +120,18 @@ uint8_t *TR::PPCDepImmSymInstruction::generateBinaryEncoding() TR_ASSERT(cg()->hasCodeCacheSwitched(), "Expecting per-codecache helper to be unreachable only when codecache was switched"); TR_CCPreLoadedCode helper = (TR_CCPreLoadedCode)(refNum - cg()->symRefTab()->getNonhelperIndex(TR::SymbolReferenceTable::firstPerCodeCacheHelperSymbol)); _addrImmediate = (uintptrj_t)fej9->getCCPreLoadedCodeAddress(cg()->getCodeCache(), helper, cg()); - distance = (intptrj_t)_addrImmediate - (intptrj_t)cursor; + targetAddress = (intptrj_t)_addrImmediate; } else { - void *trmpln = (void *)fej9->methodTrampolineLookup(comp, getSymbolReference(), (void *)cursor); - // Must use the trampoline as the target and not the label // - distance = (intptrj_t)trmpln - (intptrj_t)cursor; + targetAddress = (intptrj_t)fej9->methodTrampolineLookup(comp, getSymbolReference(), (void *)cursor); } - TR_ASSERT(distance <= BRANCH_FORWARD_LIMIT && distance >= BRANCH_BACKWARD_LIMIT, - "CodeCache is more than 32MB"); - *(int32_t *)cursor |= distance & 0x03fffffc; + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(targetAddress, (intptrj_t)cursor), + "Call target address is out of range"); + *(int32_t *)cursor |= (targetAddress - (intptrj_t)cursor) & 0x03fffffc; } } @@ -145,6 +143,7 @@ uint8_t *TR::PPCDepImmSymInstruction::generateBinaryEncoding() } else { + intptrj_t distance = imm - (intptrj_t)cursor; // Place holder only: non-TR::InstOpCode::b[l] usage of this instruction doesn't // exist at this moment. *(int32_t *)cursor |= distance & 0x03fffffc; diff --git a/runtime/compiler/p/codegen/J9PPCSnippet.cpp b/runtime/compiler/p/codegen/J9PPCSnippet.cpp index d2ddcc0ff6e..f0a7757ba1d 100644 --- a/runtime/compiler/p/codegen/J9PPCSnippet.cpp +++ b/runtime/compiler/p/codegen/J9PPCSnippet.cpp @@ -1534,13 +1534,11 @@ uint8_t *TR::PPCReadMonitorSnippet::emitSnippetBody() *(int32_t *)buffer |= (getRestartLabel()->getCodeLocation()-buffer) & 0x03FFFFFC; buffer += PPC_INSTRUCTION_LENGTH; - intptrj_t distance = (intptrj_t)getMonitorEnterHelper()->getSymbol()->castToMethodSymbol()->getMethodAddress() - (intptrj_t)buffer; - - if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT)) + intptrj_t helperAddress = (intptrj_t)getMonitorEnterHelper()->getSymbol()->castToMethodSymbol()->getMethodAddress(); + if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)buffer)) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(getMonitorEnterHelper()->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(getMonitorEnterHelper()->getReferenceNumber(), (void *)buffer); + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)buffer), "Helper address is out of range"); } opcode.setOpCodeValue(TR::InstOpCode::bl); @@ -1552,7 +1550,7 @@ uint8_t *TR::PPCReadMonitorSnippet::emitSnippetBody() __FILE__, __LINE__, getNode()); } - *(int32_t *)buffer |= distance & 0x03FFFFFC; + *(int32_t *)buffer |= (helperAddress - (intptrj_t)buffer) & 0x03FFFFFC; buffer += PPC_INSTRUCTION_LENGTH; gcMap().registerStackMap(buffer, cg()); @@ -1709,17 +1707,17 @@ uint8_t *TR::PPCHeapAllocSnippet::emitSnippetBody() *(int32_t *)buffer |= getNode()->getSecondChild()->getInt(); buffer += PPC_INSTRUCTION_LENGTH; } - TR::Compilation *comp = cg()->comp(); - intptrj_t distance = (intptrj_t)getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress() - (intptrj_t)buffer; - if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT)) + + intptrj_t helperAddress = (intptrj_t)getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress(); + if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)buffer)) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(getDestination()->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(getDestination()->getReferenceNumber(), (void *)buffer); + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)buffer), "Helper address is out of range"); } opcode.setOpCodeValue(TR::InstOpCode::bl); buffer = opcode.copyBinaryToBuffer(buffer); - *(int32_t *)buffer |= distance & 0x03FFFFFC; + *(int32_t *)buffer |= (helperAddress - (intptrj_t)buffer) & 0x03FFFFFC; if (cg()->comp()->compileRelocatableCode()) { cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer, (uint8_t*) getDestination(), TR_HelperAddress, cg()), diff --git a/runtime/compiler/p/codegen/J9UnresolvedDataSnippet.cpp b/runtime/compiler/p/codegen/J9UnresolvedDataSnippet.cpp index 4ea563eb23e..0bfcff4e18e 100644 --- a/runtime/compiler/p/codegen/J9UnresolvedDataSnippet.cpp +++ b/runtime/compiler/p/codegen/J9UnresolvedDataSnippet.cpp @@ -123,17 +123,15 @@ uint8_t *J9::Power::UnresolvedDataSnippet::emitSnippetBody() getSnippetLabel()->setCodeLocation(cursor); - intptrj_t 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"); } - // bl distance - *(int32_t *)cursor = 0x48000001 | (distance & 0x03fffffc); + *(int32_t *)cursor = 0x48000001 | ((helperAddress - (intptrj_t)cursor) & 0x03fffffc); cg()->addProjectSpecializedRelocation(cursor,(uint8_t *)glueRef, NULL, TR_HelperAddress, __FILE__, __LINE__, @@ -247,9 +245,10 @@ uint8_t *J9::Power::UnresolvedDataSnippet::emitSnippetBody() cursor += 4; *(int32_t *)cursor = 0xdeadbeef; // Pached with lis via runtime code cursor += 4; - intptrj_t ra_distance = ((intptrj_t)getAddressOfDataReference()+4) - (intptrj_t)cursor; - TR_ASSERT(ra_distance<=BRANCH_FORWARD_LIMIT && ra_distance>=BRANCH_BACKWARD_LIMIT, "Return address is more than 32MB.\n"); - *(int32_t *)cursor = 0x48000000 | (ra_distance & 0x03fffffc); + intptrj_t targetAddress = (intptrj_t)getAddressOfDataReference()+4; + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(targetAddress, (intptrj_t)cursor), + "Return address is out of range"); + *(int32_t *)cursor = 0x48000000 | ((targetAddress - (intptrj_t)cursor) & 0x03fffffc); return cursor+4; } diff --git a/runtime/compiler/p/codegen/PPCRecompilationSnippet.cpp b/runtime/compiler/p/codegen/PPCRecompilationSnippet.cpp index aff5bd5b3bb..43dbb426f98 100644 --- a/runtime/compiler/p/codegen/PPCRecompilationSnippet.cpp +++ b/runtime/compiler/p/codegen/PPCRecompilationSnippet.cpp @@ -46,22 +46,20 @@ uint8_t *TR::PPCRecompilationSnippet::emitSnippetBody() { uint8_t *buffer = cg()->getBinaryBufferCursor(); TR::Compilation *comp = cg()->comp(); - TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe()); TR::SymbolReference *countingRecompMethodSymRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_PPCcountingRecompileMethod, false, false, false); bool longPrologue = (getBranchToSnippet()->getBinaryLength() > 4); getSnippetLabel()->setCodeLocation(buffer); - intptrj_t distance = (intptrj_t)countingRecompMethodSymRef->getMethodAddress() - (intptrj_t)buffer; - if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT)) + intptrj_t helperAddress = (intptrj_t)countingRecompMethodSymRef->getMethodAddress(); + if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)buffer)) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(countingRecompMethodSymRef->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(countingRecompMethodSymRef->getReferenceNumber(), (void *)buffer); + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)buffer), "Helper address is out of range"); } // bl distance - *(int32_t *)buffer = 0x48000001 | (distance & 0x03ffffff); + *(int32_t *)buffer = 0x48000001 | ((helperAddress - (intptrj_t)buffer) & 0x03ffffff); cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer,(uint8_t *)countingRecompMethodSymRef,TR_HelperAddress, cg()), __FILE__, __LINE__, diff --git a/runtime/compiler/p/codegen/StackCheckFailureSnippet.cpp b/runtime/compiler/p/codegen/StackCheckFailureSnippet.cpp index df86d8dbd98..ac689c29d35 100644 --- a/runtime/compiler/p/codegen/StackCheckFailureSnippet.cpp +++ b/runtime/compiler/p/codegen/StackCheckFailureSnippet.cpp @@ -69,7 +69,6 @@ uint8_t *loadArgumentItem(TR::InstOpCode::Mnemonic op, uint8_t *buffer, TR::Real uint8_t *TR::PPCStackCheckFailureSnippet::emitSnippetBody() { TR::Compilation * comp = cg()->comp(); - TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe()); TR::ResolvedMethodSymbol *bodySymbol=comp->getJittedMethodSymbol(); TR::Machine *machine = cg()->machine(); TR::SymbolReference *sofRef = comp->getSymRefTab()->findOrCreateStackOverflowSymbolRef(comp->getJittedMethodSymbol()); @@ -160,16 +159,15 @@ uint8_t *TR::PPCStackCheckFailureSnippet::emitSnippetBody() buffer += 4; } - intptrj_t distance = (intptrj_t)sof->getMethodAddress() - (intptrj_t)buffer; - if (!(distance>=BRANCH_BACKWARD_LIMIT && distance<=BRANCH_FORWARD_LIMIT)) + intptrj_t helperAddress = (intptrj_t)sof->getMethodAddress(); + if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)buffer)) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(sofRef->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(sofRef->getReferenceNumber(), (void *)buffer); + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)buffer), "Helper address is out of range"); } // bl distance - *(int32_t *)buffer = 0x48000001 | (distance & 0x03ffffff); + *(int32_t *)buffer = 0x48000001 | ((helperAddress - (intptrj_t)buffer) & 0x03ffffff); cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer, (uint8_t *)sofRef, TR_HelperAddress, cg()), diff --git a/runtime/compiler/p/runtime/PPCRelocationTarget.cpp b/runtime/compiler/p/runtime/PPCRelocationTarget.cpp index 087f027fe4b..22e4e616591 100644 --- a/runtime/compiler/p/runtime/PPCRelocationTarget.cpp +++ b/runtime/compiler/p/runtime/PPCRelocationTarget.cpp @@ -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 @@ -322,7 +322,9 @@ TR_PPC32RelocationTarget::isOrderedPairRelocation(TR_RelocationRecord *reloRecor bool TR_PPCRelocationTarget::useTrampoline(uint8_t * helperAddress, uint8_t *baseLocation) { - return !(((IDATA)(helperAddress - baseLocation) <=BRANCH_FORWARD_LIMIT) && ((IDATA)(helperAddress - baseLocation) >=BRANCH_BACKWARD_LIMIT)); + return + !TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)helperAddress, (intptrj_t)baseLocation) || + TR::Options::getCmdLineOptions()->getOption(TR_StressTrampolines); } uint8_t * diff --git a/runtime/compiler/p/runtime/Recomp.cpp b/runtime/compiler/p/runtime/Recomp.cpp index adb31f42269..10babf46277 100644 --- a/runtime/compiler/p/runtime/Recomp.cpp +++ b/runtime/compiler/p/runtime/Recomp.cpp @@ -130,7 +130,6 @@ void J9::Recompilation::methodHasBeenRecompiled(void *oldStartPC, void *newStart TR_LinkageInfo *linkageInfo = TR_LinkageInfo::get(oldStartPC); int32_t bytesToSaveAtStart = 0; int32_t *patchAddr, newInstr; - intptrj_t distance; if (linkageInfo->isCountingMethodBody()) { @@ -139,15 +138,16 @@ void J9::Recompilation::methodHasBeenRecompiled(void *oldStartPC, void *newStart // which expects the new startPC. patchAddr = (int32_t *)((uint8_t *)oldStartPC + getJitEntryOffset(linkageInfo) + OFFSET_COUNTING_BRANCH_FROM_JITENTRY - 4); - distance = (uint8_t *)runtimeHelperValue(TR_PPCcountingPatchCallSite) - (uint8_t *)patchAddr; - if (!(distance<=BRANCH_FORWARD_LIMIT && distance>=BRANCH_BACKWARD_LIMIT)) + intptrj_t helperAddress = (intptrj_t)runtimeHelperValue(TR_PPCcountingPatchCallSite); + if (!TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)patchAddr) || + TR::Options::getCmdLineOptions()->getOption(TR_StressTrampolines)) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(TR_PPCcountingPatchCallSite, (void *)patchAddr) - (intptrj_t)patchAddr; - TR_ASSERT(distance<=BRANCH_FORWARD_LIMIT && distance>=BRANCH_BACKWARD_LIMIT, - "CodeCache is more than 32MB.\n"); + helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(TR_PPCcountingPatchCallSite, (void *)patchAddr); + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)patchAddr), + "Helper address is out of range"); } - newInstr = 0x48000001 | (distance & 0x03FFFFFC); + newInstr = 0x48000001 | ((helperAddress - (intptrj_t)patchAddr) & 0x03FFFFFC); *patchAddr = newInstr; ppcCodeSync((uint8_t *)patchAddr, 4); bytesToSaveAtStart = getJitEntryOffset(linkageInfo) + OFFSET_COUNTING_BRANCH_FROM_JITENTRY; @@ -157,15 +157,16 @@ void J9::Recompilation::methodHasBeenRecompiled(void *oldStartPC, void *newStart // Turn the call to samplingMethodRecompile into a call to samplingPatchCallSite patchAddr = (int32_t *)((uint8_t *)oldStartPC + OFFSET_SAMPLING_BRANCH_FROM_STARTPC); - distance = (uint8_t *)runtimeHelperValue(TR_PPCsamplingPatchCallSite) - (uint8_t *)patchAddr; - if (!(distance<=BRANCH_FORWARD_LIMIT && distance>=BRANCH_BACKWARD_LIMIT)) + intptrj_t helperAddress = (intptrj_t)runtimeHelperValue(TR_PPCsamplingPatchCallSite); + if (!TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)patchAddr) || + TR::Options::getCmdLineOptions()->getOption(TR_StressTrampolines)) { - distance = TR::CodeCacheManager::instance()->findHelperTrampoline(TR_PPCsamplingPatchCallSite, (void *)patchAddr) - (intptrj_t)patchAddr; - TR_ASSERT(distance<=BRANCH_FORWARD_LIMIT && distance>=BRANCH_BACKWARD_LIMIT, - "CodeCache is more than 32MB.\n"); + helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(TR_PPCsamplingPatchCallSite, (void *)patchAddr); + TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)patchAddr), + "Helper address is out of range"); } - newInstr = 0x48000001 | (distance & 0x03FFFFFC); + newInstr = 0x48000001 | ((helperAddress - (intptrj_t)patchAddr) & 0x03FFFFFC); *patchAddr = newInstr; ppcCodeSync((uint8_t *)patchAddr, 4); @@ -181,7 +182,7 @@ void J9::Recompilation::methodHasBeenRecompiled(void *oldStartPC, void *newStart bool codeMemoryWasAlreadyReleased = linkageInfo->hasBeenRecompiled(); // HCR - can recompile the same body twice linkageInfo->setHasBeenRecompiled(); - // asheikh 2005-05-05: Code Cache Reclamation does not work on ppc + // Code Cache Reclamation does not work on ppc // without counting method bodies. _countingPatchCallSite still refers // to the methodInfo poitner in the snippet area. if (linkageInfo->isSamplingMethodBody() && !codeMemoryWasAlreadyReleased) diff --git a/runtime/compiler/runtime/Trampoline.cpp b/runtime/compiler/runtime/Trampoline.cpp index 5866fb33f2a..aaceae26e88 100644 --- a/runtime/compiler/runtime/Trampoline.cpp +++ b/runtime/compiler/runtime/Trampoline.cpp @@ -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 @@ -43,9 +43,6 @@ #define OFFSET_IPIC_TO_CALL 32 #endif -#define BRANCH_FORWARD_LIMIT (0x01fffffc) -#define BRANCH_BACKWARD_LIMIT ((int32_t)0xfe000000) - extern TR_Processor portLibCall_getProcessorType(); #ifdef TR_HOST_POWER @@ -323,7 +320,8 @@ bool ppcCodePatching(void *method, void *callSite, void *currentPC, void *curren distance = entryAddress - (uint8_t *)callSite; currentDistance = ((oldBits << 6) >> 6) & 0xfffffffc; oldBits &= 0xfc000003; - if (TR::Options::getCmdLineOptions()->getOption(TR_StressTrampolines) || distance>BRANCH_FORWARD_LIMIT || distancegetOption(TR_StressTrampolines) || + !TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptrj_t)entryAddress, (intptrj_t)callSite)) { if (currentPC == newPC) { @@ -495,8 +493,6 @@ void ppcCodeCacheParameters(int32_t *trampolineSize, void **callBacks, int32_t * } #undef TRAMPOLINE_SIZE -#undef BRANCH_FORWARD_LIMIT -#undef BRANCH_BACKWARD_LIMIT #endif /*(TR_TARGET_POWER)*/ @@ -933,7 +929,7 @@ void s390zOS64CreateHelperTrampoline(void *trampPtr, int32_t numHelpers) static bool enableIIHF = (feGetEnv("TR_IIHF") != NULL); - if (!enableIIHF) + if (!enableIIHF) { // Trampoline Code: // zOS Linkage rEP = r15. @@ -1111,7 +1107,7 @@ bool s390zOS64CodePatching(void *method, void *callSite, void *currentPC, void * s390zOS64CreateMethodTrampoline(newTramp, newPC, method); } else - { + { // Patch the existing trampoline. // Should not require Self-loops in patching since trampolines addresses // should be aligned by 8-bytes, and STG is atomic. @@ -1228,7 +1224,7 @@ void s390zLinux64CreateHelperTrampoline(void *trampPtr, int32_t numHelpers) if (enableIIHF) { - //Alternative Trampoline code + //Alternative Trampoline code // IIHF rEP addr // IILF rEP addr // BRC rEP @@ -1236,7 +1232,7 @@ void s390zLinux64CreateHelperTrampoline(void *trampPtr, int32_t numHelpers) uint32_t low = (uint32_t)helperAddr; uint32_t high = (uint32_t)(helperAddr >> 32); - // IIHF rEP, mAddr; + // IIHF rEP, mAddr; *(int16_t *)buffer = 0xC008 + (rEP << 4); buffer += sizeof(int16_t); *(int32_t *)buffer = 0x00000000 + high; @@ -1299,7 +1295,7 @@ void s390zLinux64CreateMethodTrampoline(void *trampPtr, void *startPC, void *met intptrj_t dispatcher = (intptrj_t)((uint8_t *) startPC + linkInfo->getReservedWord()); static bool enableIIHF = (feGetEnv("TR_IIHF") != NULL); - + if (enableIIHF) { //Alternative Trampoline code @@ -1355,7 +1351,7 @@ void s390zLinux64CreateMethodTrampoline(void *trampPtr, void *startPC, void *met // DC mAddr *(intptrj_t *)buffer = dispatcher; buffer += sizeof(intptrj_t); - } + } } // zLinux64 Code Patching.