Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_base/HotFieldUtil.cpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2020, 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 "j9.h"
24
#include "j9cfg.h"
25
26
#if defined(J9VM_GC_MODRON_SCAVENGER) || defined(J9VM_GC_VLHGC)
27
28
#include "HotFieldUtil.hpp"
29
#include "GCExtensions.hpp"
30
31
/* Value used to help with the incrementing of the gc count between hot field sorting for dynamicBreadthFirstScanOrdering */
32
#define INCREMENT_GC_COUNT_BETWEEN_HOT_FIELD_SORT 100
33
34
/* Minimum hotness value for a third hot field offset if depthCopyThreePaths is enabled for dynamicBreadthFirstScanOrdering */
35
#define MINIMUM_THIRD_HOT_FIELD_HOTNESS 50000
36
37
void
38
MM_HotFieldUtil::sortAllHotFieldData(J9JavaVM *javaVM, uintptr_t gcCount)
39
{
40
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
41
42
/* update hottest fields for all elements of the hotFieldClassInfoPool where isClassHotFieldListDirty is true */
43
if ((NULL != javaVM->hotFieldClassInfoPool) && ((gcCount % extensions->gcCountBetweenHotFieldSort) == 0)) {
44
omrthread_monitor_enter(javaVM->hotFieldClassInfoPoolMutex);
45
pool_state hotFieldClassInfoPoolState;
46
J9ClassHotFieldsInfo *hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo*)pool_startDo(javaVM->hotFieldClassInfoPool, &hotFieldClassInfoPoolState);
47
48
/* sort hot field list for the class if the hot field list of the class is dirty */
49
while ((NULL != hotFieldClassInfoTemp) && (U_8_MAX != hotFieldClassInfoTemp->consecutiveHotFieldSelections)) {
50
if (hotFieldClassInfoTemp->isClassHotFieldListDirty) {
51
sortClassHotFieldList(javaVM, hotFieldClassInfoTemp);
52
}
53
hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo*)pool_nextDo(&hotFieldClassInfoPoolState);
54
}
55
omrthread_monitor_exit(javaVM->hotFieldClassInfoPoolMutex);
56
}
57
58
/* If adaptiveGcCountBetweenHotFieldSort, update the gc count required between sorting all hot fields as the application runs longer */
59
if ((extensions->adaptiveGcCountBetweenHotFieldSort) && (extensions->gcCountBetweenHotFieldSort < extensions->gcCountBetweenHotFieldSortMax) && ((gcCount % INCREMENT_GC_COUNT_BETWEEN_HOT_FIELD_SORT) == 0)) {
60
extensions->gcCountBetweenHotFieldSort++;
61
}
62
63
/* If hotFieldResettingEnabled, update the gc count required between resetting all hot fields */
64
if ((extensions->hotFieldResettingEnabled) && ((gcCount % extensions->gcCountBetweenHotFieldReset) == 0)) {
65
resetAllHotFieldData(javaVM);
66
}
67
}
68
69
MMINLINE void
70
MM_HotFieldUtil::sortClassHotFieldList(J9JavaVM *javaVM, J9ClassHotFieldsInfo* hotFieldClassInfo)
71
{
72
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
73
74
/* store initial hot field offsets before hotFieldClassInfo hot field offsets are updated */
75
uint8_t initialHotFieldOffset1 = hotFieldClassInfo->hotFieldOffset1;
76
uint8_t initialHotFieldOffset2 = hotFieldClassInfo->hotFieldOffset2;
77
uint8_t initialHotFieldOffset3 = hotFieldClassInfo->hotFieldOffset3;
78
79
/* compute and update the hot fields for each class */
80
if (1 == hotFieldClassInfo->hotFieldListLength) {
81
hotFieldClassInfo->hotFieldOffset1 = hotFieldClassInfo->hotFieldListHead->hotFieldOffset;
82
} else {
83
J9HotField* currentHotField = hotFieldClassInfo->hotFieldListHead;
84
uint64_t hottest = 0;
85
uint64_t secondHottest = 0;
86
uint64_t thirdHottest = 0;
87
uint64_t current = 0;
88
while (NULL != currentHotField) {
89
if(currentHotField->cpuUtil > extensions->minCpuUtil) {
90
current = currentHotField->hotness;
91
/* compute the three hottest fields if depthCopyThreePaths is enabled, or the two hottest fields if only depthCopyTwoPaths is enabled, otherwise, compute just the hottest field if both depthCopyTwoPaths and depthCopyThreePaths are disabled */
92
if (extensions->depthCopyThreePaths) {
93
if (current > hottest) {
94
thirdHottest = secondHottest;
95
hotFieldClassInfo->hotFieldOffset3 = hotFieldClassInfo->hotFieldOffset2;
96
secondHottest = hottest;
97
hotFieldClassInfo->hotFieldOffset2 = hotFieldClassInfo->hotFieldOffset1;
98
hottest = current;
99
hotFieldClassInfo->hotFieldOffset1 = currentHotField->hotFieldOffset;
100
} else if (current > secondHottest) {
101
thirdHottest = secondHottest;
102
hotFieldClassInfo->hotFieldOffset3 = hotFieldClassInfo->hotFieldOffset2;
103
secondHottest = current;
104
hotFieldClassInfo->hotFieldOffset2 = currentHotField->hotFieldOffset;
105
} else if (current > thirdHottest) {
106
thirdHottest = current;
107
hotFieldClassInfo->hotFieldOffset3 = currentHotField->hotFieldOffset;
108
}
109
} else if (extensions->depthCopyTwoPaths) {
110
if (current > hottest) {
111
secondHottest = hottest;
112
hotFieldClassInfo->hotFieldOffset2 = hotFieldClassInfo->hotFieldOffset1;
113
hottest = current;
114
hotFieldClassInfo->hotFieldOffset1 = currentHotField->hotFieldOffset;
115
} else if (current > secondHottest) {
116
secondHottest = current;
117
hotFieldClassInfo->hotFieldOffset2 = currentHotField->hotFieldOffset;
118
}
119
} else if (current > hottest) {
120
hottest = current;
121
hotFieldClassInfo->hotFieldOffset1 = currentHotField->hotFieldOffset;
122
}
123
}
124
currentHotField = currentHotField->next;
125
}
126
if (thirdHottest < MINIMUM_THIRD_HOT_FIELD_HOTNESS) {
127
hotFieldClassInfo->hotFieldOffset3 = U_8_MAX;
128
}
129
}
130
/* if permanantHotFields are allowed, update consecutiveHotFieldSelections counter if hot field offsets are the same as the previous time the class hot field list was sorted */
131
if (extensions->allowPermanantHotFields) {
132
if ((initialHotFieldOffset1 == hotFieldClassInfo->hotFieldOffset1) && (initialHotFieldOffset2 == hotFieldClassInfo->hotFieldOffset2) && (initialHotFieldOffset3 == hotFieldClassInfo->hotFieldOffset3)) {
133
hotFieldClassInfo->consecutiveHotFieldSelections++;
134
if (hotFieldClassInfo->consecutiveHotFieldSelections == extensions->maxConsecutiveHotFieldSelections) {
135
hotFieldClassInfo->consecutiveHotFieldSelections = U_8_MAX;
136
}
137
} else {
138
hotFieldClassInfo->consecutiveHotFieldSelections = 0;
139
}
140
}
141
hotFieldClassInfo->isClassHotFieldListDirty = false;
142
}
143
144
/**
145
* Reset all hot fields for all classes.
146
* Used when dynamicBreadthFirstScanOrdering is enabled and hotFieldResettingEnabled is true.
147
*
148
* @param javaVM[in] pointer to the J9JavaVM
149
*/
150
MMINLINE void
151
MM_HotFieldUtil::resetAllHotFieldData(J9JavaVM *javaVM)
152
{
153
omrthread_monitor_enter(javaVM->hotFieldClassInfoPoolMutex);
154
pool_state hotFieldClassInfoPoolState;
155
J9ClassHotFieldsInfo *hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo *)pool_startDo(javaVM->hotFieldClassInfoPool, &hotFieldClassInfoPoolState);
156
while (NULL != hotFieldClassInfoTemp) {
157
J9HotField* currentHotField = hotFieldClassInfoTemp->hotFieldListHead;
158
while (NULL != currentHotField) {
159
currentHotField->hotness = 0;
160
currentHotField->cpuUtil = 0;
161
currentHotField = currentHotField->next;
162
}
163
hotFieldClassInfoTemp = (struct J9ClassHotFieldsInfo*)pool_nextDo(&hotFieldClassInfoPoolState);
164
}
165
omrthread_monitor_exit(javaVM->hotFieldClassInfoPoolMutex);
166
}
167
168
#endif /* J9VM_GC_MODRON_SCAVENGER || J9VM_GC_VLHGC */
169
170