summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-06-05 14:38:53 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-06-05 14:38:53 +0000
commit38c228a8427d3765bb393258806213ed6a8566c0 (patch)
tree0e334588dcbe493516fb0b48bad85e2b6b00fb0b /compiler-rt
parent493df136d9ff897128839de753676387019b698a (diff)
downloadbcm5719-llvm-38c228a8427d3765bb393258806213ed6a8566c0.tar.gz
bcm5719-llvm-38c228a8427d3765bb393258806213ed6a8566c0.zip
[asancov] Faster coverage in memory-mapped mode.
Use caller pc of __sanitizer_cov_module_init to figure out when 2 sequential calls are from the same module; skip .sancov.map file update in this case. llvm-svn: 210267
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.h2
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc12
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc33
3 files changed, 26 insertions, 21 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 435e1fafb8e..02271e72620 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -192,7 +192,7 @@ void PrepareForSandboxing(__sanitizer_sandbox_arguments *args);
void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args);
void SetSandboxingCallback(void (*f)());
-void CovUpdateMapping();
+void CovUpdateMapping(uptr caller_pc = 0);
void CovBeforeFork();
void CovAfterFork(int child_pid);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
index 206d07ccd59..ba6c58c5799 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
@@ -174,12 +174,6 @@ void CoverageData::Extend(uptr npcs) {
}
atomic_store(&pc_array_size, size, memory_order_release);
-
- if (SANITIZER_ANDROID) {
- // dlopen/dlclose interceptors do not work on Android, so we rely on
- // Extend() calls to update .sancov.map.
- CovUpdateMapping();
- }
}
// Simply add the pc into the vector under lock. If the function is called more
@@ -371,6 +365,12 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() {
coverage_data.Init();
}
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_module_init(uptr npcs) {
+ if (SANITIZER_ANDROID && common_flags()->coverage &&
+ common_flags()->coverage_direct) {
+ // dlopen/dlclose interceptors do not work on Android, so we rely on
+ // Extend() calls to update .sancov.map.
+ CovUpdateMapping(GET_CALLER_PC());
+ }
coverage_data.Extend(npcs);
}
SANITIZER_INTERFACE_ATTRIBUTE
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
index bfeb3210758..28c93697c6a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
@@ -40,30 +40,36 @@ static const uptr kMaxTextSize = 64 * 1024;
struct CachedMapping {
public:
- bool TestAndUpdate(const char *new_mapping) {
+ bool NeedsUpdate(uptr pc) {
int new_pid = internal_getpid();
- if (last_mapping && last_pid == new_pid &&
- internal_strcmp(last_mapping, new_mapping) == 0)
+ if (last_pid == new_pid && pc && pc >= last_range_start &&
+ pc < last_range_end)
return false;
- if (!last_mapping) last_mapping = (char *)InternalAlloc(kMaxTextSize);
last_pid = new_pid;
- internal_strncpy(last_mapping, new_mapping, kMaxTextSize);
return true;
}
+ void SetModuleRange(uptr start, uptr end) {
+ last_range_start = start;
+ last_range_end = end;
+ }
+
private:
- char *last_mapping;
+ uptr last_range_start, last_range_end;
int last_pid;
};
static CachedMapping cached_mapping;
static StaticSpinMutex mapping_mu;
-void CovUpdateMapping() {
+void CovUpdateMapping(uptr caller_pc) {
if (!common_flags()->coverage || !common_flags()->coverage_direct) return;
SpinMutexLock l(&mapping_mu);
+ if (!cached_mapping.NeedsUpdate(caller_pc))
+ return;
+
InternalScopedString text(kMaxTextSize);
InternalScopedBuffer<char> modules_data(kMaxNumberOfModules *
sizeof(LoadedModule));
@@ -76,17 +82,16 @@ void CovUpdateMapping() {
for (int i = 0; i < n_modules; ++i) {
char *module_name = StripModuleName(modules[i].full_name());
for (unsigned j = 0; j < modules[i].n_ranges(); ++j) {
- text.append("%zx %zx %zx %s\n", modules[i].address_range_start(j),
- modules[i].address_range_end(j), modules[i].base_address(),
- module_name);
+ uptr start = modules[i].address_range_start(j);
+ uptr end = modules[i].address_range_end(j);
+ uptr base = modules[i].base_address();
+ text.append("%zx %zx %zx %s\n", start, end, base, module_name);
+ if (caller_pc && caller_pc >= start && caller_pc < end)
+ cached_mapping.SetModuleRange(start, end);
}
InternalFree(module_name);
}
- // Do not write mapping if it is the same as the one we've wrote last time.
- if (!cached_mapping.TestAndUpdate(text.data()))
- return;
-
int err;
InternalScopedString tmp_path(64 +
internal_strlen(common_flags()->coverage_dir));
OpenPOWER on IntegriCloud