38
38
public abstract class CommonAddressSpace implements IAbstractAddressSpace {
39
39
private static final int BUFFER_MAX = 4096 ;
40
40
private static final int MEMORY_CHECK_THRESHOLD = 0x100000 ;
41
-
41
+
42
42
private MemoryRange [] _translations ;
43
43
private Integer _lastTranslationUsed = Integer .valueOf (0 );
44
44
private boolean _isLittleEndian ;
45
45
private boolean _is64Bit ;
46
46
private int lastAsid ;
47
47
private int _is64BitAsid [];
48
-
48
+
49
49
protected CommonAddressSpace (MemoryRange [] translations , boolean isLittleEndian , boolean is64Bit )
50
50
{
51
51
_translations = _sortRanges (translations );
52
52
_isLittleEndian = isLittleEndian ;
53
53
_is64Bit = is64Bit ;
54
54
set64Bitness ();
55
55
}
56
-
56
+
57
57
private static MemoryRange [] _sortRanges (MemoryRange [] ranges )
58
58
{
59
59
Arrays .sort (ranges , new Comparator <MemoryRange >() {
60
60
@ Override
61
61
public int compare (MemoryRange one , MemoryRange two )
62
62
{
63
- return compareAddress (one .getAsid (), one .getVirtualAddress (), two .getAsid (), two .getVirtualAddress ());
63
+ return compareAddress (one .getAsid (), one .getVirtualAddress (), two .getAsid (), two .getVirtualAddress ());
64
64
}
65
65
});
66
66
return ranges ;
@@ -78,17 +78,17 @@ private void set64Bitness() {
78
78
if (_translations [i ].getVirtualAddress ()+_translations [i ].getSize () >= 0x100000000L ) {
79
79
// Found 64-bit entry
80
80
int asid = _translations [i ].getAsid ();
81
-
81
+
82
82
// Remember the ASID
83
83
int newa [] = new int [count +1 ];
84
84
for (int j = 0 ; j < count ; ++j ) {
85
85
newa [j ] = _is64BitAsid [j ];
86
86
}
87
87
newa [count ] = asid ;
88
88
_is64BitAsid = newa ;
89
-
89
+
90
90
++count ;
91
-
91
+
92
92
// Skip to the end of the ASID range
93
93
while (i < _translations .length && _translations [i ].getAsid () == asid ) ++i ;
94
94
}
@@ -106,59 +106,59 @@ public Iterator getMemoryRanges()
106
106
protected MemoryRange _residentRange (int asid , long address ) throws MemoryAccessException
107
107
{
108
108
int range = findWhichMemoryRange (asid , address , _translations , _lastTranslationUsed , true );
109
-
109
+
110
110
if (range >= 0 ) {
111
111
return _translations [range ];
112
112
} else {
113
113
throw new MemoryAccessException (asid , address );
114
114
}
115
115
}
116
-
116
+
117
117
/**
118
- *
118
+ *
119
119
* This searches memory ranges for an addr using a binary chop and returns an int indicating the memory range
120
- * or -1 if address is not within any memory range......
120
+ * or -1 if address is not within any memory range......
121
121
* @param asid TODO
122
122
*/
123
123
protected static int findWhichMemoryRange (int asid , long addr , MemoryRange [] ranges , Integer lastRange , boolean doLinearIfNotFound )
124
124
{
125
125
int retI =-1 ; //assume we won't find it
126
126
int last = lastRange .intValue ();
127
127
int lastPlusOne = last +1 ;
128
-
129
- if ((last < ranges .length ) &&
130
- (ranges [last ].contains (asid , addr )) &&
128
+
129
+ if ((last < ranges .length ) &&
130
+ (ranges [last ].contains (asid , addr )) &&
131
131
(ranges [last ].isInCoreFile () || (!ranges [last ].isInCoreFile () && ranges [last ].getLibraryReader () != null ))) { //TLB hit
132
132
retI = last ;
133
- } else if ((lastPlusOne < ranges .length ) &&
134
- (ranges [lastPlusOne ].contains (asid , addr )) &&
133
+ } else if ((lastPlusOne < ranges .length ) &&
134
+ (ranges [lastPlusOne ].contains (asid , addr )) &&
135
135
(ranges [last ].isInCoreFile () || (!ranges [last ].isInCoreFile () && ranges [last ].getLibraryReader () != null ))) { //TLB hit
136
136
retI = lastPlusOne ;
137
137
} else {
138
138
// TLB failed to do the search
139
-
139
+
140
140
// Now effectively do a binary search find the right range....
141
141
// note: on some platforms we can have overlapping memory ranges!!
142
142
// (ie. AIX, zOs and linux) so we always give back the first
143
143
144
144
int highpos = ranges .length -1 ;
145
145
int lowpos = 0 ;
146
-
146
+
147
147
while (lowpos <= highpos ) {
148
148
int currentPos = lowpos + ((highpos -lowpos ) >>> 1 );
149
149
long mraStartAddr = ranges [currentPos ].getVirtualAddress ();
150
150
int mraAsid = ranges [currentPos ].getAsid ();
151
151
152
152
if (compareAddress (asid , addr , mraAsid , mraStartAddr ) >= 0 ) { //addr above base of range
153
- if (compareAddress (asid , addr , mraAsid , mraStartAddr + ranges [currentPos ].getSize ()) < 0 &&
153
+ if (compareAddress (asid , addr , mraAsid , mraStartAddr + ranges [currentPos ].getSize ()) < 0 &&
154
154
(ranges [currentPos ].isInCoreFile () || !ranges [currentPos ].isInCoreFile () && ranges [currentPos ].getLibraryReader () != null )) {
155
155
retI = currentPos ;
156
156
break ;
157
157
}
158
158
lowpos = currentPos + 1 ;
159
159
} else {
160
160
highpos = currentPos -1 ;
161
- }
161
+ }
162
162
}
163
163
164
164
// No match using binary chop, probably due to overlapping ranges => revert to a linear search
@@ -168,8 +168,8 @@ protected static int findWhichMemoryRange(int asid, long addr, MemoryRange[] ran
168
168
for (int i = 0 ; i < lowpos ; i ++) {
169
169
long mraStartAddr = ranges [i ].getVirtualAddress ();
170
170
int mraAsid = ranges [i ].getAsid ();
171
- if ((compareAddress (asid , addr , mraAsid , mraStartAddr ) >= 0 ) &&
172
- (compareAddress (asid , addr , mraAsid , mraStartAddr + ranges [i ].getSize ()) < 0 ) &&
171
+ if ((compareAddress (asid , addr , mraAsid , mraStartAddr ) >= 0 ) &&
172
+ (compareAddress (asid , addr , mraAsid , mraStartAddr + ranges [i ].getSize ()) < 0 ) &&
173
173
(ranges [i ].isInCoreFile () || (!ranges [i ].isInCoreFile () && ranges [i ].getLibraryReader () != null ))) {
174
174
retI = i ;
175
175
break ;
@@ -182,7 +182,7 @@ protected static int findWhichMemoryRange(int asid, long addr, MemoryRange[] ran
182
182
}
183
183
return retI ;
184
184
}
185
-
185
+
186
186
protected static int compareAddress (int lasid , long lhs , int rasid , long rhs ) {
187
187
if (lasid < rasid ) return -1 ;
188
188
if (lasid > rasid ) return 1 ;
@@ -194,7 +194,7 @@ protected static int compareAddress(int lasid, long lhs, int rasid, long rhs) {
194
194
return lhs < rhs ? 1 : -1 ;
195
195
}
196
196
}
197
-
197
+
198
198
private boolean isMemoryAccessible (int asid , long address , int size )
199
199
{
200
200
// CMVC 125071 - jextract failing with OOM error
@@ -205,13 +205,13 @@ private boolean isMemoryAccessible(int asid, long address, int size)
205
205
int startRange ;
206
206
long hi ;
207
207
long memhi ;
208
-
208
+
209
209
startRange = findWhichMemoryRange (asid , address , _translations , _lastTranslationUsed , true );
210
210
if (startRange == -1 ) {
211
211
// Range not found, so return false
212
212
return rc ;
213
213
}
214
-
214
+
215
215
// Now we have a start range, check if the size fits
216
216
hi = _translations [startRange ].getVirtualAddress () + _translations [startRange ].getSize ();
217
217
memhi = address + size ;
@@ -222,12 +222,12 @@ private boolean isMemoryAccessible(int asid, long address, int size)
222
222
// size goes beyond the end of this range, so walk the contiguous
223
223
// ranges to find if it will still fit
224
224
cumulativeSize = hi - address ;
225
-
225
+
226
226
for (int i = startRange +1 ; i < _translations .length ; i ++) {
227
227
long rangeBaseAddress = _translations [i ].getVirtualAddress ();
228
228
long rangeSize = _translations [i ].getSize ();
229
229
long rangeTopAddress = rangeBaseAddress + rangeSize ;
230
-
230
+
231
231
if (rangeBaseAddress == hi ) {
232
232
// contiguous range
233
233
cumulativeSize += rangeSize ;
@@ -279,23 +279,23 @@ public byte[] getMemoryBytes(int asid, long vaddr, int size)
279
279
{
280
280
// CMVC 125071 - jextract failing with OOM error
281
281
// This check is to help protect from OOM situations where a damaged core
282
- // has given us a ridiculously large memory size to allocate. If size is
282
+ // has given us a ridiculously large memory size to allocate. If size is
283
283
// sufficiently large, then check if the memory really exists before trying
284
284
// to allocate it. Obviously, this does not stop OOM occurring, if the memory
285
285
// exists in the core file we may pass the test and still OOM on the allocation.
286
286
boolean getMem = true ;
287
287
lastAsid = asid ;
288
288
byte [] buffer = null ;
289
-
289
+
290
290
if (size < 0 ) {
291
291
return null ;
292
292
}
293
-
293
+
294
294
if (0 != vaddr ) {
295
295
if (size > MEMORY_CHECK_THRESHOLD ) {
296
296
getMem = isMemoryAccessible (0 , vaddr , size );
297
297
}
298
-
298
+
299
299
if (getMem ) {
300
300
buffer = new byte [size ];
301
301
@@ -321,7 +321,7 @@ else if (0 != bufferMax % align)
321
321
322
322
long location = -1 ;
323
323
Iterator ranges = getMemoryRanges ();
324
-
324
+
325
325
while ((-1 == location ) && ranges .hasNext ()) {
326
326
MemoryRange range = (MemoryRange ) ranges .next ();
327
327
// Skip over previous asids
@@ -334,15 +334,15 @@ else if (0 != bufferMax % align)
334
334
if (location == -1 ) lastAsid = 0 ;
335
335
return location ;
336
336
}
337
-
337
+
338
338
private static int match (byte [] whatBytes , int matchedSoFar , byte [] buffer , int index ) {
339
339
int matched = matchedSoFar ;
340
340
for (int i = index ; i < buffer .length && matched < whatBytes .length ; i ++, matched ++)
341
341
if (buffer [i ] != whatBytes [matched ])
342
342
return 0 ;
343
343
return matched ;
344
344
}
345
-
345
+
346
346
private long findPatternInRange (byte [] whatBytes , int alignment , long start , MemoryRange range , int bufferMax ) {
347
347
if (range .getVirtualAddress () >= start || range .contains (start )) {
348
348
// Ensure the address is within the range and aligned
@@ -353,7 +353,7 @@ private long findPatternInRange(byte[] whatBytes, int alignment, long start, Mem
353
353
addr += alignment - (addr % alignment );
354
354
355
355
long edge = range .getVirtualAddress () + range .getSize ();
356
-
356
+
357
357
int asid = range .getAsid ();
358
358
359
359
// FIXME this is somewhat inefficient - should use Boyer-Moore
@@ -362,22 +362,22 @@ private long findPatternInRange(byte[] whatBytes, int alignment, long start, Mem
362
362
while (addr < edge ) {
363
363
long bytesLeftInRange = edge - addr ;
364
364
long count = bufferMax < bytesLeftInRange ? bufferMax : bytesLeftInRange ;
365
-
365
+
366
366
if (0 != addr ) {
367
367
byte [] buffer = getMemoryBytes (asid , addr , (int )count );
368
-
368
+
369
369
if (null != buffer ) {
370
370
// Handle partial match
371
371
if (0 != matched ) {
372
372
matched = match (whatBytes , matched , buffer , 0 );
373
373
}
374
-
374
+
375
375
// Handle no match
376
376
for (int i = 0 ; i < buffer .length && 0 == matched ; i += alignment ) {
377
377
matchAddr = addr + i ;
378
378
matched = match (whatBytes , 0 , buffer , i );
379
379
}
380
-
380
+
381
381
// Check for a full match
382
382
if (whatBytes .length == matched ) {
383
383
return matchAddr ;
@@ -392,7 +392,7 @@ private long findPatternInRange(byte[] whatBytes, int alignment, long start, Mem
392
392
}
393
393
return -1 ;
394
394
}
395
-
395
+
396
396
/* (non-Javadoc)
397
397
* @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getLongAt(int, long)
398
398
*/
0 commit comments