tsan: do not imitate memory write on malloc() (Go)
better memory range access functions (put only 1 event to trace) (Go)

llvm-svn: 175056
diff --git a/compiler-rt/lib/tsan/go/tsan_go.cc b/compiler-rt/lib/tsan/go/tsan_go.cc
index c9c533a..b2aa622 100644
--- a/compiler-rt/lib/tsan/go/tsan_go.cc
+++ b/compiler-rt/lib/tsan/go/tsan_go.cc
@@ -116,14 +116,12 @@
 
 void __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr step,
                        void *pc) {
-  for (uptr i = 0; i < size; i += step)
-	  MemoryRead(thr, (uptr)pc, (uptr)addr + i, kSizeLog1);
+  MemoryAccessRangeStep(thr, (uptr)pc, (uptr)addr, size, step, false);
 }
 
 void __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr step,
                         void *pc) {
-  for (uptr i = 0; i < size; i += step)
-	  MemoryWrite(thr, (uptr)pc, (uptr)addr + i, kSizeLog1);
+  MemoryAccessRangeStep(thr, (uptr)pc, (uptr)addr, size, step, true);
 }
 
 void __tsan_func_enter(ThreadState *thr, void *pc) {
@@ -138,7 +136,7 @@
   if (thr == 0)  // probably before __tsan_init()
     return;
   thr->in_rtl++;
-  MemoryRangeImitateWrite(thr, (uptr)pc, (uptr)p, sz);
+  MemoryResetRange(thr, (uptr)pc, (uptr)p, sz);
   thr->in_rtl--;
 }
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index e29c18b..6452636 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -592,6 +592,8 @@
     u64 *shadow_mem, Shadow cur);
 void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
     uptr size, bool is_write);
+void MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr,
+    uptr size, uptr step, bool is_write);
 
 const int kSizeLog1 = 0;
 const int kSizeLog2 = 1;
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
index 3af42e4..f25fb41 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -422,4 +422,26 @@
         shadow_mem, cur);
   }
 }
+
+void MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr,
+    uptr size, uptr step, bool is_write) {
+  if (size == 0)
+    return;
+  FastState fast_state = thr->fast_state;
+  if (fast_state.GetIgnoreBit())
+    return;
+  StatInc(thr, StatMopRange);
+  fast_state.IncrementEpoch();
+  thr->fast_state = fast_state;
+  TraceAddEvent(thr, fast_state, EventTypeMop, pc);
+
+  for (uptr addr_end = addr + size; addr < addr_end; addr += step) {
+    u64 *shadow_mem = (u64*)MemToShadow(addr);
+    Shadow cur(fast_state);
+    cur.SetWrite(is_write);
+    cur.SetAddr0AndSizeLog(addr & (kShadowCell - 1), kSizeLog1);
+    MemoryAccessImpl(thr, addr, kSizeLog1, is_write, false,
+        shadow_mem, cur);
+  }
+}
 }  // namespace __tsan