-
Notifications
You must be signed in to change notification settings - Fork 746
/
Copy pathshcdatautils.c
166 lines (145 loc) · 5.5 KB
/
shcdatautils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*******************************************************************************
* Copyright IBM Corp. and others 2001
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution and
* is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following
* Secondary Licenses when the conditions for such availability set
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
* General Public License, version 2 with the GNU Classpath
* Exception [1] and GNU General Public License, version 2 with the
* OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#include "shcdatautils.h"
/* This is a bunch of utility functions for walking a cache in and out of process */
/* Given a VM, this returns a pointer to the start of the metadata, the first metadata entry and the length
* This is designed to match the dbg version of this function which is in dbgext.c */
void*
shcReadSharedCacheMetadata(J9JavaVM* vm, UDATA* length, ShcItemHdr** firstEntry)
{
if (vm->sharedClassConfig) {
J9SharedClassConfig* config = vm->sharedClassConfig;
if (config->metadataMemorySegment) {
J9MemorySegment* metadataMemorySegment = config->metadataMemorySegment;
UDATA size = (metadataMemorySegment->heapTop - metadataMemorySegment->heapBase);
if (size > 0) {
void* metaStart = metadataMemorySegment->heapBase;
if (length) {
*length = size;
}
if (firstEntry) {
*firstEntry = (ShcItemHdr*)((((U_8*)metaStart) + size) - sizeof(ShcItemHdr));
}
return metaStart;
}
}
}
return NULL;
}
/**
* Walks a cache in or out of process.
*
* @see shcSharedClassMetadataEntriesStartDo
*
* @param[in] vm A javavm
* @param[in] state A walk state struct
*
* @return The next item in the cache corresponding to the limits specified
*/
ShcItem*
shcSharedClassMetadataEntriesNextDo(J9SharedClassMetadataWalkState* state)
{
ShcItemHdr* entry = state->entry;
ShcItem* current = NULL;
ShcItem* walk;
ShcItemHdr* nextEntry = entry;
if (entry == NULL) {
return NULL;
}
do {
UDATA type;
entry = nextEntry;
nextEntry = (ShcItemHdr*)CCITEMNEXT(entry);
if ((UDATA)nextEntry <= (UDATA)state->metaStart) {
if (state->savedEntry != NULL) {
state->metaStart = state->savedMetaStart;
nextEntry = state->savedEntry;
state->savedEntry = NULL;
if ((UDATA)nextEntry <= (UDATA)state->metaStart) {
/* Once we've finished walking the cache, set to NULL */
nextEntry = NULL;
}
} else {
/* Once we've finished walking the cache, set to NULL */
nextEntry = NULL;
}
}
walk = (ShcItem*)CCITEM(entry);
type = J9SHR_READMEM(walk->dataType);
if (type == TYPE_CACHELET) {
CacheletWrapper *cw = (CacheletWrapper*)ITEMDATA(walk);
J9SharedCacheHeader *header = (J9SharedCacheHeader*)CLETDATA(cw);
UDATA totalBytes = J9SHR_READMEM(header->totalBytes);
UDATA updatePtr = (UDATA)header + J9SHR_READMEM(header->updateSRP);
UDATA metadataEnd = (UDATA)header + totalBytes;
/* skip empty cachelets */
if ((metadataEnd - sizeof(ShcItemHdr)) > updatePtr) {
state->savedEntry = nextEntry;
state->metaStart = (void*)updatePtr;
nextEntry = (ShcItemHdr *)(metadataEnd - sizeof(ShcItemHdr));
}
}
if ((!state->limitDataType || (type == state->limitDataType)) &&
(state->includeStale || (!CCITEMSTALE(entry)))
) {
current = walk;
break;
}
} while (nextEntry);
state->entry = nextEntry;
return current;
}
/**
* Walks a cache in or out of process.
* If limitDataType is zero, all entries are returned. To limit to a specific data type, set limitDataType to one of the values in shcdatatypes.h
* If includeStale is zero, stale entries are included in the walk. Otherwise, stale entries are skipped.
*
* Note that in the out-of-process version, the metadata area is dbgMalloc'd by this function.
* This memory is freed when nextDo reaches the end of the metadata area.
*
* Note also that state->reloc returns the difference in bytes between the dbgMalloc'd memory address and the dump address.
* To get the dump address, add state->reloc to any address returned.
* @param[in] vm A javavm
* @param[in] state A walk state struct
* @param[in] limitDataType Non-zero if the data type returned should be limited
* @param[in] includeStale Non-zero if stale classes should be included
*
* @return The first item in the cache corresponding to the limits specified
*/
ShcItem*
shcSharedClassMetadataEntriesStartDo(J9JavaVM* vm, J9SharedClassMetadataWalkState* state, UDATA limitDataType, UDATA includeStale)
{
void* metaStart;
UDATA length;
ShcItemHdr* firstEntry;
if (!(metaStart = shcReadSharedCacheMetadata(vm, &length, &firstEntry))) {
return NULL;
}
state->metaStart = metaStart;
state->savedMetaStart = metaStart;
state->entry = firstEntry;
state->savedEntry = NULL;
state->length = length;
state->limitDataType = (U_16)limitDataType;
state->includeStale = includeStale;
return shcSharedClassMetadataEntriesNextDo(state);
}