[compiler-rt] r215961 - DFSan's set label function should avoid writing to the shadow memory when the write would not change the value in memory.

Peter Collingbourne peter at pcc.me.uk
Mon Aug 18 18:47:34 PDT 2014


Author: pcc
Date: Mon Aug 18 20:47:33 2014
New Revision: 215961

URL: http://llvm.org/viewvc/llvm-project?rev=215961&view=rev
Log:
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

Modified:
    compiler-rt/trunk/lib/dfsan/dfsan.cc

Modified: compiler-rt/trunk/lib/dfsan/dfsan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/dfsan/dfsan.cc?rev=215961&r1=215960&r2=215961&view=diff
==============================================================================
--- compiler-rt/trunk/lib/dfsan/dfsan.cc (original)
+++ compiler-rt/trunk/lib/dfsan/dfsan.cc Mon Aug 18 20:47:33 2014
@@ -169,8 +169,20 @@ dfsan_label dfsan_create_label(const cha
 
 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





More information about the llvm-commits mailing list