|
From: <sv...@va...> - 2015-05-26 21:26:49
|
Author: philippe
Date: Tue May 26 22:26:39 2015
New Revision: 15293
Log:
Slightly improve x86 unwind intensive workload.
e.g. perf/memrw is improved by 2% to 3% with this patch.
The unwinding code on x86 is trying to unwind using
either the %ebp-chain or CFI unwinding.
If these 2 techniques fail, then it tries to unwind
using FPO (PDB) debug info.
However, unless running wine or similar, there will never be
such FPO/PDB info.
The function VG_(use_FPO_info) is thus called for nothing
for each 'end of stack'. This function scans all the loaded di
to find a debug info that has some FP, to not find anything.
With this patch, the unwind code on x86 will only call VG_(use_FPO_info) if
some FPO/PDB info was loaded.
The fact that FPO/PDB info was loaded is cached and updated similarly to
cfi cache : each time new debug info is loaded, the cache value is refreshed
using the debuginfo generation.
The patch also changes the name of VG_(CF_info_generation)
to VG_(debuginfo_generation), as this generation is changed for
any kind of load or unload of debug info, not only for CFI based debug
info
Modified:
trunk/coregrind/m_debuginfo/debuginfo.c
trunk/coregrind/m_stacktrace.c
trunk/coregrind/pub_core_debuginfo.h
Modified: trunk/coregrind/m_debuginfo/debuginfo.c
==============================================================================
--- trunk/coregrind/m_debuginfo/debuginfo.c (original)
+++ trunk/coregrind/m_debuginfo/debuginfo.c Tue May 26 22:26:39 2015
@@ -105,7 +105,7 @@
/*--- fwdses ---*/
/*------------------------------------------------------------*/
-static UInt CF_info_generation = 0;
+static UInt debuginfo_generation = 0;
static void cfsi_m_cache__invalidate ( void );
@@ -2645,12 +2645,12 @@
static void cfsi_m_cache__invalidate ( void ) {
VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache));
- CF_info_generation++;
+ debuginfo_generation++;
}
-UInt VG_(CF_info_generation) (void)
+UInt VG_(debuginfo_generation) (void)
{
- return CF_info_generation;
+ return debuginfo_generation;
}
static inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip )
@@ -3086,6 +3086,16 @@
return True;
}
+Bool VG_(FPO_info_present)(void)
+{
+ const DebugInfo* di;
+ for (di = debugInfo_list; di != NULL; di = di->next) {
+ if (di->fpo != NULL)
+ return True;
+ }
+ return False;
+}
+
/*--------------------------------------------------------------*/
/*--- ---*/
Modified: trunk/coregrind/m_stacktrace.c
==============================================================================
--- trunk/coregrind/m_stacktrace.c (original)
+++ trunk/coregrind/m_stacktrace.c Tue May 26 22:26:39 2015
@@ -129,11 +129,16 @@
then they will not land in the same cache bucket.
*/
+/* cached result of VG_(FPO_info_present)(). Refreshed each time
+ the fp_CF_verif_generation is different of the current debuginfo
+ generation. */
+static Bool FPO_info_present = False;
+
static UInt fp_CF_verif_generation = 0;
// Our cache has to be maintained in sync with the CFI cache.
-// Each time the CFI cache is changed, its generation will be incremented.
+// Each time the debuginfo is changed, its generation will be incremented.
// We will clear our cache when our saved generation differs from
-// the CFI cache generation.
+// the debuginfo generation.
UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
/*OUT*/Addr* ips, UInt max_n_ips,
@@ -226,9 +231,10 @@
}
# endif
- if (UNLIKELY (fp_CF_verif_generation != VG_(CF_info_generation)())) {
- fp_CF_verif_generation = VG_(CF_info_generation)();
+ if (UNLIKELY (fp_CF_verif_generation != VG_(debuginfo_generation)())) {
+ fp_CF_verif_generation = VG_(debuginfo_generation)();
VG_(memset)(&fp_CF_verif_cache, 0, sizeof(fp_CF_verif_cache));
+ FPO_info_present = VG_(FPO_info_present)();
}
@@ -398,8 +404,9 @@
}
/* And, similarly, try for MSVC FPO unwind info. */
- if ( VG_(use_FPO_info)( &uregs.xip, &uregs.xsp, &uregs.xbp,
- fp_min, fp_max ) ) {
+ if (FPO_info_present
+ && VG_(use_FPO_info)( &uregs.xip, &uregs.xsp, &uregs.xbp,
+ fp_min, fp_max ) ) {
if (debug) unwind_case = "MS";
if (do_stats) stats.MS++;
goto unwind_done;
Modified: trunk/coregrind/pub_core_debuginfo.h
==============================================================================
--- trunk/coregrind/pub_core_debuginfo.h (original)
+++ trunk/coregrind/pub_core_debuginfo.h Tue May 26 22:26:39 2015
@@ -142,14 +142,22 @@
Addr min_accessible,
Addr max_accessible );
-/* returns the "generation" of the CF info.
+/* returns the "generation" of the debug info.
Each time some debuginfo is changed (e.g. loaded or unloaded),
- the VG_(CF_info_generation) value returned will be increased.
- This can be used to flush cached information derived from the CF info. */
-extern UInt VG_(CF_info_generation) (void);
+ the VG_(debuginfo_generation)() value returned will be increased.
+ This can be used to flush cached information derived from debug
+ info (e.g. CFI info or FPO info or ...). */
+extern UInt VG_(debuginfo_generation) (void);
+/* True if some FPO information is loaded.
+ It is useless to call VG_(use_FPO_info) if this returns False.
+ Note that the return value should preferrably be cached in
+ the stack unwind code, and re-queried when the debug info generation
+ changes. */
+extern Bool VG_(FPO_info_present)(void);
+
/* Use MSVC FPO data to do one step of stack unwinding. */
extern Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
/*MOD*/Addr* spP,
|