Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/bcutil/ROMClassCreationContext.cpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2001, 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 "ROMClassCreationContext.hpp"
24
25
extern "C" void
26
romVerboseRecordPhaseStart(void *verboseContext, UDATA phase)
27
{
28
ROMClassCreationContext *context = (ROMClassCreationContext*)verboseContext;
29
context->recordPhaseStart(ROMClassCreationPhase(phase));
30
}
31
32
extern "C" void
33
romVerboseRecordPhaseEnd(void *verboseContext, UDATA phase)
34
{
35
ROMClassCreationContext *context = (ROMClassCreationContext*)verboseContext;
36
context->recordPhaseEnd(ROMClassCreationPhase(phase), OK);
37
}
38
39
void
40
ROMClassCreationContext::verbosePrintPhase(ROMClassCreationPhase phase, bool *printedPhases, UDATA indent)
41
{
42
static const char *verbosePhaseName[] = { /* Ensure this matches ROMClassCreationPhase */
43
"ROMClassCreation",
44
"ROMClassTranslation",
45
"CompareHashtableROMClass",
46
"CompareSharedROMClass",
47
"CreateSharedClass",
48
"WalkUTF8sAndMarkInterns",
49
"MarkAndCountUTF8s",
50
"VisitUTF8Block",
51
"WriteUTF8s",
52
"PrepareUTF8sAfterInternsMarked",
53
"ComputeExtraModifiers",
54
"ComputeOptionalFlags",
55
"ROMClassPrepareAndLayDown",
56
"PrepareROMClass",
57
"LayDownROMClass",
58
"ClassFileAnalysis",
59
"ClassFileHeaderAnalysis",
60
"ClassFileFieldsAnalysis",
61
"ClassFileAttributesAnalysis",
62
"ClassFileAttributesRecordAnalysis",
63
"ClassFileInterfacesAnalysis",
64
"ClassFileMethodsAnalysis",
65
"ClassFileMethodAttributesAnalysis",
66
"ClassFileAnnotationsAnalysis",
67
"ClassFileAnnotationElementAnalysis",
68
"ComputeSendSlotCount",
69
"ClassFileMethodThrownExceptionsAnalysis",
70
"ClassFileMethodCodeAttributeAnalysis",
71
"ClassFileMethodCodeAttributeAttributesAnalysis",
72
"ClassFileMethodMethodParametersAttributeAnalysis",
73
"CompressLineNumbers",
74
"ClassFileMethodCodeAttributeCaughtExceptionsAnalysis",
75
"ClassFileMethodCodeAttributeCodeAnalysis",
76
"CheckForLoop",
77
"ClassFileStackMapSlotsAnalysis",
78
"MethodIsFinalize",
79
"MethodIsEmpty",
80
"MethodIsForwarder",
81
"MethodIsGetter",
82
"MethodIsVirtual",
83
"MethodIsObjectConstructor",
84
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
85
"MethodIsConstructor",
86
"MethodIsNonStaticSynchronized",
87
#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */
88
"ShouldConvertInvokeVirtualToInvokeSpecial",
89
"ParseClassFile",
90
"ParseClassFileConstantPool",
91
"ParseClassFileFields",
92
"ParseClassFileMethods",
93
"ParseClassFileAttributes",
94
"ParseClassFileCheckClass",
95
"ParseClassFileVerifyClass",
96
"ParseClassFileInlineJSRs",
97
"ConstantPoolMapping",
98
"SRPOffsetTableCreation"
99
};
100
101
if (!printedPhases[phase]) {
102
printedPhases[phase] = true;
103
if ((0 != _verboseRecords[phase].accumulatedTime) || (0 != _verboseRecords[phase].failureTime) || (OK != _verboseRecords[phase].buildResult)) {
104
bool printCompactElement = (0 == _verboseRecords[phase].failureTime) && (OK == _verboseRecords[phase].buildResult);
105
ROMClassCreationPhase nested = ROMClassCreationPhase(phase + 1);
106
/*
107
* Look for a nested phase.
108
* Postcondition: printCompactElement || (phase != _verboseRecords[i].parentPhase where i < nested && i > phase)
109
*/
110
while (printCompactElement && (nested < ROMClassCreationPhaseCount)) {
111
if (phase == _verboseRecords[nested].parentPhase) {
112
printCompactElement = false;
113
} else {
114
++nested;
115
}
116
}
117
118
PORT_ACCESS_FROM_PORT(_portLibrary);
119
if (printCompactElement) {
120
j9tty_printf(_portLibrary, "% *c<phase name=\"%s\" totalusec=\"%i\" />\n", indent, ' ', verbosePhaseName[phase], _verboseRecords[phase].accumulatedTime);
121
} else {
122
j9tty_printf(_portLibrary, "% *c<phase name=\"%s\" totalusec=\"%i\">\n", indent, ' ', verbosePhaseName[phase], _verboseRecords[phase].accumulatedTime);
123
if (0 != _verboseRecords[phase].failureTime) {
124
j9tty_printf(_portLibrary, "% *c<failures totalusec=\"%i\" />\n", indent + 2, ' ', _verboseRecords[phase].failureTime);
125
}
126
if (OK != _verboseRecords[phase].buildResult) {
127
j9tty_printf(_portLibrary, "% *c<result value=\"%i\" />\n", indent + 2, ' ', buildResultString(_verboseRecords[phase].buildResult));
128
}
129
130
/*
131
* Print nested phases.
132
* Precondition: phase != _verboseRecords[i].parentPhase where i < nested && i > phase
133
*/
134
while (nested < ROMClassCreationPhaseCount) {
135
if (phase == _verboseRecords[nested].parentPhase) {
136
verbosePrintPhase(nested, printedPhases, indent + 2);
137
}
138
++nested;
139
}
140
141
j9tty_printf(_portLibrary, "% *c</phase>\n", indent, ' ');
142
}
143
}
144
}
145
}
146
147
const char *
148
ROMClassCreationContext::buildResultString(BuildResult result)
149
{
150
switch (result) {
151
case OK: return "OK";
152
case GenericError: return "GenericError";
153
case OutOfROM: return "OutOfROM";
154
case ClassRead: return "ClassRead";
155
case BytecodeTranslationFailed: return "BytecodeTranslationFailed";
156
case StackMapFailed: return "StackMapFailed";
157
case InvalidBytecode: return "InvalidBytecode";
158
case OutOfMemory: return "OutOfMemory";
159
case VerifyErrorInlining: return "VerifyErrorInlining";
160
case NeedWideBranches: return "NeedWideBranches";
161
case UnknownAnnotation: return "UnknownAnnotation";
162
case ClassNameMismatch: return "ClassNameMismatch";
163
case InvalidAnnotation: return "InvalidAnnotation";
164
case InvalidClassType: return "InvalidClassType";
165
default: return "Unknown";
166
}
167
}
168
169
void
170
ROMClassCreationContext::reportVerboseStatistics()
171
{
172
bool printedPhases[ROMClassCreationPhaseCount] = { false, }; // TODO check correct initialization syntax
173
174
PORT_ACCESS_FROM_PORT(_portLibrary);
175
j9tty_printf(_portLibrary, "<romclass name=\"%.*s\" result=\"%s\">\n", _classNameLength, _className, buildResultString(_buildResult));
176
for (ROMClassCreationPhase phase = ROMClassCreation; phase != ROMClassCreationPhaseCount; ++phase) {
177
verbosePrintPhase(phase, printedPhases, 2);
178
}
179
if (0 != _verboseOutOfMemoryCount) {
180
j9tty_printf(_portLibrary, " <oom count=\"%i\" lastBufferSizeExceeded=\"%i\" />\n", _verboseOutOfMemoryCount, _verboseLastBufferSizeExceeded);
181
182
}
183
j9tty_printf(_portLibrary, "</romclass>\n");
184
}
185
186
J9ROMMethod *
187
ROMClassCreationContext::romMethodFromOffset(IDATA offset)
188
{
189
J9ROMMethod *returnMethod = NULL;
190
if (NULL != _romClass) {
191
UDATA romclassaddr = ((UDATA)_romClass) + offset;
192
J9ROMMethod *currentMethod = J9ROMCLASS_ROMMETHODS(_romClass);
193
194
for (UDATA i = 0; i < _romClass->romMethodCount; i++) {
195
/* There's no easy way to get the exact end of a ROMMethod, so iterate
196
* thru the methods until we get to the last one.
197
*
198
* TODO:
199
* - If a bad & large address is being looked for the last method
200
* will be returned.
201
* - If a bad & small address is being looked for then null will be returned.
202
* - A function similar to nextROMMethod should maybe written to replace this logic,
203
* except have it return the end addr of the method.
204
*/
205
if (romclassaddr >= (UDATA)currentMethod) {
206
returnMethod = currentMethod;
207
currentMethod = nextROMMethod(currentMethod);
208
continue;
209
} else {
210
break;
211
}
212
}
213
}
214
return returnMethod;
215
}
216
217