|
From: <sv...@va...> - 2006-05-27 15:31:13
|
Author: weidendo
Date: 2006-05-27 16:30:58 +0100 (Sat, 27 May 2006)
New Revision: 5942
Log:
Fix a failed assertion on retranslation of rep or cmov instructions.
Bug description: Very similar to cachegrind, callgrind stores
metainformation per guest instruction; this meta information is
given when calling into the simulator. In contrast to cachegrind,
callgrind keeps this info when the source is discarded, and checks
on retranslation whether the same meta info is generated.
This check sometimes fails: E.g. for rep x86 instructions, 2 simulator
calls
are usually generated for one x86 instruction (the instruction fetch and
a
data access), thus overwriting the data_size meta information for one
x86
instruction first with 0, and afterwards e.g. with 1. The check on
retranslation
fails because of this. The fix is to only write/check data_size values
>0.
Modified:
trunk/callgrind/bb.c
trunk/callgrind/main.c
Modified: trunk/callgrind/bb.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/callgrind/bb.c 2006-05-27 11:25:18 UTC (rev 5941)
+++ trunk/callgrind/bb.c 2006-05-27 15:30:58 UTC (rev 5942)
@@ -120,16 +120,17 @@
UInt instr_count, UInt cjmp_count, Bool cjmp_inverted)
{
BB* new;
- UInt new_idx;
+ UInt new_idx, size;
=20
/* check fill degree of bb hash table and resize if needed (>80%) */
bbs.entries++;
if (10 * bbs.entries / bbs.size > 8)
resize_bb_table();
=20
- new =3D (BB*) CLG_MALLOC(sizeof(BB) +
- instr_count * sizeof(InstrInfo) +
- (cjmp_count+1) * sizeof(CJmpInfo));
+ size =3D sizeof(BB) + instr_count * sizeof(InstrInfo)
+ + (cjmp_count+1) * sizeof(CJmpInfo);
+ new =3D (BB*) CLG_MALLOC(size);
+ VG_(memset)(new, 0, size);
=20
new->obj =3D obj;
new->offset =3D offset;
Modified: trunk/callgrind/main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/callgrind/main.c 2006-05-27 11:25:18 UTC (rev 5941)
+++ trunk/callgrind/main.c 2006-05-27 15:30:58 UTC (rev 5942)
@@ -272,29 +272,44 @@
es =3D insert_simcall(bbOut, ii, dataSize, instrIssued,
loadAddrExpr, storeAddrExpr);
=20
+ CLG_DEBUG(5, " Instr +%2d (Size %d, DSize %d): ESet %s (Size %d)\n",
+ instr_offset, instrLen, dataSize,=20
+ es ? es->name : (Char*)"(no instrumentation)",
+ es ? es->size : 0);
+
if (bb_seen_before) {
+ CLG_DEBUG(5, " before: Instr +%2d (Size %d, DSize %d)\n",
+ ii->instr_offset, ii->instr_size, ii->data_size);
+
CLG_ASSERT(ii->instr_offset =3D=3D instr_offset);
CLG_ASSERT(ii->instr_size =3D=3D instrLen);
- CLG_ASSERT(ii->data_size =3D=3D dataSize);
CLG_ASSERT(ii->cost_offset =3D=3D *cost_offset);
CLG_ASSERT(ii->eventset =3D=3D es);
+
+ /* Only check size if data size >0.
+ * This is needed: e.g. for rep or cmov x86 instructions, the same Instr=
Info
+ * is used both for 2 simulator calls: for the pure instruction fetch an=
d
+ * separately for an memory access (which may not happen dependin=
g on flags).
+ * If checked always, this triggers an assertion failure on retranslatio=
n.
+ */
+ if (dataSize>0) CLG_ASSERT(ii->data_size =3D=3D dataSize);
+
}
else {
ii->instr_offset =3D instr_offset;
ii->instr_size =3D instrLen;
- ii->data_size =3D dataSize;
ii->cost_offset =3D *cost_offset;
ii->eventset =3D es;
+ =20
+ /* data size only relevant if >0 */
+ if (dataSize > 0) ii->data_size =3D dataSize;
=20
+
CLG_(stat).distinct_instrs++;
}
=20
*cost_offset +=3D es ? es->size : 0;
=20
- CLG_DEBUG(5, " Instr +%2d (Size %d, DSize %d): ESet %s (Size %d)\n",
- instr_offset, instrLen, dataSize,=20
- es ? es->name : (Char*)"(no Instr)",
- es ? es->size : 0);
}
=20
#if defined(VG_BIGENDIAN)
|