Path: blob/master/runtime/compiler/p/codegen/CallSnippet.hpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2019 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#ifndef PPCCALLSNIPPET_INCL23#define PPCCALLSNIPPET_INCL2425#include "codegen/Snippet.hpp"26#include "env/VMJ9.h"27#include "infra/Annotations.hpp"28#include "p/codegen/PPCInstruction.hpp"2930namespace TR { class CodeGenerator; }31class TR_J2IThunk;3233extern void ppcCodeSync(uint8_t *codePointer, uint32_t codeSize);3435namespace TR {3637class PPCCallSnippet : public TR::Snippet38{39uint8_t *callRA;40int32_t sizeOfArguments;4142bool needsGCMap(TR::CodeGenerator *cg, TR::SymbolReference *methodSymRef)43{44TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg->fe());45if (OMR_UNLIKELY(cg->comp()->compileRelocatableCode() && !cg->comp()->getOption(TR_UseSymbolValidationManager)))46return false;47TR::MethodSymbol *methodSymbol = methodSymRef->getSymbol()->castToMethodSymbol();48return !methodSymRef->isUnresolved() &&49(methodSymbol->isVMInternalNative() || methodSymbol->isJITInternalNative());50}5152protected:53TR_RuntimeHelper getInterpretedDispatchHelper(TR::SymbolReference *methodSymRef,54TR::DataType type, bool isSynchronized,55bool& isNativeStatic, TR::CodeGenerator* cg);56TR::SymbolReference * _realMethodSymbolReference;5758public:5960PPCCallSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s)61: TR::Snippet(cg, c, lab, needsGCMap(cg, c->getSymbolReference())), sizeOfArguments(s), callRA(0)62{63_realMethodSymbolReference = NULL;64}6566PPCCallSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, TR::SymbolReference *symRef, int32_t s)67: TR::Snippet(cg, c, lab, needsGCMap(cg, symRef ? symRef : c->getSymbolReference())), sizeOfArguments(s), callRA(0)68{69_realMethodSymbolReference = symRef;70}7172virtual Kind getKind() { return IsCall; }7374virtual uint8_t *emitSnippetBody();7576virtual uint32_t getLength(int32_t estimatedSnippetStart);7778int32_t getSizeOfArguments() {return sizeOfArguments;}79int32_t setSizeOfArguments(int32_t s) {return (sizeOfArguments = s);}8081uint8_t *getCallRA() {return callRA;}82uint8_t *setCallRA(uint8_t *ra) {return (callRA=ra);}8384TR::SymbolReference *getRealMethodSymbolReference() {return _realMethodSymbolReference;}85void setRealMethodSymbolReference(TR::SymbolReference *sf) {_realMethodSymbolReference = sf;}8687uint8_t *setUpArgumentsInRegister(uint8_t *buffer, TR::Node *callNode, int32_t argSize, TR::CodeGenerator *cg);8889static uint8_t *generateVIThunk(TR::Node *callNode, int32_t argSize, TR::CodeGenerator *cg);90static TR_J2IThunk *generateInvokeExactJ2IThunk(TR::Node *callNode, int32_t argSize, TR::CodeGenerator *cg, char *signature);91static int32_t instructionCountForArguments(TR::Node *callNode, TR::CodeGenerator *cg);92};9394class PPCUnresolvedCallSnippet : public TR::PPCCallSnippet95{9697public:9899PPCUnresolvedCallSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s)100: TR::PPCCallSnippet(cg, c, lab, s)101{102}103104virtual Kind getKind() { return IsUnresolvedCall; }105106virtual uint8_t *emitSnippetBody();107108virtual uint32_t getLength(int32_t estimatedSnippetStart);109};110111class PPCVirtualSnippet : public TR::Snippet112{113TR::LabelSymbol *returnLabel;114int32_t sizeOfArguments;115116public:117118PPCVirtualSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s, TR::LabelSymbol *retl, bool isGCSafePoint = false)119: TR::Snippet(cg, c, lab, isGCSafePoint), sizeOfArguments(s), returnLabel(retl) {}120121virtual Kind getKind() { return IsVirtual; }122123virtual uint8_t *emitSnippetBody();124125virtual uint32_t getLength(int32_t estimatedSnippetStart);126127int32_t getSizeOfArguments() {return sizeOfArguments;}128int32_t setSizeOfArguments(int32_t s) {return (sizeOfArguments = s);}129130TR::LabelSymbol *getReturnLabel() {return returnLabel;}131TR::LabelSymbol *setReturnLabel(TR::LabelSymbol *rl) {return (returnLabel=rl);}132};133134class PPCVirtualUnresolvedSnippet : public TR::PPCVirtualSnippet135{136uint8_t *thunkAddress;137public:138139PPCVirtualUnresolvedSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s, TR::LabelSymbol *retl)140: TR::PPCVirtualSnippet(cg, c, lab, s, retl, true), thunkAddress(NULL)141{142}143144PPCVirtualUnresolvedSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s, TR::LabelSymbol *retl, uint8_t *thunkPtr)145: TR::PPCVirtualSnippet(cg, c, lab, s, retl, true), thunkAddress(thunkPtr)146{147}148149virtual Kind getKind() { return IsVirtualUnresolved; }150151virtual uint8_t *emitSnippetBody();152153virtual uint32_t getLength(int32_t estimatedSnippetStart);154};155156class PPCInterfaceCallSnippet : public TR::PPCVirtualSnippet157{158TR::Instruction *_upperInstruction, *_lowerInstruction;159int32_t _tocOffset;160uint8_t *thunkAddress;161162public:163164PPCInterfaceCallSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s, TR::LabelSymbol *retl)165: TR::PPCVirtualSnippet(cg, c, lab, s, retl, true),166_upperInstruction(NULL), _lowerInstruction(NULL), _tocOffset(0), thunkAddress(NULL)167{168}169170PPCInterfaceCallSnippet(TR::CodeGenerator *cg, TR::Node *c, TR::LabelSymbol *lab, int32_t s, TR::LabelSymbol *retl, uint8_t *thunkPtr)171: TR::PPCVirtualSnippet(cg, c, lab, s, retl, true),172_upperInstruction(NULL), _lowerInstruction(NULL), _tocOffset(0), thunkAddress(thunkPtr)173{174}175176virtual Kind getKind() { return IsInterfaceCall; }177178TR::Instruction *getUpperInstruction() {return _upperInstruction;}179TR::Instruction *setUpperInstruction(TR::Instruction *pi)180{181return (_upperInstruction = pi);182}183184TR::Instruction *getLowerInstruction() {return _lowerInstruction;}185TR::Instruction *setLowerInstruction(TR::Instruction *pi)186{187return (_lowerInstruction = pi);188}189190int32_t getTOCOffset() {return _tocOffset;}191void setTOCOffset(int32_t v) {_tocOffset = v;}192193virtual uint8_t *emitSnippetBody();194195virtual uint32_t getLength(int32_t estimatedSnippetStart);196};197198}199200#endif201202203