Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/aarch64/codegen/J9InstructionDelegate.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2019, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at http://eclipse.org/legal/epl-2.0
7
* or the Apache License, Version 2.0 which accompanies this distribution
8
* and is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following Secondary
11
* Licenses when the conditions for such availability set forth in the
12
* Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
13
* version 2 with the GNU Classpath Exception [1] and GNU General Public
14
* License, version 2 with the OpenJDK Assembly Exception [2].
15
*
16
* [1] https://www.gnu.org/software/classpath/license.html
17
* [2] http://openjdk.java.net/legal/assembly-exception.html
18
*
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-exception
20
*******************************************************************************/
21
22
#include "codegen/ARM64Instruction.hpp"
23
#include "codegen/CallSnippet.hpp"
24
#include "codegen/CodeGenerator.hpp"
25
#include "codegen/InstructionDelegate.hpp"
26
#include "il/Node.hpp"
27
#include "il/Node_inlines.hpp"
28
29
void
30
J9::ARM64::InstructionDelegate::encodeBranchToLabel(TR::CodeGenerator *cg, TR::ARM64ImmSymInstruction *ins, uint8_t *cursor)
31
{
32
((TR::ARM64CallSnippet *)ins->getCallSnippet())->setCallRA(cursor + ARM64_INSTRUCTION_LENGTH);
33
}
34
35
static bool
36
isNPEThrowingInstruction(TR::InstOpCode::Mnemonic opCodeValue)
37
{
38
return (opCodeValue != TR::InstOpCode::addimmx) && (opCodeValue != TR::InstOpCode::addx)
39
&& (opCodeValue != TR::InstOpCode::prfm) && (opCodeValue != TR::InstOpCode::prfmimm) && (opCodeValue != TR::InstOpCode::prfmoff);
40
}
41
42
static void
43
setupImplicitNullPointerExceptionImpl(TR::CodeGenerator *cg, TR::Instruction *instr, TR::Node *node, TR::MemoryReference *mr)
44
{
45
TR::Compilation *comp = cg->comp();
46
if(cg->getHasResumableTrapHandler())
47
{
48
// If the treetop node is BNDCHK node combined with NULLCHK, the previous treetop node is NULLCHK.
49
auto treeTopNode = cg->getCurrentEvaluationTreeTop()->getNode();
50
if (treeTopNode->chkFoldedImplicitNULLCHK())
51
{
52
treeTopNode = cg->getCurrentEvaluationTreeTop()->getPrevTreeTop()->getNode();
53
}
54
// this instruction throws an implicit null check if:
55
// 1. The treetop node is a NULLCHK node
56
// 2. The memory reference of this instruction can cause a null pointer exception
57
// 3. The instruction throws NPE (prefetch or add does not throw it).
58
// 4. The null check reference node must be a child of this node
59
// 5. This memory reference uses the same register as the null check reference
60
// 6. This is the first instruction in the evaluation of this null check node to have met all the conditions
61
62
// Test conditions 1, 2, 3, and 6
63
if(node != NULL & mr != NULL &&
64
mr->getCausesImplicitNullPointerException() &&
65
treeTopNode->getOpCode().isNullCheck() &&
66
isNPEThrowingInstruction(instr->getOpCodeValue()) &&
67
cg->getImplicitExceptionPoint() == NULL)
68
{
69
// determine what the NULLcheck reference node is
70
TR::Node * nullCheckReference;
71
TR::Node * firstChild = treeTopNode->getFirstChild();
72
if (comp->useCompressedPointers() &&
73
firstChild->getOpCodeValue() == TR::l2a)
74
{
75
TR::ILOpCodes loadOp = comp->il.opCodeForIndirectLoad(TR::Int32);
76
TR::ILOpCodes rdbarOp = comp->il.opCodeForIndirectReadBarrier(TR::Int32);
77
while (firstChild->getOpCodeValue() != loadOp && firstChild->getOpCodeValue() != rdbarOp)
78
firstChild = firstChild->getFirstChild();
79
nullCheckReference = firstChild->getFirstChild();
80
}
81
else
82
nullCheckReference = treeTopNode->getNullCheckReference();
83
84
TR::Register *nullCheckReg = nullCheckReference->getRegister();
85
// Test conditions 3 and 4
86
if ((node->getOpCode().hasSymbolReference() &&
87
node->getSymbolReference() == comp->getSymRefTab()->findVftSymbolRef()) ||
88
(node->hasChild(nullCheckReference) && (nullCheckReg != NULL) && mr->refsRegister(nullCheckReg)))
89
{
90
if (comp->getOption(TR_TraceCG))
91
{
92
traceMsg(comp,"Instruction %p throws an implicit NPE, node: %p NPE node: %p\n", instr, node, nullCheckReference);
93
}
94
cg->setImplicitExceptionPoint(instr);
95
}
96
}
97
}
98
}
99
100
void
101
J9::ARM64::InstructionDelegate::setupImplicitNullPointerException(TR::CodeGenerator *cg, TR::ARM64Trg1MemInstruction *instr)
102
{
103
setupImplicitNullPointerExceptionImpl(cg, instr, instr->getNode(), instr->getMemoryReference());
104
}
105
106
void
107
J9::ARM64::InstructionDelegate::setupImplicitNullPointerException(TR::CodeGenerator *cg, TR::ARM64MemInstruction *instr)
108
{
109
setupImplicitNullPointerExceptionImpl(cg, instr, instr->getNode(), instr->getMemoryReference());
110
}
111
112