Path: blob/master/runtime/compiler/x/amd64/codegen/AMD64GuardedDevirtualSnippet.cpp
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#include "x/amd64/codegen/AMD64GuardedDevirtualSnippet.hpp"2324#include <stddef.h>25#include "codegen/GuardedDevirtualSnippet.hpp"26#include "codegen/CodeGenerator.hpp"27#include "codegen/Linkage.hpp"28#include "codegen/Linkage_inlines.hpp"29#include "il/LabelSymbol.hpp"30#include "il/MethodSymbol.hpp"31#include "il/Symbol.hpp"3233uint8_t *TR::AMD64GuardedDevirtualSnippet::loadArgumentsIfNecessary(TR::Node *callNode, uint8_t *cursor, bool calculateSizeOnly, int32_t *sizeOfFlushArea)34{35if (!_realMethodSymbolReference)36return cursor;3738TR::MethodSymbol *methodSymbol = _realMethodSymbolReference->getSymbol()->castToMethodSymbol();39if (isLoadArgumentsNecessary(methodSymbol))40{41// Devirtualized VMInternalNatives have their args evaluated to the42// stack, so we must load them into regs before the vft dispatch43TR::Linkage *linkage = cg()->getLinkage(methodSymbol->getLinkageConvention());44cursor = linkage->loadArguments(callNode, cursor, calculateSizeOnly, sizeOfFlushArea, false);45}46return cursor;47}4849uint8_t *TR::AMD64GuardedDevirtualSnippet::emitSnippetBody()50{51uint8_t *buffer = cg()->getBinaryBufferCursor();52uint8_t *cursor = loadArgumentsIfNecessary(getNode(), buffer, false, NULL);53cg()->setBinaryBufferCursor(cursor);54cursor = TR::X86GuardedDevirtualSnippet::emitSnippetBody();55getSnippetLabel()->setCodeLocation(buffer);56cg()->setBinaryBufferCursor(buffer);57return cursor;58}5960uint32_t TR::AMD64GuardedDevirtualSnippet::getLength(int32_t estimatedSnippetStart)61{62int32_t sizeOfFlushArea = 0;63loadArgumentsIfNecessary(getNode(), (uint8_t*)0 + estimatedSnippetStart, true, &sizeOfFlushArea);64return sizeOfFlushArea + TR::X86GuardedDevirtualSnippet::getLength(estimatedSnippetStart + sizeOfFlushArea);65}6667bool TR::AMD64GuardedDevirtualSnippet::isLoadArgumentsNecessary(TR::MethodSymbol *methodSymbol)68{69return (methodSymbol && methodSymbol->isVMInternalNative());70}717273