Path: blob/master/runtime/compiler/aarch64/codegen/J9InstructionDelegate.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2019, 2021 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 http://eclipse.org/legal/epl-2.06* or the Apache License, Version 2.0 which accompanies this distribution7* and is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following Secondary10* Licenses when the conditions for such availability set forth in the11* Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,12* version 2 with the GNU Classpath Exception [1] and GNU General Public13* License, version 2 with the OpenJDK Assembly Exception [2].14*15* [1] https://www.gnu.org/software/classpath/license.html16* [2] http://openjdk.java.net/legal/assembly-exception.html17*18* 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-exception19*******************************************************************************/2021#include "codegen/ARM64Instruction.hpp"22#include "codegen/CallSnippet.hpp"23#include "codegen/CodeGenerator.hpp"24#include "codegen/InstructionDelegate.hpp"25#include "il/Node.hpp"26#include "il/Node_inlines.hpp"2728void29J9::ARM64::InstructionDelegate::encodeBranchToLabel(TR::CodeGenerator *cg, TR::ARM64ImmSymInstruction *ins, uint8_t *cursor)30{31((TR::ARM64CallSnippet *)ins->getCallSnippet())->setCallRA(cursor + ARM64_INSTRUCTION_LENGTH);32}3334static bool35isNPEThrowingInstruction(TR::InstOpCode::Mnemonic opCodeValue)36{37return (opCodeValue != TR::InstOpCode::addimmx) && (opCodeValue != TR::InstOpCode::addx)38&& (opCodeValue != TR::InstOpCode::prfm) && (opCodeValue != TR::InstOpCode::prfmimm) && (opCodeValue != TR::InstOpCode::prfmoff);39}4041static void42setupImplicitNullPointerExceptionImpl(TR::CodeGenerator *cg, TR::Instruction *instr, TR::Node *node, TR::MemoryReference *mr)43{44TR::Compilation *comp = cg->comp();45if(cg->getHasResumableTrapHandler())46{47// If the treetop node is BNDCHK node combined with NULLCHK, the previous treetop node is NULLCHK.48auto treeTopNode = cg->getCurrentEvaluationTreeTop()->getNode();49if (treeTopNode->chkFoldedImplicitNULLCHK())50{51treeTopNode = cg->getCurrentEvaluationTreeTop()->getPrevTreeTop()->getNode();52}53// this instruction throws an implicit null check if:54// 1. The treetop node is a NULLCHK node55// 2. The memory reference of this instruction can cause a null pointer exception56// 3. The instruction throws NPE (prefetch or add does not throw it).57// 4. The null check reference node must be a child of this node58// 5. This memory reference uses the same register as the null check reference59// 6. This is the first instruction in the evaluation of this null check node to have met all the conditions6061// Test conditions 1, 2, 3, and 662if(node != NULL & mr != NULL &&63mr->getCausesImplicitNullPointerException() &&64treeTopNode->getOpCode().isNullCheck() &&65isNPEThrowingInstruction(instr->getOpCodeValue()) &&66cg->getImplicitExceptionPoint() == NULL)67{68// determine what the NULLcheck reference node is69TR::Node * nullCheckReference;70TR::Node * firstChild = treeTopNode->getFirstChild();71if (comp->useCompressedPointers() &&72firstChild->getOpCodeValue() == TR::l2a)73{74TR::ILOpCodes loadOp = comp->il.opCodeForIndirectLoad(TR::Int32);75TR::ILOpCodes rdbarOp = comp->il.opCodeForIndirectReadBarrier(TR::Int32);76while (firstChild->getOpCodeValue() != loadOp && firstChild->getOpCodeValue() != rdbarOp)77firstChild = firstChild->getFirstChild();78nullCheckReference = firstChild->getFirstChild();79}80else81nullCheckReference = treeTopNode->getNullCheckReference();8283TR::Register *nullCheckReg = nullCheckReference->getRegister();84// Test conditions 3 and 485if ((node->getOpCode().hasSymbolReference() &&86node->getSymbolReference() == comp->getSymRefTab()->findVftSymbolRef()) ||87(node->hasChild(nullCheckReference) && (nullCheckReg != NULL) && mr->refsRegister(nullCheckReg)))88{89if (comp->getOption(TR_TraceCG))90{91traceMsg(comp,"Instruction %p throws an implicit NPE, node: %p NPE node: %p\n", instr, node, nullCheckReference);92}93cg->setImplicitExceptionPoint(instr);94}95}96}97}9899void100J9::ARM64::InstructionDelegate::setupImplicitNullPointerException(TR::CodeGenerator *cg, TR::ARM64Trg1MemInstruction *instr)101{102setupImplicitNullPointerExceptionImpl(cg, instr, instr->getNode(), instr->getMemoryReference());103}104105void106J9::ARM64::InstructionDelegate::setupImplicitNullPointerException(TR::CodeGenerator *cg, TR::ARM64MemInstruction *instr)107{108setupImplicitNullPointerExceptionImpl(cg, instr, instr->getNode(), instr->getMemoryReference());109}110111112