Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/codegen/J9WatchedStaticFieldSnippet.cpp
6000 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 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 "codegen/J9WatchedStaticFieldSnippet.hpp"
24
#include "codegen/Relocation.hpp"
25
#include "il/SymbolReference.hpp"
26
27
TR::J9WatchedStaticFieldSnippet::J9WatchedStaticFieldSnippet(TR::CodeGenerator *cg, TR::Node *node, J9Method *m, UDATA loc, void *fieldAddress, J9Class *fieldClass)
28
: TR::Snippet(cg, node, generateLabelSymbol(cg), false)
29
{
30
staticFieldData.method = m;
31
staticFieldData.location = loc;
32
staticFieldData.fieldAddress = fieldAddress;
33
staticFieldData.fieldClass = fieldClass;
34
}
35
36
uint8_t *TR::J9WatchedStaticFieldSnippet::emitSnippetBody()
37
{
38
uint8_t *cursor = cg()->getBinaryBufferCursor();
39
getSnippetLabel()->setCodeLocation(cursor);
40
TR::Node *node = getNode();
41
42
// We emit the dataSnippet based on the assumption that the J9JITWatchedStaticFieldData structure is laid out as below:
43
/*
44
typedef struct J9JITWatchedStaticFieldData {
45
J9Method *method; // Currently executing method
46
UDATA location; // Bytecode PC index
47
void *fieldAddress; // Address of static field storage
48
J9Class *fieldClass; // Declaring class of static field
49
} J9JITWatchedStaticFieldData;
50
*/
51
52
// Emit each field and add a relocation record (for AOT compiles) for any field if needed.
53
J9JITWatchedStaticFieldData *str = reinterpret_cast<J9JITWatchedStaticFieldData *>(cursor);
54
str->method = staticFieldData.method;
55
str->location = staticFieldData.location;
56
str->fieldAddress = staticFieldData.fieldAddress;
57
str->fieldClass = staticFieldData.fieldClass;
58
59
if (cg()->comp()->getOption(TR_UseSymbolValidationManager))
60
{
61
cg()->addExternalRelocation(
62
new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor + offsetof(J9JITWatchedStaticFieldData, method), reinterpret_cast<uint8_t *>(staticFieldData.method), reinterpret_cast<uint8_t *>(TR::SymbolType::typeMethod), TR_SymbolFromManager, cg()),
63
__FILE__,
64
__LINE__,
65
node);
66
}
67
else if (cg()->needClassAndMethodPointerRelocations())
68
{
69
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor + offsetof(J9JITWatchedStaticFieldData, method), NULL, TR_RamMethod, cg()), __FILE__, __LINE__, node);
70
}
71
72
bool isResolved = !node->getSymbolReference()->isUnresolved();
73
// If the field is unresolved then we populate these snippet fields with the correct value at runtime (via the instructions generated by generateFillInDataBlockSequenceForUnresolvedField)
74
// and hence don't need to add relocation records here.
75
if (isResolved)
76
{
77
if (cg()->needRelocationsForStatics())
78
{
79
cg()->addExternalRelocation(
80
new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor + offsetof(J9JITWatchedStaticFieldData, fieldAddress), reinterpret_cast<uint8_t *>(node->getSymbolReference()), reinterpret_cast<uint8_t *>(node->getInlinedSiteIndex()), TR_DataAddress, cg()),
81
__FILE__,
82
__LINE__,
83
node);
84
}
85
86
if (cg()->comp()->getOption(TR_UseSymbolValidationManager))
87
{
88
cg()->addExternalRelocation(
89
new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor + offsetof(J9JITWatchedStaticFieldData, fieldClass), reinterpret_cast<uint8_t *>(staticFieldData.fieldClass), reinterpret_cast<uint8_t *>(TR::SymbolType::typeClass), TR_SymbolFromManager, cg()),
90
__FILE__,
91
__LINE__,
92
node);
93
}
94
// relocations for TR_ClassAddress are needed for AOT/AOTaaS compiles and not needed for regular JIT and JITServer compiles.
95
// cg->needClassAndMethodPointerRelocations() tells us whether a relocation is needed depending on the type of compile being performed.
96
else if (cg()->needClassAndMethodPointerRelocations())
97
{
98
// As things currently stand, this will not work on Power because TR_ClassAddress is used to a generate a 5 instruction sequence that materializes the address into a register. Meanwhile we are using TR_ClassAddress here to represent a contiguous word.
99
// A short-term solution would be to use TR_ClassPointer. However this is hacky because TR_ClassPointer expects an aconst node (so we would have to create a dummy node). The proper solution would be to implement the functionality in the power
100
// codegenerator to be able to patch TR_ClassAddress contiguous word.
101
cg()->addExternalRelocation(
102
new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor + offsetof(J9JITWatchedStaticFieldData, fieldClass), reinterpret_cast<uint8_t *>(node->getSymbolReference()), reinterpret_cast<uint8_t *>(node->getInlinedSiteIndex()), TR_ClassAddress, cg()),
103
__FILE__,
104
__LINE__,
105
node);
106
}
107
}
108
109
cursor += sizeof(J9JITWatchedStaticFieldData);
110
111
return cursor;
112
}
113
114
void TR::J9WatchedStaticFieldSnippet::print(TR::FILE *pOutFile, TR_Debug *debug)
115
{
116
uint8_t *bufferPos = getSnippetLabel()->getCodeLocation();
117
118
debug->printSnippetLabel(pOutFile, getSnippetLabel(), bufferPos, "J9WatchedStaticFieldSnippet");
119
120
debug->printPrefix(pOutFile, NULL, bufferPos, sizeof(J9Method *));
121
trfprintf(pOutFile, "DC \t%p \t\t# J9Method", *(reinterpret_cast<J9Method **>(bufferPos)));
122
bufferPos += sizeof(J9Method *);
123
124
debug->printPrefix(pOutFile, NULL, bufferPos, sizeof(UDATA));
125
trfprintf(pOutFile, "DC \t%lu \t\t# location", *(reinterpret_cast<UDATA *>(bufferPos)));
126
bufferPos += sizeof(UDATA);
127
128
debug->printPrefix(pOutFile, NULL, bufferPos, sizeof(void *));
129
trfprintf(pOutFile, "DC \t%p \t\t# fieldAddress", *(reinterpret_cast<void **>(bufferPos)));
130
bufferPos += sizeof(void *);
131
132
debug->printPrefix(pOutFile, NULL, bufferPos, sizeof(J9Class *));
133
trfprintf(pOutFile, "DC \t%p \t\t# fieldClass", *(reinterpret_cast<J9Class **>(bufferPos)));
134
bufferPos += sizeof(J9Class *);
135
}
136
137
138