mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-12 11:35:21 +02:00
[248636] Changes to the memory cache to allow to keep it private.
This commit is contained in:
parent
a9b0d0a49a
commit
c2468b0c14
2 changed files with 139 additions and 163 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Ericsson and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Ericsson - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
package org.eclipse.dd.gdb.internal.provisional.service;
|
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
@ -34,8 +44,6 @@ public class GDBMemory_7_0 extends MIMemory {
|
||||||
register(new String[] { MIMemory.class.getName(), IMemory.class.getName(), GDBMemory_7_0.class.getName()},
|
register(new String[] { MIMemory.class.getName(), IMemory.class.getName(), GDBMemory_7_0.class.getName()},
|
||||||
new Hashtable<String, String>());
|
new Hashtable<String, String>());
|
||||||
|
|
||||||
setMemoryCache(new GDBMemoryCache());
|
|
||||||
|
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,59 +53,47 @@ public class GDBMemory_7_0 extends MIMemory {
|
||||||
super.shutdown(requestMonitor);
|
super.shutdown(requestMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class GDBMemoryCache extends MIMemoryCache {
|
@Override
|
||||||
@Override
|
protected void readMemoryBlock(IDMContext dmc, IAddress address, long offset,
|
||||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
int word_size, int count, DataRequestMonitor<MemoryByte[]> drm)
|
||||||
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
{
|
||||||
{
|
IDMContext threadOrMemoryDmc = dmc;
|
||||||
IDMContext threadOrMemoryDmc = dmc;
|
|
||||||
|
|
||||||
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
||||||
if(containerCtx != null) {
|
if(containerCtx != null) {
|
||||||
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
|
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
|
||||||
|
|
||||||
if (procService != null) {
|
if (procService != null) {
|
||||||
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
|
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
|
||||||
// Return any thread... let's take the first one.
|
// Return any thread... let's take the first one.
|
||||||
if (execCtxs != null && execCtxs.length > 0) {
|
if (execCtxs != null && execCtxs.length > 0) {
|
||||||
threadOrMemoryDmc = execCtxs[0];
|
threadOrMemoryDmc = execCtxs[0];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, drm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, drm);
|
||||||
* @param memoryDMC
|
|
||||||
* @param address
|
|
||||||
* @param offset
|
|
||||||
* @param word_size
|
|
||||||
* @param count
|
|
||||||
* @param buffer
|
|
||||||
* @param rm
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
|
||||||
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
|
|
||||||
{
|
|
||||||
IDMContext threadOrMemoryDmc = dmc;
|
|
||||||
|
|
||||||
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
|
||||||
if(containerCtx != null) {
|
|
||||||
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
|
|
||||||
|
|
||||||
if (procService != null) {
|
|
||||||
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
|
|
||||||
// Return any thread... let's take the first one.
|
|
||||||
if (execCtxs != null && execCtxs.length > 0) {
|
|
||||||
threadOrMemoryDmc = execCtxs[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, buffer, rm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeMemoryBlock(IDMContext dmc, IAddress address, long offset,
|
||||||
|
int word_size, int count, byte[] buffer, RequestMonitor rm)
|
||||||
|
{
|
||||||
|
IDMContext threadOrMemoryDmc = dmc;
|
||||||
|
|
||||||
|
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
||||||
|
if(containerCtx != null) {
|
||||||
|
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
|
||||||
|
|
||||||
|
if (procService != null) {
|
||||||
|
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
|
||||||
|
// Return any thread... let's take the first one.
|
||||||
|
if (execCtxs != null && execCtxs.length > 0) {
|
||||||
|
threadOrMemoryDmc = execCtxs[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, buffer, rm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,9 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Back-end commands cache
|
||||||
|
private CommandCache fCommandCache;
|
||||||
|
// Local memory cache
|
||||||
private MIMemoryCache fMemoryCache;
|
private MIMemoryCache fMemoryCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,12 +114,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @param requestMonitor
|
* @param requestMonitor
|
||||||
*/
|
*/
|
||||||
private void doInitialize(final RequestMonitor requestMonitor) {
|
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||||
|
// Create the command cache
|
||||||
|
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
|
||||||
|
fCommandCache = new CommandCache(getSession(), commandControl);
|
||||||
|
fCommandCache.setContextAvailable(commandControl.getContext(), true);
|
||||||
|
|
||||||
// Register this service
|
// Register this service
|
||||||
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
|
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
|
||||||
|
|
||||||
// Create the memory requests cache
|
// Create the memory requests cache
|
||||||
setMemoryCache(new MIMemoryCache());
|
fMemoryCache = new MIMemoryCache();
|
||||||
|
|
||||||
// Register as service event listener
|
// Register as service event listener
|
||||||
getSession().addServiceEventListener(this, null);
|
getSession().addServiceEventListener(this, null);
|
||||||
|
@ -149,15 +156,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
return MIPlugin.getBundleContext();
|
return MIPlugin.getBundleContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method resets the memory cache. It allows an overriding class to provide
|
|
||||||
* its own overridden memory cache class.
|
|
||||||
*
|
|
||||||
* @since 1.1
|
|
||||||
*/
|
|
||||||
protected void setMemoryCache(MIMemoryCache cache) { fMemoryCache = cache; }
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// IMemory
|
// IMemory
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -279,6 +277,86 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
fMemoryCache.setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm);
|
fMemoryCache.setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Back-end functions
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param memoryDMC
|
||||||
|
* @param address
|
||||||
|
* @param offset
|
||||||
|
* @param word_size
|
||||||
|
* @param count
|
||||||
|
* @param drm
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
*/
|
||||||
|
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
||||||
|
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||||
|
{
|
||||||
|
/* To simplify the parsing of the MI result, we request the output to
|
||||||
|
* be on 1 row of [count] columns, no char interpretation.
|
||||||
|
*/
|
||||||
|
int mode = MIFormat.HEXADECIMAL;
|
||||||
|
int nb_rows = 1;
|
||||||
|
int nb_cols = count;
|
||||||
|
Character asChar = null;
|
||||||
|
|
||||||
|
fCommandCache.execute(
|
||||||
|
new MIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
|
||||||
|
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
// Retrieve the memory block
|
||||||
|
drm.setData(getData().getMIMemoryBlock());
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void handleFailure() {
|
||||||
|
// Bug234289: If memory read fails, return a block marked as invalid
|
||||||
|
MemoryByte[] block = new MemoryByte[word_size * count];
|
||||||
|
for (int i = 0; i < block.length; i++)
|
||||||
|
block[i] = new MemoryByte((byte) 0, (byte) 0);
|
||||||
|
drm.setData(block);
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param memoryDMC
|
||||||
|
* @param address
|
||||||
|
* @param offset
|
||||||
|
* @param word_size
|
||||||
|
* @param count
|
||||||
|
* @param buffer
|
||||||
|
* @param rm
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
*/
|
||||||
|
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
||||||
|
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
|
||||||
|
{
|
||||||
|
// Each byte is written individually (GDB power...)
|
||||||
|
// so we need to keep track of the count
|
||||||
|
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
|
||||||
|
countingRM.setDoneCount(count);
|
||||||
|
|
||||||
|
// We will format the individual bytes in decimal
|
||||||
|
int format = MIFormat.DECIMAL;
|
||||||
|
String baseAddress = address.toString();
|
||||||
|
|
||||||
|
// Issue an MI request for each byte to write
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
String value = new Byte(buffer[i]).toString();
|
||||||
|
fCommandCache.execute(
|
||||||
|
new MIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
|
||||||
|
new DataRequestMonitor<MIDataWriteMemoryInfo>(getExecutor(), countingRM)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Event handlers
|
// Event handlers
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -290,10 +368,11 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(IResumedDMEvent e) {
|
public void eventDispatched(IResumedDMEvent e) {
|
||||||
if (e instanceof IContainerResumedDMEvent) {
|
if (e instanceof IContainerResumedDMEvent) {
|
||||||
fMemoryCache.setTargetAvailable(e.getDMContext(), false);
|
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.getReason() != StateChangeReason.STEP) {
|
if (e.getReason() != StateChangeReason.STEP) {
|
||||||
|
fCommandCache.reset();
|
||||||
fMemoryCache.reset();
|
fMemoryCache.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,8 +384,9 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(ISuspendedDMEvent e) {
|
public void eventDispatched(ISuspendedDMEvent e) {
|
||||||
if (e instanceof IContainerSuspendedDMEvent) {
|
if (e instanceof IContainerSuspendedDMEvent) {
|
||||||
fMemoryCache.setTargetAvailable(e.getDMContext(), true);
|
fCommandCache.setContextAvailable(e.getDMContext(), true);
|
||||||
}
|
}
|
||||||
|
fCommandCache.reset();
|
||||||
fMemoryCache.reset();
|
fMemoryCache.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,44 +529,20 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
// MIMemoryCache
|
// MIMemoryCache
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
private class MIMemoryCache {
|
||||||
* This class can now be overridden.
|
|
||||||
*
|
|
||||||
* @since 1.1
|
|
||||||
*/
|
|
||||||
protected class MIMemoryCache {
|
|
||||||
|
|
||||||
// Back-end commands cache
|
|
||||||
private CommandCache fCommandCache;
|
|
||||||
|
|
||||||
// The memory cache data structure
|
// The memory cache data structure
|
||||||
private SortedMemoryBlockList fMemoryBlockList;
|
private SortedMemoryBlockList fMemoryBlockList;
|
||||||
|
|
||||||
public MIMemoryCache() {
|
public MIMemoryCache() {
|
||||||
// Create the command cache
|
|
||||||
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
|
|
||||||
fCommandCache = new CommandCache(getSession(), commandControl);
|
|
||||||
fCommandCache.setContextAvailable(commandControl.getContext(), true);
|
|
||||||
|
|
||||||
// Create the memory block cache
|
// Create the memory block cache
|
||||||
fMemoryBlockList = new SortedMemoryBlockList();
|
fMemoryBlockList = new SortedMemoryBlockList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
// Clear the command cache
|
|
||||||
fCommandCache.reset();
|
|
||||||
// Clear the memory cache
|
// Clear the memory cache
|
||||||
fMemoryBlockList.clear();
|
fMemoryBlockList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTargetAvailable(IDMContext dmc, boolean isAvailable) {
|
|
||||||
fCommandCache.setContextAvailable(dmc, isAvailable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTargetAvailable(IDMContext dmc) {
|
|
||||||
return fCommandCache.isTargetAvailable(dmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function walks the address-sorted memory block list to identify
|
* This function walks the address-sorted memory block list to identify
|
||||||
* the 'missing' blocks (i.e. the holes) that need to be fetched on the target.
|
* the 'missing' blocks (i.e. the holes) that need to be fetched on the target.
|
||||||
|
@ -849,83 +905,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// Back-end functions
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param memoryDMC
|
|
||||||
* @param address
|
|
||||||
* @param offset
|
|
||||||
* @param word_size
|
|
||||||
* @param count
|
|
||||||
* @param drm
|
|
||||||
*/
|
|
||||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
|
||||||
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
|
||||||
{
|
|
||||||
/* To simplify the parsing of the MI result, we request the output to
|
|
||||||
* be on 1 row of [count] columns, no char interpretation.
|
|
||||||
*/
|
|
||||||
int mode = MIFormat.HEXADECIMAL;
|
|
||||||
int nb_rows = 1;
|
|
||||||
int nb_cols = count;
|
|
||||||
Character asChar = null;
|
|
||||||
|
|
||||||
fCommandCache.execute(
|
|
||||||
new MIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
|
|
||||||
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
|
|
||||||
@Override
|
|
||||||
protected void handleSuccess() {
|
|
||||||
// Retrieve the memory block
|
|
||||||
drm.setData(getData().getMIMemoryBlock());
|
|
||||||
drm.done();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void handleFailure() {
|
|
||||||
// Bug234289: If memory read fails, return a block marked as invalid
|
|
||||||
MemoryByte[] block = new MemoryByte[word_size * count];
|
|
||||||
for (int i = 0; i < block.length; i++)
|
|
||||||
block[i] = new MemoryByte((byte) 0, (byte) 0);
|
|
||||||
drm.setData(block);
|
|
||||||
drm.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param memoryDMC
|
|
||||||
* @param address
|
|
||||||
* @param offset
|
|
||||||
* @param word_size
|
|
||||||
* @param count
|
|
||||||
* @param buffer
|
|
||||||
* @param rm
|
|
||||||
*/
|
|
||||||
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
|
||||||
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
|
|
||||||
{
|
|
||||||
// Each byte is written individually (GDB power...)
|
|
||||||
// so we need to keep track of the count
|
|
||||||
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
|
|
||||||
countingRM.setDoneCount(count);
|
|
||||||
|
|
||||||
// We will format the individual bytes in decimal
|
|
||||||
int format = MIFormat.DECIMAL;
|
|
||||||
String baseAddress = address.toString();
|
|
||||||
|
|
||||||
// Issue an MI request for each byte to write
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String value = new Byte(buffer[i]).toString();
|
|
||||||
fCommandCache.execute(
|
|
||||||
new MIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
|
|
||||||
new DataRequestMonitor<MIDataWriteMemoryInfo>(getExecutor(), countingRM)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -933,6 +912,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
public void flushCache(IDMContext context) {
|
public void flushCache(IDMContext context) {
|
||||||
|
fCommandCache.reset();
|
||||||
fMemoryCache.reset();
|
fMemoryCache.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue