Path: blob/master/runtime/compiler/z/codegen/ForceRecompilationSnippet.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "z/codegen/ForceRecompilationSnippet.hpp"2324#include "codegen/CodeGenerator.hpp"25#include "codegen/Relocation.hpp"26#include "env/IO.hpp"27#include "env/jittypes.h"28#include "env/VMJ9.h"29#include "il/LabelSymbol.hpp"30#include "il/Node.hpp"31#include "il/Node_inlines.hpp"32#include "runtime/CodeCacheManager.hpp"3334uint8_t *35TR::S390ForceRecompilationSnippet::emitSnippetBody()36{37uint8_t * cursor = cg()->getBinaryBufferCursor();38getSnippetLabel()->setCodeLocation(cursor);39TR::Compilation *comp = cg()->comp();40TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());4142uint32_t rEP = (uint32_t) cg()->getEntryPointRegister() - 1;43TR::SymbolReference * glueRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_S390induceRecompilation);4445// Set up the start of data constants and jump to helper.46// We generate:47// LARL r14, <Start of DC>48// BRCL <Helper Addr>4950// LARL - Add Relocation the data constants to this LARL.51cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative32BitRelocation(cursor, getDataConstantSnippet()->getSnippetLabel()));5253*(int16_t *) cursor = 0xC0E0;54cursor += sizeof(int16_t);5556// Place holder. Proper offset will be calculated by relocation.57*(int32_t *) cursor = 0xDEADBEEF;58cursor += sizeof(int32_t);5960// Generate RIOFF if RI is supported.61cursor = generateRuntimeInstrumentationOnOffInstruction(cg(), cursor, TR::InstOpCode::RIOFF);6263// BRCL64*(int16_t *) cursor = 0xC0F4;65cursor += sizeof(int16_t);6667// Calculate the relative offset to get to helper method.68// If MCC is not supported, everything should be reachable.69// If MCC is supported, we will look up the appropriate trampoline, if70// necessary.71intptr_t destAddr = (intptr_t)(glueRef->getMethodAddress());7273#if defined(TR_TARGET_64BIT)74#if defined(J9ZOS390)75if (comp->getOption(TR_EnableRMODE64))76#endif77{78if (NEEDS_TRAMPOLINE(destAddr, cursor, cg()))79{80// Destination is beyond our reachable jump distance, we'll find the trampoline.81destAddr = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor);82this->setUsedTrampoline(true);83}84}85#endif8687TR_ASSERT(CHECK_32BIT_TRAMPOLINE_RANGE(destAddr, cursor), "Helper Call is not reachable.");88this->setSnippetDestAddr(destAddr);8990*(int32_t *) cursor = (int32_t)((destAddr - (intptr_t)(cursor - 2)) / 2);9192AOTcgDiag1(comp, "add TR_HelperAddress cursor=%x\n", cursor);93cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, (uint8_t*) glueRef, TR_HelperAddress, cg()),94__FILE__, __LINE__, getNode());9596cursor += sizeof(int32_t);9798return cursor;99100}101102103uint32_t104TR::S390ForceRecompilationSnippet::getLength(int32_t estimatedSnippetStart)105{106uint32_t length = 12; // LARL + BRCL107length += getRuntimeInstrumentationOnOffInstructionLength(cg());108return length;109}110111112void113TR_Debug::print(TR::FILE *pOutFile, TR::S390ForceRecompilationSnippet * snippet)114{115uint8_t * bufferPos = snippet->getSnippetLabel()->getCodeLocation();116117printSnippetLabel(pOutFile, snippet->getSnippetLabel(), bufferPos, "Force Recompilation Call Snippet");118119printPrefix(pOutFile, NULL, bufferPos, 6);120trfprintf(pOutFile, "LARL \tGPR14, <%p>\t# Addr of DataConst",121(intptr_t) snippet->getDataConstantSnippet()->getSnippetLabel()->getCodeLocation());122bufferPos += 6;123124bufferPos = printRuntimeInstrumentationOnOffInstruction(pOutFile, bufferPos, false); // RIOFF125126printPrefix(pOutFile, NULL, bufferPos, 6);127trfprintf(pOutFile, "BRCL \t<%p>\t\t# Branch to %s %s",128snippet->getSnippetDestAddr(),129getName(_cg->getSymRef(TR_S390induceRecompilation)),130snippet->usedTrampoline()?"- Trampoline Used.":"");131bufferPos += 6;132}133134TR::S390ForceRecompilationDataSnippet::S390ForceRecompilationDataSnippet(TR::CodeGenerator *cg,135TR::Node *node,136TR::LabelSymbol *restartLabel):137TR::S390ConstantDataSnippet(cg,node,generateLabelSymbol(cg),0),138_restartLabel(restartLabel)139{140}141142uint8_t *143TR::S390ForceRecompilationDataSnippet::emitSnippetBody()144{145TR::Compilation *comp = cg()->comp();146uint8_t * cursor = cg()->getBinaryBufferCursor();147AOTcgDiag1(comp, "TR::S390ForceRecompilationDataSnippet::emitSnippetBody cursor=%x\n", cursor);148getSnippetLabel()->setCodeLocation(cursor);149150/** IMPORTANT **/151// If the fields in this snippet are modified, the respective changes must be reflected152// in jitrt.dev/s390/Recompilation.m4153// RetAddrInForceRecompSnippet and StartPCInForceRecompSnippet vars.154155// Return Address156*(intptr_t *) cursor = (intptr_t)getRestartLabel()->getCodeLocation();157AOTcgDiag1(comp, "add TR_AbsoluteMethodAddress cursor=%x\n", cursor);158cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, NULL, TR_AbsoluteMethodAddress, cg()),159__FILE__, __LINE__, getNode());160cursor += sizeof(intptr_t);161162// Start PC163*(intptr_t *) cursor = (intptr_t)cg()->getCodeStart();164AOTcgDiag1(comp, "add TR_AbsoluteMethodAddress cursor=%x\n", cursor);165cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, NULL, TR_AbsoluteMethodAddress, cg()),166__FILE__, __LINE__, getNode());167cursor += sizeof(intptr_t);168169return cursor;170}171172uint32_t173TR::S390ForceRecompilationDataSnippet::getLength(int32_t estimatedSnippetStart)174{175// Data Snippet is only 2 pointers:176// Return Address177// StartPC178return 2 * sizeof(intptr_t);179}180181void182TR_Debug::print(TR::FILE *pOutFile, TR::S390ForceRecompilationDataSnippet * snippet)183{184uint8_t * bufferPos = snippet->getSnippetLabel()->getCodeLocation();185186printSnippetLabel(pOutFile, snippet->getSnippetLabel(), bufferPos, "Force Recompilation Data Snippet");187printPrefix(pOutFile, NULL, bufferPos, sizeof(intptr_t));188trfprintf(pOutFile, "DC \t%p \t\t# Main Code Return Address", *((intptr_t*)bufferPos));189bufferPos += sizeof(intptr_t);190191printPrefix(pOutFile, NULL, bufferPos, sizeof(intptr_t));192trfprintf(pOutFile, "DC \t%p \t\t# Method Start PC (to patch)", *((intptr_t*)bufferPos));193bufferPos += sizeof(intptr_t);194}195196197198