Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/dbgext/dbgpool.c
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2014 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 "j9dbgext.h"
24
#include "j9protos.h"
25
26
#define J9DBGEXTPOOL_PUDDLELIST(base) LOCAL_WSRP_GET((base)->puddleList, J9PoolPuddleList *)
27
#define J9DBGEXTPOOLPUDDLELIST_NEXTPUDDLE(base) LOCAL_WSRP_GET((base)->nextPuddle, J9PoolPuddle *)
28
#define J9DBGEXTPOOLPUDDLE_NEXTPUDDLE(base) LOCAL_WSRP_GET((base)->nextPuddle, J9PoolPuddle *)
29
30
#define DEFAULT_J9POOL_WALK_PFUNC defaultJ9PoolWalkPFunc
31
extern J9Pool * dbgRead_J9Pool(void*);
32
extern J9PoolPuddle * dbgRead_J9PoolPuddle(void*);
33
34
#define PARSE_FUNC_PTR(args,pFunc) \
35
parseFuncPtr(args,(void (**)(void*,J9PoolWalkData*))(&pFunc))
36
37
void defaultJ9PoolWalkPFunc(void *addr, J9PoolWalkData *data)
38
{
39
/* userData contains the segment offset */
40
dbgPrint("\t[%d]\t=\t0x%zx\n", data->counter, (UDATA)addr + data->puddle->userData);
41
}
42
43
44
static void parseFuncPtr(const char *args, void (**ppFunc)(void*,J9PoolWalkData*))
45
{
46
if(ppFunc != NULL) {
47
*ppFunc = DEFAULT_J9POOL_WALK_PFUNC;
48
}
49
}
50
51
52
static J9PoolPuddle *
53
mapPuddle(J9Pool* head, UDATA addr)
54
{
55
UDATA bytesToBeRead;
56
IDATA segmentOffset;
57
J9PoolPuddle *puddle = NULL;
58
59
bytesToBeRead = head->puddleAllocSize;
60
puddle = dbgMallocAndRead(bytesToBeRead, (void*)addr);
61
if(puddle == NULL) {
62
dbgError("\tcould not map J9PoolPuddle at 0x%p (%zu bytes).\n", addr, bytesToBeRead);
63
return NULL;
64
}
65
66
segmentOffset = addr - (UDATA)puddle;
67
puddle->userData = segmentOffset;
68
69
/* adjust nextPuddle & friends to be accurate */
70
if (puddle->nextPuddle != 0) {
71
puddle->nextPuddle += segmentOffset;
72
}
73
if (puddle->prevPuddle != 0) {
74
puddle->prevPuddle += segmentOffset;
75
}
76
if (puddle->nextAvailablePuddle != 0) {
77
puddle->nextAvailablePuddle += segmentOffset;
78
}
79
if (puddle->prevAvailablePuddle != 0) {
80
puddle->prevAvailablePuddle += segmentOffset;
81
}
82
83
return puddle;
84
}
85
86
void dbgUnmapPool(J9Pool *pool)
87
{
88
J9PoolPuddleList *puddleList;
89
J9PoolPuddle *thisPuddle, *nextPuddle;
90
91
puddleList = J9DBGEXTPOOL_PUDDLELIST(pool);
92
thisPuddle = J9DBGEXTPOOLPUDDLELIST_NEXTPUDDLE(puddleList);
93
nextPuddle = NULL;
94
while(thisPuddle != NULL) {
95
nextPuddle = J9DBGEXTPOOLPUDDLE_NEXTPUDDLE(thisPuddle);
96
dbgFree(thisPuddle);
97
thisPuddle = nextPuddle;
98
}
99
dbgFree(puddleList);
100
dbgFree(pool);
101
}
102
103
104
J9Pool *dbgMapPool(UDATA addr)
105
{
106
J9Pool *pool = (J9Pool*)dbgRead_J9Pool((void*)addr);
107
J9PoolPuddleList *puddleList, *mappedPuddleList;
108
J9PoolPuddle *poolNextPuddle, *prevPuddle, *walk;
109
IDATA offset;
110
UDATA bytesRead;
111
112
puddleList = J9POOL_PUDDLELIST(pool);
113
mappedPuddleList = dbgMalloc(sizeof(J9PoolPuddleList), puddleList);
114
if (!mappedPuddleList) {
115
dbgError("could not allocate temp space for J9PoolPuddleList\n");
116
return NULL;
117
}
118
119
dbgReadMemory( (UDATA) puddleList, mappedPuddleList, sizeof(J9PoolPuddleList), &bytesRead);
120
if (bytesRead != sizeof(J9PoolPuddleList)) {
121
dbgError("could not read J9PoolPuddleList at %p\n", puddleList);
122
return NULL;
123
}
124
125
offset = (UDATA)puddleList - (UDATA)mappedPuddleList;
126
if (mappedPuddleList->nextAvailablePuddle) {
127
mappedPuddleList->nextAvailablePuddle += offset;
128
}
129
if (mappedPuddleList->nextPuddle) {
130
mappedPuddleList->nextPuddle += offset;
131
}
132
133
NNWSRP_SET(pool->puddleList, mappedPuddleList);
134
walk = poolNextPuddle = J9DBGEXTPOOLPUDDLELIST_NEXTPUDDLE(mappedPuddleList);
135
prevPuddle = NULL;
136
137
while(walk != NULL) {
138
J9PoolPuddle *mappedPuddle = NULL;
139
mappedPuddle = mapPuddle(pool, (UDATA)walk);
140
if (mappedPuddle == NULL) {
141
dbgFree(mappedPuddleList);
142
dbgFree(pool);
143
return NULL;
144
}
145
if (walk == poolNextPuddle) {
146
NNWSRP_SET(mappedPuddleList->nextPuddle, mappedPuddle);
147
}
148
if (NULL != prevPuddle) {
149
NNWSRP_SET(prevPuddle->nextPuddle, mappedPuddle);
150
}
151
WSRP_SET(mappedPuddle->prevPuddle, prevPuddle);
152
walk = J9DBGEXTPOOLPUDDLE_NEXTPUDDLE(mappedPuddle);
153
WSRP_SET(mappedPuddle->nextPuddle, NULL);
154
prevPuddle = mappedPuddle;
155
}
156
157
return pool;
158
}
159
160
/**
161
* @return 1 if the puddle contains the given element, 0 otherwise
162
*/
163
static UDATA
164
puddleContainsElement(J9Pool* head, J9PoolPuddle *puddle, void *element)
165
{
166
UDATA puddleBase = (UDATA)LOCAL_WSRP_GET(puddle->firstElementAddress, void*);
167
UDATA puddleTop = puddleBase + (head->elementSize * head->elementsPerPuddle);
168
169
if( ((UDATA)element >= puddleBase) && ((UDATA)element < puddleTop) ) {
170
return 1;
171
}
172
return 0;
173
}
174
175
void walkJ9Pool(UDATA addr, void (*pFunc)(void*,J9PoolWalkData*), J9PoolWalkData*data)
176
{
177
J9Pool *pool;
178
179
if (!addr) {
180
dbgError("bad or missing J9Pool at 0x%p\n",addr);
181
return;
182
}
183
184
pool = dbgMapPool(addr);
185
if (pool != NULL) {
186
J9PoolPuddleList *puddleList = J9DBGEXTPOOL_PUDDLELIST(pool);
187
void *anElement;
188
pool_state aState;
189
anElement = pool_startDo(pool, &aState);
190
191
data->head = pool;
192
data->puddle = J9DBGEXTPOOLPUDDLELIST_NEXTPUDDLE(puddleList);
193
194
for( data->counter = 0; anElement != NULL; data->counter++ ) {
195
while(!puddleContainsElement(data->head, data->puddle, anElement)) {
196
data->puddle = J9DBGEXTPOOLPUDDLE_NEXTPUDDLE(data->puddle);
197
if(data->puddle == NULL) {
198
dbgError("\tcould not locate element 0x%p in J9Pool at 0x%p\n", anElement, addr);
199
return;
200
}
201
}
202
203
(pFunc)(anElement, data);
204
anElement = pool_nextDo(&aState);
205
}
206
207
dbgUnmapPool(pool);
208
} else {
209
dbgError("could not map J9Pool at 0x%p\n",addr);
210
}
211
}
212
213
void dbgext_walkj9pool(const char *args)
214
{
215
UDATA addr = dbgGetExpression(args);
216
J9PoolWalkData data;
217
void (*pFunc)(void*,J9PoolWalkData*);
218
219
PARSE_FUNC_PTR(args,pFunc);
220
if(pFunc == DEFAULT_J9POOL_WALK_PFUNC) {
221
dbgPrint("J9Pool at 0x%zx\n{\n",addr);
222
walkJ9Pool(addr,pFunc,&data);
223
dbgPrint("}\n");
224
} else {
225
walkJ9Pool(addr,pFunc,&data);
226
}
227
}
228
229
230
231
232
233
234