<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>