summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-08-19 01:47:33 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2014-08-19 01:47:33 +0000
commit82ff058cf9f8e95b44da737c86f7db419e335c6d (patch)
treea39fbf66a6ef7750d4b84fa1d868a56d152bf57b
parentdfd04582ae3c84e92700710b92d614dd0f51cce5 (diff)
downloadbcm5719-llvm-82ff058cf9f8e95b44da737c86f7db419e335c6d.tar.gz
bcm5719-llvm-82ff058cf9f8e95b44da737c86f7db419e335c6d.zip
DFSan's set label function should avoid writing to the shadow memory when the write would not change the value in memory.
When writing a label to shadow memory, don't write if the value is already set to the value being written. This dramatically reduces real memory consumption in programs with sparse use of labels. Test Plan: It would be nice to test that unnecessary writes are skipped, but I do not see how a unit test could do this. Patch by Sam Kerner! Differential Revision: http://reviews.llvm.org/D4894 llvm-svn: 215961
-rw-r--r--compiler-rt/lib/dfsan/dfsan.cc14
1 files changed, 13 insertions, 1 deletions
diff --git a/compiler-rt/lib/dfsan/dfsan.cc b/compiler-rt/lib/dfsan/dfsan.cc
index 11ab77e2eb7..a9673d5c5f8 100644
--- a/compiler-rt/lib/dfsan/dfsan.cc
+++ b/compiler-rt/lib/dfsan/dfsan.cc
@@ -169,8 +169,20 @@ dfsan_label dfsan_create_label(const char *desc, void *userdata) {
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
void __dfsan_set_label(dfsan_label label, void *addr, uptr size) {
- for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp)
+ for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp) {
+ // Don't write the label if it is already the value we need it to be.
+ // In a program where most addresses are not labeled, it is common that
+ // a page of shadow memory is entirely zeroed. The Linux copy-on-write
+ // implementation will share all of the zeroed pages, making a copy of a
+ // page when any value is written. The un-sharing will happen even if
+ // the value written does not change the value in memory. Avoiding the
+ // write when both |label| and |*labelp| are zero dramatically reduces
+ // the amount of real memory used by large programs.
+ if (label == *labelp)
+ continue;
+
*labelp = label;
+ }
}
SANITIZER_INTERFACE_ATTRIBUTE
OpenPOWER on IntegriCloud