Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_base/QueryGCStatus.cpp
5986 views
1
2
/*******************************************************************************
3
* Copyright (c) 1991, 2014 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* 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
22
*******************************************************************************/
23
24
#include "j9.h"
25
#include "j9cfg.h"
26
#include "jni.h"
27
#include "j9protos.h"
28
29
#include "AllocationFailureStats.hpp"
30
#include "GCExtensions.hpp"
31
#include "Heap.hpp"
32
#include "MemorySpace.hpp"
33
#include "MemorySubSpace.hpp"
34
#include "VMInterface.hpp"
35
36
extern "C" {
37
#define QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_ENABLED 2
38
#define QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_DISABLED 1
39
/**
40
* Query the state of the Garbage Collector.
41
*
42
* Initially, the API should be called with a statusSize of 0. This call will return
43
* JNI_EINVAL and nHeaps, which is the number of storage structures for which data will be
44
* returned. This allows the caller to calculate how large statusSize should be by using
45
* something similar to nHeaps * sizeof(GCStatus).
46
*
47
* The API returns the data in the supplied array and can be interrogated using the heap field
48
* to identify whether the data is for a heap or shared memory. If the data is for shared memory,
49
* the count field can be used to identify whether the data is for the shared memory page pool
50
* or for a subpool. There is no implied order in which the data is returned.
51
*
52
* @param vm The javaVM
53
* @param nHeap Number of heaps for which data has been returned
54
* @param status An array of GCStatus structures
55
* @param statusSize The size of the status array in bytes
56
*
57
* @return JNI_OK Call completed successfully
58
* @return JNI_ERR Processing the request failed
59
* @return JNI_EINVAL The query given was invalid, for example, the size of the status array is too small.
60
*/
61
jint JNICALL
62
queryGCStatus(JavaVM *vm, jint *nHeaps, GCStatus *status, jint statusSize)
63
{
64
J9JavaVM *javaVM = (J9JavaVM *)vm;
65
jint filledElements = *nHeaps; /* Number of elements of status that are filled */
66
jint returnCode = JNI_OK;
67
68
/* may not be attached to a VM */
69
/*
70
if (omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT)) {
71
return JNI_ERR;
72
}
73
javaVM->internalVMFunctions->acquireExclusiveVMAccessFromExternalThread(javaVM);
74
*/
75
76
/* From here on in, must branch to exit to return. Do not return directly */
77
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
78
MM_MemorySpace *memorySpace = extensions->heap->getMemorySpaceList();
79
80
/* first call? */
81
if (0 == statusSize) {
82
/* Return JNI_EINVAL and update nHeaps to be the number of storage structures
83
* that will be populated.
84
*/
85
*nHeaps = 0;
86
while (memorySpace) {
87
#if defined (J9VM_GC_MODRON_SCAVENGER)
88
if (extensions->scavengerEnabled) {
89
*nHeaps += QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_ENABLED;
90
} else
91
#endif /* J9VM_GC_MODRON_SCAVENGER */
92
{
93
*nHeaps += QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_DISABLED;
94
}
95
96
memorySpace = memorySpace->getNext();
97
}
98
returnCode = JNI_EINVAL;
99
goto done;
100
}
101
102
/* Sanity check, it may be some incorrect large number, but it can never be negative */
103
if (*nHeaps < 0) {
104
returnCode = JNI_EINVAL;
105
goto done;
106
}
107
108
/* Sanity check, it may be some incorrect large number, but it can never be negative */
109
if (statusSize < 0) {
110
returnCode = JNI_EINVAL;
111
goto done;
112
}
113
114
/* Sanity check, are there enough array elements to hold the requested data? */
115
if (statusSize != (*nHeaps) * (jint)sizeof(GCStatus)) {
116
returnCode = JNI_EINVAL;
117
goto done;
118
}
119
120
/* Initialize the return structure to known values */
121
memset((void *)status, 0, statusSize);
122
while ((NULL != memorySpace) && (0 != filledElements)) {
123
#if defined(J9VM_GC_MODRON_SCAVENGER)
124
if (extensions->scavengerEnabled) {
125
MM_MemorySubSpace *defaultMemorySubSpace = memorySpace->getDefaultMemorySubSpace();
126
MM_AllocationFailureStats *allocationFailureStats = defaultMemorySubSpace->getAllocationFailureStats();
127
status->heap = (jint) JNI_GCQUERY_NURSERY_HEAP;
128
status->count = (jint) allocationFailureStats->allocationFailureCount;
129
status->freestorage = (jlong) defaultMemorySubSpace->getActualFreeMemorySize();
130
status->totalstorage = (jlong) defaultMemorySubSpace->getActiveMemorySize();
131
status += 1;
132
filledElements -=1;
133
}
134
#endif /* J9VM_GC_MODRON_SCAVENGER */
135
136
MM_MemorySubSpace *tenuredMemorySubSpace = memorySpace->getTenureMemorySubSpace();
137
MM_AllocationFailureStats *tenuredAllocationFailureStats = tenuredMemorySubSpace->getAllocationFailureStats();
138
status->heap = (jint) JNI_GCQUERY_MATURE_HEAP;
139
status->count = (jint) tenuredAllocationFailureStats->allocationFailureCount;
140
status->freestorage = (jlong) tenuredMemorySubSpace->getActualFreeMemorySize();
141
status->totalstorage = (jlong) tenuredMemorySubSpace->getActiveMemorySize();
142
status += 1;
143
filledElements -=1;
144
145
memorySpace = memorySpace->getNext();
146
}
147
148
/* Yet another sanity check. If there is a mismatch between the expected number
149
* of elements to be returned, and the actual number of elements filled
150
* inform the user. Don't wipe the data already collected.
151
*/
152
if ((NULL != memorySpace) || (0 != filledElements)) {
153
returnCode = JNI_EINVAL;
154
}
155
156
done:
157
158
/*
159
javaVM->internalVMFunctions->releaseExclusiveVMAccessFromExternalThread(javaVM);
160
omrthread_detach(NULL);
161
*/
162
return returnCode;
163
}
164
165
} /* extern "C" */
166
167
168