1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bugzilla 293480.

This commit is contained in:
Randy Rohrbach 2009-10-27 18:29:04 +00:00
parent 5c8a3a78a4
commit e2a14c751f

View file

@ -297,120 +297,230 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
return false;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long)
*/
public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException {
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long)
*/
@SuppressWarnings("null")
public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException {
if (isUseCacheData() && fBlockAddress.compareTo(address) == 0 && units * getAddressableSize() <= fBlock.length)
return fBlock;
MemoryByte[] newBlock = fetchMemoryBlock(address, units);
int newLength = (newBlock != null) ? newBlock.length : 0;
if (isUseCacheData() && fBlockAddress.compareTo(address) == 0 && units * getAddressableSize() <= fBlock.length)
return fBlock;
MemoryByte[] newBlock = fetchMemoryBlock(address, units);
int newLength = (newBlock != null) ? newBlock.length : 0;
// If the retrieved block overlaps with the cached block, flag the changed bytes
// so they can be properly highlighted in the platform Memory view.
// Note: In the standard Memory view, the values are displayed in cells of 4 bytes
// (on 4-bytes address boundaries) and all 4 bytes have to be flagged so the
// cell is highlighted (and the delta sigh is shown).
if (fBlock != null && newLength > 0) {
switch (fBlockAddress.compareTo(address)) {
// Cached block begins before the retrieved block location
// If there is no overlap, there are no bytes to flag
case -1:
{
// Determine the distance between the cached and the
// requested block addresses
BigInteger bigDistance = address.subtract(fBlockAddress);
// If the retrieved block overlaps with the cached block, flag the changed bytes
// so they can be properly highlighted in the platform Memory view.
// Note: In the standard Memory view, the values are displayed in cells of 4 bytes
// (on 4-bytes address boundaries) and all 4 bytes have to be flagged so the
// cell is highlighted (and the delta sigh is shown).
if (fBlock != null && newLength > 0) {
switch (fBlockAddress.compareTo(address)) {
// Cached block begins before the retrieved block location
//
// <--- fLength -------------------------------------------------->
// +--------------------------------------------------------------+
// | Cached data from previous retrieve |
// | |
// | <------------------ length ----------------------------->|
// | <------------------ newLength --------------------> |
// | +-------------------------------------------------+ |
// | | | |
// | | Newly retrieved data | |
// |<-+->+-------------------------------------------------+ |
// | | address |
// | | |
// | +--- bigDistance/distance |
// | |
// | <------------------ length ----------------------------->|
// | <------------------ newLength -------------------------->|
// | +--------------------------------------------------------+
// | | |
// | | Newly retrieved data |
// |<-+->+--------------------------------------------------------+
// | | address |
// | | |
// | +--- bigDistance/distance |
// | |
// | <------------------ length ----------------------------->|
// | <------------------ newLength ---------------------------------->
// | +---------------------------------------------------------------+
// | | |
// | | Newly retrieved data |
// |<-+->+---------------------------------------------------------------+
// | | address |
// | | |
// | +--- bigDistance/distance |
// | |
// +--------------------------------------------------------------+
// fBlockAddress
case -1:
{
// Determine the distance between the cached and the
// requested block addresses
BigInteger bigDistance = address.subtract(fBlockAddress);
// If the distance does not exceed the length of the cached block,
// then there is some overlap between the blocks and we have to
// mark the changed bytes (if applicable)
if (bigDistance.compareTo(BigInteger.valueOf(fLength)) == -1) {
// Here we can reasonably assume that java integers are OK
int distance = bigDistance.intValue();
int length = fLength - distance;
// If the distance does not exceed the length of the cached block,
// then there is some overlap between the blocks and we have to
// mark the changed bytes (if applicable)
if (bigDistance.compareTo(BigInteger.valueOf(fLength)) == -1) {
// Here we can reasonably assume that java integers are OK
int distance = bigDistance.intValue();
int length = fLength - distance;
if ( length > newLength ) {
length = newLength;
}
// Work by cells of 4 bytes
for (int i = 0; i < length; i += 4) {
// Determine if any byte within the cell was modified
boolean changed = false;
for (int j = i; j < (i + 4) && j < length; j++) {
if ( j < fBlock.length ) {
newBlock[j].setFlags(fBlock[distance + j].getFlags());
if (newBlock[j].getValue() != fBlock[distance + j].getValue())
changed = true;
}
}
// If so, flag the whole cell as modified
if (changed)
for (int j = i; j < (i + 4) && j < length; j++) {
newBlock[j].setHistoryKnown(true);
newBlock[j].setChanged(true);
}
}
}
break;
}
// Work by cells of 4 bytes
for (int i = 0; i < length && i + 4 < newLength; i += 4) {
// Determine if any byte within the cell was modified
boolean changed = false;
for (int j = i; j < (i + 4) && j < length; j++) {
if ( j < newLength ) {
newBlock[j].setFlags(fBlock[distance + j].getFlags());
if (newBlock[j].getValue() != fBlock[distance + j].getValue()) {
changed = true;
}
}
}
// If so, flag the whole cell as modified
if (changed) {
for (int j = i; j < (i + 4) && j < length; j++) {
if ( j < newLength ) {
newBlock[j].setHistoryKnown(true);
newBlock[j].setChanged(true);
}
}
}
}
}
break;
}
// Cached block begins before the retrieved block location
// If there is no overlap, there are no bytes to flag
// (this block of code is symmetric with the previous one)
case 0:
case 1:
{
// Determine the distance between the cached and the
// requested block addresses
BigInteger bigDistance = fBlockAddress.subtract(address);
// The cached block starts at the same address as the retrieved data
// or it starts after the retrieved block and the retrieved block runs
// in to it.
//
// Case 0:
//
// <--- fLength -------------------------------------------------->
// +--------------------------------------------------------------+
// | Cached data from previous retrieve |
// | |
// |<-- length ----------------> |
// |<-- newLength -------------> |
// +---------------------------+ |
// | | |
// | Newly retrieve data | |
// +---------------------------+ |
// |address |
// | |
// |<--------------------- length ------------------------------->|
// |<--------------------- newLength ---------------------------->|
// +--------------------------------------------------------------+
// | |
// | Newly retrieve data |
// +--------------------------------------------------------------+
// |address |
// | |
// +--------------------------------------------------------------+
// fBlockAddress
// bigDistance/distance = 0
//
// Case 1:
// <--- fLength -------------------------------------------------->
// +--------------------------------------------------------------+
// | Cached data from previous retrieve |
// | |
// |<-- length -----> |
// <-- newLength ----------> |
// +-----------------------+ |
// | | |
// | Newly retrieved data | |
// +-----------------------+ |
// address| |
// | |
// |<----------------------- length ----------------------------->|
// <------------------------------- newLength -------------------------->|
// +---------------------------------------------------------------------+
// | |
// | Newly retrieved data |
// +---------------------------------------------------------------------+
// address| |
// | |
// |<----------------------- length ----------------------------->|
// <------------------------------- newLength --------------------------------->
// +---------------------------------------------------------------------------+
// | |
// | Newly retrieved data |
// +---------------------------------------------------------------------------+
// address| |
// <--+-->| |
// | +--------------------------------------------------------------+
// | fBlockAddress
// +---bigDistance/distance
case 0:
case 1:
{
// Determine the distance between the cached and the
// requested block addresses
BigInteger bigDistance = fBlockAddress.subtract(address);
// If the distance does not exceed the length of the new block,
// then there is some overlap between the blocks and we have to
// mark the changed bytes (if applicable)
if (bigDistance.compareTo(BigInteger.valueOf(newLength)) == -1) {
// Here we can reasonably assume that java integers are OK
int distance = bigDistance.intValue();
int length = newLength - distance;
// Work by cells of 4 bytes
for (int i = 0; i < length; i += 4) {
// Determine if any byte within the cell was modified
boolean changed = false;
for (int j = i; j < (i + 4) && j < length; j++) {
if ( j < fBlock.length ) {
newBlock[distance + j].setFlags(fBlock[j].getFlags());
if (newBlock[distance + j].getValue() != fBlock[j].getValue())
changed = true;
}
}
// If so, flag the whole cell as modified
if (changed)
for (int j = i; j < (i + 4) && j < length; j++) {
newBlock[distance + j].setHistoryKnown(true);
newBlock[distance + j].setChanged(true);
}
}
}
break;
}
// If the distance does not exceed the length of the new block,
// then there is some overlap between the blocks and we have to
// mark the changed bytes (if applicable)
if (bigDistance.compareTo(BigInteger.valueOf(newLength)) == -1) {
// Here we can reasonably assume that java integers are OK
int distance = bigDistance.intValue();
int length = newLength - distance;
if ( length > fBlock.length ) {
length = fBlock.length;
}
// Work by cells of 4 bytes
for (int i = 0; i < length && distance + i + 4 < newLength; i += 4) {
// Determine if any byte within the cell was modified
boolean changed = false;
for (int j = i; j < (i + 4) && j < length; j++) {
if ( ( distance + j ) < newLength ) {
newBlock[distance + j].setFlags(fBlock[j].getFlags());
if (newBlock[distance + j].getValue() != fBlock[j].getValue()) {
changed = true;
}
}
}
// If so, flag the whole cell as modified
if (changed) {
for (int j = i; j < (i + 4) && j < length; j++) {
if ( ( distance + j ) < newLength ) {
newBlock[distance + j].setHistoryKnown(true);
newBlock[distance + j].setChanged(true);
}
}
}
}
}
break;
}
default:
break;
}
}
default:
break;
}
}
// Update the internal state
fBlock = newBlock;
fBlockAddress = address;
fLength = newLength;
if (fUpdatePolicy.equals(DsfMemoryBlock.UPDATE_POLICY_BREAKPOINT))
fUseCachedData = true;
else if (fUpdatePolicy.equals(DsfMemoryBlock.UPDATE_POLICY_MANUAL))
fUseCachedData = true;
// Update the internal state
fBlock = newBlock;
fBlockAddress = address;
fLength = newLength;
if (fUpdatePolicy.equals(DsfMemoryBlock.UPDATE_POLICY_BREAKPOINT))
fUseCachedData = true;
else if (fUpdatePolicy.equals(DsfMemoryBlock.UPDATE_POLICY_MANUAL))
fUseCachedData = true;
return fBlock;
}
return fBlock;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#setValue(java.math.BigInteger, byte[])
@ -522,7 +632,6 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
else {
drm.done();
}
}
};
fRetrieval.getExecutor().execute(query);
@ -530,13 +639,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
try {
return query.get();
} catch (InterruptedException e) {
throw new DebugException(new Status(IStatus.ERROR,
DsfPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
"Error reading memory block (InterruptedException)", e)); //$NON-NLS-1$
throw new DebugException(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Error reading memory block (InterruptedException)", e)); //$NON-NLS-1$
} catch (ExecutionException e) {
throw new DebugException(new Status(IStatus.ERROR,
DsfPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
"Error reading memory block (ExecutionException)", e)); //$NON-NLS-1$
throw new DebugException(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Error reading memory block (ExecutionException)", e)); //$NON-NLS-1$
}
}