[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [dsdp-dd-dev] Memory service questions
|
Francois Chouinard wrote:
Exact. Each time a memory monitor is created (by the user), the debug
platform instantiates a corresponding IMemoryBlockExtension via a call
to IMemoryBlockRetrieval.getExtendedMemoryBlock(). For DSF, these
interfaces are implemented by DsfMemoryBlockRetrieval and DsfMemoryBlock
respectively.
Following that, each time an update is requested, the UI makes a call to
IMemoryBlockExtension.getBytesFromAddress(). In our case, depending on
the requested block "location" (address and size) with respect to the
cached block, and on the update policy (through
IMemoryBlockUpdatePolicyProvider), we determine if the cached block (or
parts of it) can be re-used and if a trip to the memory service is
needed (IMemory.getMemory()).
If so (getMemory() was called), the retrieved block is compared with the
cached block to flag the changed MemoryBytes so the UI can highlight
them in the corresponding monitor.
The memory service itself should issue its requests through a
CommandCache which handles the duplicates quite nicely and limits the
number of trips to the back-end.
Even if I ignore multiple identical requests, I still get OutOfMemory
issues when I scroll alot, so even with a CommandCache I would have
problems.
The issue here is that I get alot of *identical* getMemory()
requests (same address, same range, same wordsize, etc.). If I start
scrolling, the service is sometimes flooded with calls until I get a
OutOfMemory error.
Each of these getMemory() requests is ultimately triggered by the UI and
should be factorized by the CommandCache. The UI will request a memory
read upon receiving a DebugEvent (DebugEvent.CHANGE,
DebugEvent.CONTENT). By any chance, does your service issue such events
liberally? That could explain the flood of identical requests.
My memory service doesn't issue any debug-events at all at this time.
The HISTORY_KNOWN flag simply means that the CHANGED flag is meaningful
(my english is lousy, I know...). In getBytesFromAddress(),
DsfMemoryBlock compares the cached block with the newly retrieved one
and flags the changed bytes. It also sets the HISTORY_KNOWN flag so the
UI will correctly hightlight the changes (and put the little delta
decorator too).
Does that mean that the memory service itself does not (and should not)
set the HISTORY_KNOWN and CHANGED flags?
As Pawel mentionned, we elected to use a MemoryByte[] to represent our
memory blocks. And each MemoryByte comes with its personalized set of
flags :-) At first glance this might look inefficient, but this is what
the UI expects (see IMemoryBlockExtension).
Not much to do then. Ideally I would like to be able to pass a primitive
array (byte[]/short[]/int[],long[]), but I don't think this will really
be an issue.
For the "word size", my understanding is that it corresponds to the size
of the smallest addressable item, usually the byte (but, like a few
other parameters, this should really be a launch configuration parameter).
That's not how I interpret it. If you have memory where the program has
written 32-bit integers, and you tell the view to display 4-byte units,
I expect the integers to come out correct. I.e. if I have this program
uint32_t x = 0x11223344;
and display the location &x to be viewed as 4-byte units, I want the
memory view to display
11223344
and not
44332211
Endianness is not (IMHO, I should add) a property of a single byte or a
byte stream, it is a way to interpret a fixed sequence of bytes read
from memory. How should 4 sequential bytes read from memory be converted
into a 32-bit int?
Anyway, I'll have more reason to revisit the endianness issue further
down the line. It is not a critical issue at the moment.
Anyway, to keep things simple, I found it is easier to provide an array
of bytes then let the Memory View handle the formatting (ASCII, Integer,
char, ...). I suggest that you adopt a similar approach and that you
provide a specific memory renderer for your more exotic rendering needs.
Of course, I might very well have overseen some critical aspect and, if
you have one, I would very much like to have an example where this
doesn't work.
My understanding of the endianness flag (another launch configuration
parameter candidate) is really for the renderer to know how to handle
the raw byte array.
I'll dig a little deeper into the flooding getMemory() calls and see
what I can find.
--
/Jesper