Based on feedback from Nick Nethercote.
* DHAT:
- A new kind of user request has been added which allows you to
override the 1024 byte limit on access count histograms for blocks
- of memories. Two client requests are available,
- DHAT_HISTOGRAM_MEMORY_UNINIT and DHAT_HISTOGRAM_MEMORY_INIT.
+ of memory. The client request is DHAT_HISTOGRAM_MEMORY.
* ==================== FIXED BUGS ====================
case VG_USERREQ__DHAT_HISTOGRAM_MEMORY: {
Addr address = (Addr)arg[1];
- UWord initial_count = arg[2];
Block* bk = find_Block_containing( address );
// bogus address
return False;
}
- // already histogrammed
+ // too big
if (bk->req_szB > USER_HISTOGRAM_SIZE_LIMIT) {
VG_(message)(
Vg_UserMsg,
bk->histoW = VG_(malloc)("dh.new_block.3", bk->req_szB * sizeof(UShort));
- if (initial_count == 0U) {
- VG_(memset)(bk->histoW, 0, bk->req_szB * sizeof(UShort));
- } else {
- for (SizeT i = 0U; i < bk->req_szB; ++i) {
- bk->histoW[i] = 1U;
- }
- }
+ VG_(memset)(bk->histoW, 0, bk->req_szB * sizeof(UShort));
+
return True;
}
enum {
VG_USERREQ__DHAT_AD_HOC_EVENT = VG_USERREQ_TOOL_BASE('D', 'H'),
VG_USERREQ__DHAT_HISTOGRAM_MEMORY,
- VG_USERREQ__DHAT_HISTOGRAM_ARRAY,
// This is just for DHAT's internal use. Don't use it.
_VG_USERREQ__DHAT_COPY = VG_USERREQ_TOOL_BASE('D','H') + 256
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DHAT_AD_HOC_EVENT, \
(_qzz_weight), 0, 0, 0, 0)
-// for limited histograms of memory larger than 1k
-#define DHAT_HISTOGRAM_MEMORY(_qzz_address, _qzz_initial_count) \
+// for access count histograms of memory larger than 1k
+#define DHAT_HISTOGRAM_MEMORY(_qzz_address) \
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DHAT_HISTOGRAM_MEMORY, \
- (_qzz_address), (_qzz_initial_count), 0, 0, 0)
-
-// convenience macro for DHAT_HISTOGRAM_MEMORY
-// for initialized memory (calloc, std::vector with initialization)
-#define DHAT_HISTOGRAM_MEMORY_INIT(_qzz_address) \
- DHAT_HISTOGRAM_MEMORY(_qzz_address, 1U)
-
-// convenience macro for DHAT_HISTOGRAM_MEMORY
-// for uninitialized memory (malloc, std::vector without initialization)
-#define DHAT_HISTOGRAM_MEMORY_UNINIT(_qzz_address) \
- DHAT_HISTOGRAM_MEMORY(_qzz_address, 0U)
-
+ (_qzz_address), 0, 0, 0, 0)
#endif
the size of the generated output reasonable. However, it is possible to override
this limit using client requests. The use-case for this is to first run DHAT
normally, and then identify any large blocks that you would like to further
-investigate with access histograms. The client requests are declared in
-<filename>dhat/dhat.h</filename>. There are two versions, <computeroutput>DHAT_HISTOGRAM_MEMORY_INIT</computeroutput> and
-<computeroutput>DHAT_HISTOGRAM_MEMORY_UNINIT</computeroutput>. The
-UNINIT version should be used with allocators that return uninitialized
-memory (like <computeroutput>malloc</computeroutput> and <computeroutput>new</computeroutput>
-without a constructor). The INIT version should be used with allocators
-that initialize memory (like <computeroutput>calloc</computeroutput> and <computeroutput>new</computeroutput>
-with a constructor). The macros should be placed immediately after the
-call to the allocator, and use the pointer returned by the allocator.</para>
+investigate with access count histograms. The client request is declared in
+<filename>dhat/dhat.h</filename> and is called <computeroutput>DHAT_HISTOGRAM_MEMORY</computeroutput>.
+The macro should be placed immediately after the call to the allocator,
+and use the pointer returned by the allocator.</para>
<programlisting><![CDATA[
// LargeStruct bigger than 1024 bytes
struct LargeStruct* ls = malloc(sizeof(struct LargeStruct));
-DHAT_HISTOGRAM_MEMORY_INIT(ls);
+DHAT_HISTOGRAM_MEMORY(ls);
]]></programlisting>
<para>The memory that can be profiled in this way with user requests
-has a further upper limit of 25kbytes.</para>
+has a further upper limit of 25kbytes. Be aware that the access counts
+will all be set to zero. This means that the access counts will not
+include any reads or writes performed during initialisation. An example where this
+will happen are uses of C++ <computeroutput>new</computeroutput> with user-defined constructors.</para>
<para>Access counts can be useful for identifying data alignment holes or other
layout inefficiencies.</para>
int main()
{
std::vector<uint8_t> vec(2000, 0);
- DHAT_HISTOGRAM_MEMORY_INIT(vec.data());
+ DHAT_HISTOGRAM_MEMORY(vec.data());
std::mt19937 gen(42);;
std::uniform_int_distribution<> index_distrib(0, 1999);
std::uniform_int_distribution<> val_distrib(0, 255);
// try to generate some warnings
vec.resize(500);
vec.shrink_to_fit();
- DHAT_HISTOGRAM_MEMORY_UNINIT(vec.data());
+ DHAT_HISTOGRAM_MEMORY(vec.data());
auto old = vec.data();
vec.resize(100000);
// old should have been deleted
- DHAT_HISTOGRAM_MEMORY_UNINIT(old);
+ DHAT_HISTOGRAM_MEMORY(old);
// and this is too big
- DHAT_HISTOGRAM_MEMORY_UNINIT(vec.data());
+ DHAT_HISTOGRAM_MEMORY(vec.data());
}