<br><br><div class="gmail_quote">On Fri, Jan 13, 2012 at 8:13 AM, Alexander Potapenko <span dir="ltr"><<a href="mailto:glider@google.com">glider@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: glider<br>
Date: Fri Jan 13 10:13:58 2012<br>
New Revision: 148116<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=148116&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=148116&view=rev</a><br>
Log:<br>
This patch adds two methods, __asan_allocate_island and __asan_deallocate_island<br>
and switches our interceptors to using them instead of the default<br>
vm_allocate-based approach used by mach_override_ptr.<br>
<br>
To simplify the code, a fixed memory mapping is used for the allocation pool --<br>
note that we can't mmap an arbitrary chunk of memory, because the shadow memory hasn't been mapped yet<br>
(for the reasons discussed in <a href="http://code.google.com/p/address-sanitizer/issues/detail?id=24" target="_blank">http://code.google.com/p/address-sanitizer/issues/detail?id=24</a>, we cannot map the shadow earlier)<br>

<br>
The patch drops the program startup time from several second to half a second,<br></blockquote><div>Nice improvement! </div><div>The startup time on 64-bit Mac was irritating. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

which speeds up the execution of ASan tests noticeably.<br>
Because of the virtual memory size occupied by the programs it's hard<br>
to speed up the shutdown time, which would've also helped the tests.<br>
<br>
Modified:<br>
    compiler-rt/trunk/lib/asan/asan_interceptors.cc<br>
    compiler-rt/trunk/lib/asan/asan_mac.cc<br>
    compiler-rt/trunk/lib/asan/asan_mac.h<br>
<br>
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=148116&r1=148115&r2=148116&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=148116&r1=148115&r2=148116&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)<br>
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Fri Jan 13 10:13:58 2012<br>
@@ -43,24 +43,25 @@<br>
 // After interception, the calls to system functions will be substituted by<br>
 // calls to our interceptors. We store pointers to system function f()<br>
 // in __asan::real_f().<br>
-//<br>
-// TODO(glider): mach_override_ptr() tends to spend too much time<br>
-// in allocateBranchIsland(). This should be ok for real-word<br>
-// application, but slows down our tests which fork too many children.<br>
 #ifdef __APPLE__<br>
 #include "mach_override/mach_override.h"<br>
 #define WRAPPER_NAME(x) "wrap_"#x<br>
<br>
-#define OVERRIDE_FUNCTION(oldfunc, newfunc)                             \<br>
-  CHECK(0 == __asan_mach_override_ptr((void*)(oldfunc),                        \<br>
-                                      (void*)(newfunc),                        \<br>
-                                      (void**)&real_##oldfunc));               \<br>
-  CHECK(real_##oldfunc != NULL);<br>
-<br>
-#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc)                   \<br>
-  do { __asan_mach_override_ptr((void*)(oldfunc),                              \<br>
-                                (void*)(newfunc),                              \<br>
-                                (void**)&real_##oldfunc); } while (0)<br>
+#define OVERRIDE_FUNCTION(oldfunc, newfunc)                                   \<br>
+  do {CHECK(0 == __asan_mach_override_ptr_custom((void*)(oldfunc),            \<br>
+                                                 (void*)(newfunc),            \<br>
+                                                 (void**)&real_##oldfunc,     \<br>
+                                                 __asan_allocate_island,      \<br>
+                                                 __asan_deallocate_island));  \<br>
+  CHECK(real_##oldfunc != NULL);   } while(0)<br>
+<br>
+#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc)               \<br>
+  do { __asan_mach_override_ptr_custom((void*)(oldfunc),            \<br>
+                                       (void*)(newfunc),            \<br>
+                                       (void**)&real_##oldfunc,     \<br>
+                                       __asan_allocate_island,      \<br>
+                                       __asan_deallocate_island);   \<br>
+  } while (0)<br>
<br>
 #define INTERCEPT_FUNCTION(func)                                        \<br>
   OVERRIDE_FUNCTION(func, WRAP(func))<br>
<br>
Modified: compiler-rt/trunk/lib/asan/asan_mac.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=148116&r1=148115&r2=148116&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=148116&r1=148115&r2=148116&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)<br>
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Fri Jan 13 10:13:58 2012<br>
@@ -32,6 +32,8 @@<br>
<br>
 namespace __asan {<br>
<br>
+void *island_allocator_pos = NULL;<br></blockquote><div><br></div><div>This could be made static, even though it is inside __asan namespace. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
 extern dispatch_async_f_f real_dispatch_async_f;<br>
 extern dispatch_sync_f_f real_dispatch_sync_f;<br>
 extern dispatch_after_f_f real_dispatch_after_f;<br>
@@ -172,6 +174,37 @@<br>
   OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);<br>
 }<br>
<br>
+// The range of pages to be used by __asan_mach_override_ptr for escape<br>
+// islands.<br>
+// TODO(glider): instead of mapping a fixed range we must find a range of<br>
+// unmapped pages in vmmap and take them.<br>
+#define kIslandEnd (0x7fffffdf0000 - kPageSize)<br></blockquote><div><br></div><div>Don't you need to use constants from asan_mapping.h?  </div><div>The current constants don't seem correct for 32-bits (although they may "magically" work).</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+#define kIslandBeg (kIslandEnd - 256 * kPageSize)<br>
+<br>
+extern "C"<br>
+mach_error_t __asan_allocate_island(void **ptr,<br>
+                                    size_t unused_size,<br>
+                                    void *unused_hint) {<br>
+  if (!island_allocator_pos) {<br>
+    if ((void*)-1 == asan_mmap((void*)kIslandBeg, kIslandEnd - kIslandBeg,<br>
+                               PROT_READ | PROT_WRITE | PROT_EXEC,<br>
+                               MAP_PRIVATE | MAP_ANON | MAP_FIXED,<br>
+                               -1, 0)) {<br>
+      return KERN_NO_SPACE;<br>
+    }<br>
+    island_allocator_pos = (void*)kIslandBeg;<br>
+  };<br>
+  *ptr = island_allocator_pos;<br>
+  island_allocator_pos = (char*)island_allocator_pos + kPageSize;<br>
+  return err_none;<br>
+}<br>
+<br>
+extern "C"<br>
+mach_error_t __asan_deallocate_island(void *ptr) {<br>
+  // Do nothing.<br>
+  // TODO(glider): allow to free and reuse the island memory.<br>
+  return err_none;<br>
+}<br>
<br>
 // Support for the following functions from libdispatch on Mac OS:<br>
 //   dispatch_async_f()<br>
<br>
Modified: compiler-rt/trunk/lib/asan/asan_mac.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.h?rev=148116&r1=148115&r2=148116&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.h?rev=148116&r1=148115&r2=148116&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/asan_mac.h (original)<br>
+++ compiler-rt/trunk/lib/asan/asan_mac.h Fri Jan 13 10:13:58 2012<br>
@@ -20,6 +20,7 @@<br>
<br>
 // TODO(glider): need to check if the OS X version is 10.6 or greater.<br>
 #include <dispatch/dispatch.h><br>
+#include <mach/mach_error.h><br>
 #include <setjmp.h><br>
<br>
 typedef void* pthread_workqueue_t;<br>
@@ -54,6 +55,15 @@<br>
<br>
<br>
 extern "C" {<br>
+<br>
+// Allocate memory for the escape island. This cannot be moved to<br>
+// mach_override, because the allocator needs to know about the ASan shadow<br>
+// mappings.<br>
+// TODO(glider): in order to place a relative jump the allocated memory should<br>
+// be within 2 Gb from the hint address.<br>
+mach_error_t __asan_allocate_island(void **ptr, size_t unused_size, void *unused_hint);<br>
+mach_error_t __asan_deallocate_island(void *ptr);<br>
+<br>
 // dispatch_barrier_async_f() is not declared in <dispatch/dispatch.h>.<br>
 void dispatch_barrier_async_f(dispatch_queue_t dq,<br>
                               void *ctxt, dispatch_function_t func);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br>