void TR::ExternalRelocation::apply(TR::CodeGenerator *codeGen) { TR::Compilation *comp = codeGen->comp(); AOTcgDiag1(comp, "TR::ExternalRelocation::apply updateLocation=" POINTER_PRINTF_FORMAT " \n", getUpdateLocation()); uint8_t * relocatableMethodCodeStart = (uint8_t *)comp->getRelocatableMethodCodeStart(); getRelocationRecord()->addRelocationEntry((uint32_t)(getUpdateLocation() - relocatableMethodCodeStart)); }
uint8_t * TR::S390HelperCallSnippet::emitSnippetBody() { uint8_t * cursor = cg()->getBinaryBufferCursor(); getSnippetLabel()->setCodeLocation(cursor); TR::Node * callNode = getNode(); TR::SymbolReference * helperSymRef = getHelperSymRef(); bool jitInduceOSR = helperSymRef == cg()->symRefTab()->element(TR_induceOSRAtCurrentPC); if (jitInduceOSR) { // Flush in-register arguments back to the stack for interpreter cursor = TR::S390CallSnippet::S390flushArgumentsToStack(cursor, callNode, getSizeOfArguments(), cg()); } uint32_t rEP = (uint32_t) cg()->getEntryPointRegister() - 1; //load vm thread into gpr13 cursor = generateLoadVMThreadInstruction(cg(), cursor); // Generate RIOFF if RI is supported. cursor = generateRuntimeInstrumentationOnOffInstruction(cg(), cursor, TR::InstOpCode::RIOFF); if ( // Methods that require alwaysExcept()) // R14 to point to snippet: { // For trace method entry/exit, we need to set up R14 to point to the // beginning of the data segment. We will use BRASL to automatically // set R14 correctly. // For methods that lead to exceptions, and never return to the // main code, we set up R14, so that if GC occurs, the stackwalker // will see R14 is pointing to this snippet, and pick up the correct // stack map. *(int16_t *) cursor = 0xC0E5; // BRASL R14, <Helper Addr> cursor += sizeof(int16_t); } else // Otherwise: { // We're not sure if the helper will return. So, we need to provide // the return addr of the main line code, so that when helper call // completes, it can jump back properly. // Load Return Address into R14. intptrj_t returnAddr = (intptrj_t)getReStartLabel()->getCodeLocation(); // LARL R14, <Return Addr> *(int16_t *) cursor = 0xC0E0; cursor += sizeof(int16_t); *(int32_t *) cursor = (int32_t)((returnAddr - (intptrj_t)(cursor - 2)) / 2); cursor += sizeof(int32_t); *(int16_t *) cursor = 0xC0F4; // BRCL <Helper Addr> cursor += sizeof(int16_t); } // Calculate the relative offset to get to helper method. // If MCC is not supported, everything should be reachable. // If MCC is supported, we will look up the appropriate trampoline, if // necessary. intptrj_t destAddr = (intptrj_t)(helperSymRef->getSymbol()->castToMethodSymbol()->getMethodAddress()); #if defined(TR_TARGET_64BIT) #if defined(J9ZOS390) if (cg()->comp()->getOption(TR_EnableRMODE64)) #endif { if (NEEDS_TRAMPOLINE(destAddr, cursor, cg())) { destAddr = cg()->fe()->indexedTrampolineLookup(helperSymRef->getReferenceNumber(), (void *)cursor); this->setUsedTrampoline(true); // We clobber rEP if we take a trampoline. Update our register map if necessary. if (gcMap().getStackMap() != NULL) { gcMap().getStackMap()->maskRegisters(~(0x1 << (rEP))); } } } #endif TR_ASSERT(CHECK_32BIT_TRAMPOLINE_RANGE(destAddr, cursor), "Helper Call is not reachable."); this->setSnippetDestAddr(destAddr); *(int32_t *) cursor = (int32_t)((destAddr - (intptrj_t)(cursor - 2)) / 2); AOTcgDiag1(cg()->comp(), "add TR_HelperAddress cursor=%x\n", cursor); cg()->addProjectSpecializedRelocation(cursor, (uint8_t*) helperSymRef, NULL, TR_HelperAddress, __FILE__, __LINE__, getNode()); cursor += sizeof(int32_t); gcMap().registerStackMap(cursor, cg()); return cursor; }
void TR::ExternalRelocation::addExternalRelocation(TR::CodeGenerator *codeGen) { TR::AheadOfTimeCompile::interceptAOTRelocation(this); TR::Compilation *comp = codeGen->comp(); AOTcgDiag0(comp, "TR::ExternalRelocation::addExternalRelocation\n"); TR_LinkHead<TR::IteratedExternalRelocation>& aot = codeGen->getAheadOfTimeCompile()->getAOTRelocationTargets(); uint32_t narrowSize = getNarrowSize(); uint32_t wideSize = getWideSize(); flags8_t modifier(collectModifier()); TR::IteratedExternalRelocation *r; AOTcgDiag1(comp, "target=" POINTER_PRINTF_FORMAT "\n", _targetAddress); if (_targetAddress2) AOTcgDiag1(comp, "target2=" POINTER_PRINTF_FORMAT "\n", _targetAddress2); for (r = aot.getFirst(); r != 0; r = r->getNext()) { if (r->getTargetAddress2()) AOTcgDiag6(comp, "r=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " target2=" POINTER_PRINTF_FORMAT ", kind=%x modifier=%x\n", r, r->full(), r->getTargetAddress(), r->getTargetAddress2(), r->getTargetKind(), r->getModifierValue()); else AOTcgDiag5(comp, "r=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", r, r->full(), r->getTargetAddress(), r->getTargetKind(), r->getModifierValue()); AOTcgDiag2(comp, "#sites=%x size=%x\n", r->getNumberOfRelocationSites(), r->getSizeOfRelocationData()); if (r->full() == false && r->getTargetAddress() == _targetAddress && r->getTargetAddress2() == _targetAddress2 && r->getTargetKind() == _kind && modifier.getValue() == r->getModifierValue()) { if (!r->needsWideOffsets()) { if (r->getSizeOfRelocationData() + narrowSize > MAX_SIZE_RELOCATION_DATA) { r->setFull(); continue; // look for one that's not full } } else { if (r->getSizeOfRelocationData() + wideSize > MAX_SIZE_RELOCATION_DATA) { r->setFull(); continue; // look for one that's not full } } r->setNumberOfRelocationSites(r->getNumberOfRelocationSites()+1); r->setSizeOfRelocationData(r->getSizeOfRelocationData() + (r->needsWideOffsets()?wideSize:narrowSize)); _relocationRecord = r; if (r->getTargetAddress2()) AOTcgDiag6(comp, "r=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " target2=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", r, r->full(), r->getTargetAddress(), r->getTargetAddress2(), r->getTargetKind(), r->getModifierValue()); else AOTcgDiag5(comp, "r=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", r, r->full(), r->getTargetAddress(), r->getTargetKind(), r->getModifierValue()); AOTcgDiag2(comp, "#sites=%x size=%x\n", r->getNumberOfRelocationSites(), r->getSizeOfRelocationData()); return; } } TR::IteratedExternalRelocation *temp = _targetAddress2 ? new (codeGen->trHeapMemory()) TR::IteratedExternalRelocation(_targetAddress, _targetAddress2, _kind, modifier, codeGen) : new (codeGen->trHeapMemory()) TR::IteratedExternalRelocation(_targetAddress, _kind, modifier, codeGen); aot.add(temp); if (_targetAddress2) AOTcgDiag6(comp, "temp=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " target2=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", temp, temp->full(), temp->getTargetAddress(), temp->getTargetAddress2(), temp->getTargetKind(), temp->getModifierValue()); else AOTcgDiag5(comp, "temp=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", temp, temp->full(), temp->getTargetAddress(), temp->getTargetKind(), temp->getModifierValue()); AOTcgDiag2(comp, "#sites=%x size=%x\n", temp->getNumberOfRelocationSites(), temp->getSizeOfRelocationData()); temp->setNumberOfRelocationSites(temp->getNumberOfRelocationSites()+1); temp->setSizeOfRelocationData(temp->getSizeOfRelocationData() + (temp->needsWideOffsets()?wideSize:narrowSize)); _relocationRecord = temp; if (_targetAddress2) AOTcgDiag6(comp, "temp=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " target2=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", temp, temp->full(), temp->getTargetAddress(), temp->getTargetAddress2(), temp->getTargetKind(), temp->getModifierValue()); else AOTcgDiag5(comp, "temp=" POINTER_PRINTF_FORMAT " full=%x target=" POINTER_PRINTF_FORMAT " kind=%x modifier=%x\n", temp, temp->full(), temp->getTargetAddress(), temp->getTargetKind(), temp->getModifierValue()); AOTcgDiag2(comp, "#sites=%x size=%x\n", temp->getNumberOfRelocationSites(), temp->getSizeOfRelocationData()); }