Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/p/codegen/PPCRecompilation.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2020 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 https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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
21
*******************************************************************************/
22
23
#include "p/codegen/PPCRecompilation.hpp"
24
25
#include "codegen/CodeGenerator.hpp"
26
#include "codegen/Machine.hpp"
27
#include "codegen/RealRegister.hpp"
28
#include "codegen/Register.hpp"
29
#include "codegen/Snippet.hpp"
30
#include "compile/ResolvedMethod.hpp"
31
#include "env/jittypes.h"
32
#include "env/CompilerEnv.hpp"
33
#include "env/VMJ9.h"
34
#include "il/DataTypes.hpp"
35
#include "il/LabelSymbol.hpp"
36
#include "il/Node.hpp"
37
#include "il/Node_inlines.hpp"
38
#include "il/TreeTop.hpp"
39
#include "il/TreeTop_inlines.hpp"
40
#include "p/codegen/GenerateInstructions.hpp"
41
#include "p/codegen/PPCInstruction.hpp"
42
#include "p/codegen/PPCRecompilationSnippet.hpp"
43
#include "env/CompilerEnv.hpp"
44
45
// Allocate a machine-specific recompilation processor for this compilation
46
//
47
TR::Recompilation *TR_PPCRecompilation::allocate(TR::Compilation *comp)
48
{
49
if (comp->isRecompilationEnabled())
50
{
51
return new (comp->trHeapMemory()) TR_PPCRecompilation(comp);
52
}
53
54
return NULL;
55
}
56
57
TR_PPCRecompilation::TR_PPCRecompilation(TR::Compilation * comp)
58
: TR::Recompilation(comp)
59
{
60
_countingSupported = true;
61
62
setupMethodInfo();
63
}
64
65
TR_PersistentMethodInfo *TR_PPCRecompilation::getExistingMethodInfo(TR_ResolvedMethod *method)
66
{
67
int8_t *startPC = (int8_t *)method->startAddressForInterpreterOfJittedMethod();
68
TR_PersistentMethodInfo *info = getJittedBodyInfoFromPC(startPC)->getMethodInfo();
69
return(info);
70
}
71
72
TR::Instruction *TR_PPCRecompilation::generatePrePrologue()
73
{
74
TR::Compilation *comp = cg()->comp();
75
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());
76
77
// If in Full Speed Debug, allow to go through
78
if (!couldBeCompiledAgain() && !comp->getOption(TR_FullSpeedDebug))
79
return(NULL);
80
81
// gr12 may contain the vtable offset, and must be preserved here
82
// see PicBuilder.s and Recompilation.s
83
TR::Instruction *cursor=NULL;
84
TR::Machine *machine = cg()->machine();
85
TR::Register *gr0 = machine->getRealRegister(TR::RealRegister::gr0);
86
TR::Node *firstNode = comp->getStartTree()->getNode();
87
TR::SymbolReference *recompileMethodSymRef = cg()->symRefTab()->findOrCreateRuntimeHelper(TR_PPCsamplingRecompileMethod);
88
TR_PersistentJittedBodyInfo *info = getJittedBodyInfo();
89
// force creation of switch to interpreter pre prologue if in Full Speed Debug
90
if (cg()->mustGenerateSwitchToInterpreterPrePrologue())
91
{
92
cursor = cg()->generateSwitchToInterpreterPrePrologue(cursor, firstNode);
93
}
94
95
if (useSampling() && couldBeCompiledAgain())
96
{
97
// gr0 must contain the saved LR; see Recompilation.s
98
cursor = new (cg()->trHeapMemory()) TR::PPCTrg1Instruction(TR::InstOpCode::mflr, firstNode, gr0, cursor, cg());
99
cursor = generateDepImmSymInstruction(cg(), TR::InstOpCode::bl, firstNode, (uintptr_t)recompileMethodSymRef->getMethodAddress(), new (cg()->trHeapMemory()) TR::RegisterDependencyConditions(0,0, cg()->trMemory()), recompileMethodSymRef, NULL, cursor);
100
if (comp->target().is64Bit())
101
{
102
int32_t highBits = (int32_t)((intptr_t)info>>32), lowBits = (int32_t)((intptr_t)info);
103
cursor = generateImmInstruction(cg(), TR::InstOpCode::dd, firstNode,
104
comp->target().cpu.isBigEndian()?highBits:lowBits, TR_BodyInfoAddress, cursor);
105
cursor = generateImmInstruction(cg(), TR::InstOpCode::dd, firstNode,
106
comp->target().cpu.isBigEndian()?lowBits:highBits, cursor);
107
}
108
else
109
{
110
cursor = generateImmInstruction(cg(), TR::InstOpCode::dd, firstNode, (int32_t)(intptr_t)info, TR_BodyInfoAddress, cursor);
111
}
112
cursor = generateImmInstruction(cg(), TR::InstOpCode::dd, firstNode, 0, cursor);
113
}
114
115
return(cursor);
116
}
117
118
119
TR::Instruction *TR_PPCRecompilation::generatePrologue(TR::Instruction *cursor)
120
{
121
if (couldBeCompiledAgain())
122
{
123
// gr12 may contain the vtable offset, and must be preserved here
124
// see PicBuilder.s and Recompilation.s
125
TR::Compilation *comp = cg()->comp();
126
TR::Machine *machine = cg()->machine();
127
TR::Register *gr0 = machine->getRealRegister(TR::RealRegister::gr0);
128
TR::Register *gr11 = machine->getRealRegister(TR::RealRegister::gr11);
129
TR::Register *cr0 = machine->getRealRegister(TR::RealRegister::cr0);
130
TR::Node *firstNode = comp->getStartTree()->getNode();
131
intptr_t addr = (intptr_t)getCounterAddress(); // What is the RL category?
132
TR::LabelSymbol *snippetLabel = generateLabelSymbol(cg());
133
134
if (comp->target().is64Bit())
135
{
136
intptr_t adjustedAddr = HI_VALUE(addr);
137
// lis gr11, upper 16-bits
138
cursor = generateTrg1ImmInstruction(cg(), TR::InstOpCode::lis, firstNode, gr11, (int16_t)adjustedAddr>>32, cursor );
139
// ori gr11, gr11, next 16-bit
140
cursor = generateTrg1Src1ImmInstruction(cg(), TR::InstOpCode::ori, firstNode, gr11, gr11, ((adjustedAddr>>16) & 0x0000FFFF), cursor);
141
// rldicr gr11, gr11, 32, 31
142
cursor = generateTrg1Src1Imm2Instruction(cg(), TR::InstOpCode::rldicr, firstNode, gr11, gr11, 32, CONSTANT64(0xFFFFFFFF00000000), cursor);
143
// oris gr11, gr11, next 16-bits
144
cursor = generateTrg1Src1ImmInstruction(cg(), TR::InstOpCode::oris, firstNode, gr11, gr11, (adjustedAddr & 0x0000FFFF), cursor);
145
}
146
else
147
{
148
cursor = generateTrg1ImmInstruction(cg(), TR::InstOpCode::lis, firstNode, gr11, (int16_t)HI_VALUE(addr), cursor);
149
}
150
151
// lwzu gr0, last 16-bits(gr11)
152
cursor = generateTrg1MemInstruction(cg(), (!isProfilingCompilation())?TR::InstOpCode::lwzu:TR::InstOpCode::lwz, firstNode, gr0,
153
TR::MemoryReference::createWithDisplacement(cg(), gr11, LO_VALUE(addr), 4), cursor);
154
155
if (!isProfilingCompilation())
156
{
157
cursor = generateTrg1Src1ImmInstruction(cg(), TR::InstOpCode::addic_r, firstNode, gr0, gr0, -1, cursor);
158
cursor = generateMemSrc1Instruction(cg(), TR::InstOpCode::stw, firstNode,
159
TR::MemoryReference::createWithDisplacement(cg(), gr11, (int32_t)0, 4), gr0, cursor);
160
}
161
else
162
{
163
// This only applies to JitProfiling, as JProfiling uses sampling
164
TR_ASSERT(comp->getProfilingMode() == JitProfiling, "JProfiling should not use counting mechanism to trip recompilation");
165
166
cursor = generateTrg1Src1ImmInstruction(cg(), TR::InstOpCode::cmpi4, firstNode, cr0, gr0, 0, cursor);
167
// this is just padding for consistent code length
168
cursor = generateTrg1Src2Instruction (cg(), TR::InstOpCode::OR, firstNode, gr11, gr11, gr11, cursor);
169
}
170
171
// gr0 must contain the saved LR; see Recompilation.s
172
cursor = generateTrg1Instruction(cg(), TR::InstOpCode::mflr, firstNode, gr0, cursor);
173
// this instruction is replaced after successful recompilation
174
cursor = generateTrg1Src2Instruction (cg(), TR::InstOpCode::OR, firstNode, gr11, gr11, gr11, cursor);
175
cursor = generateConditionalBranchInstruction(cg(), TR::InstOpCode::blt, firstNode, snippetLabel, cr0, cursor);
176
TR::Snippet *snippet = new (cg()->trHeapMemory()) TR::PPCRecompilationSnippet(snippetLabel, cursor->getPPCConditionalBranchInstruction(), cg());
177
cg()->addSnippet(snippet);
178
}
179
return(cursor);
180
}
181
182