forked from OSchip/llvm-project
				
			
							parent
							
								
									6c7dbf5858
								
							
						
					
					
						commit
						5bfac97ff9
					
				| 
						 | 
					@ -28,9 +28,7 @@ const int kTidBits = 13;
 | 
				
			||||||
const unsigned kMaxTid = 1 << kTidBits;
 | 
					const unsigned kMaxTid = 1 << kTidBits;
 | 
				
			||||||
const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
 | 
					const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
 | 
				
			||||||
const int kClkBits = 43;
 | 
					const int kClkBits = 43;
 | 
				
			||||||
#ifdef TSAN_GO
 | 
					#ifndef TSAN_GO
 | 
				
			||||||
const int kShadowStackSize = 8 * 1024;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
const int kShadowStackSize = 1024;
 | 
					const int kShadowStackSize = 1024;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,7 @@ enum MBlockType {
 | 
				
			||||||
  MBlockScopedBuf,
 | 
					  MBlockScopedBuf,
 | 
				
			||||||
  MBlockString,
 | 
					  MBlockString,
 | 
				
			||||||
  MBlockStackTrace,
 | 
					  MBlockStackTrace,
 | 
				
			||||||
 | 
					  MBlockShadowStack,
 | 
				
			||||||
  MBlockSync,
 | 
					  MBlockSync,
 | 
				
			||||||
  MBlockClock,
 | 
					  MBlockClock,
 | 
				
			||||||
  MBlockThreadContex,
 | 
					  MBlockThreadContex,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -451,14 +451,28 @@ void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size) {
 | 
				
			||||||
void FuncEntry(ThreadState *thr, uptr pc) {
 | 
					void FuncEntry(ThreadState *thr, uptr pc) {
 | 
				
			||||||
  DCHECK_EQ(thr->in_rtl, 0);
 | 
					  DCHECK_EQ(thr->in_rtl, 0);
 | 
				
			||||||
  StatInc(thr, StatFuncEnter);
 | 
					  StatInc(thr, StatFuncEnter);
 | 
				
			||||||
  DPrintf2("#%d: tsan::FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc);
 | 
					  DPrintf2("#%d: FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc);
 | 
				
			||||||
  thr->fast_state.IncrementEpoch();
 | 
					  thr->fast_state.IncrementEpoch();
 | 
				
			||||||
  TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncEnter, pc);
 | 
					  TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncEnter, pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Shadow stack maintenance can be replaced with
 | 
					  // Shadow stack maintenance can be replaced with
 | 
				
			||||||
  // stack unwinding during trace switch (which presumably must be faster).
 | 
					  // stack unwinding during trace switch (which presumably must be faster).
 | 
				
			||||||
  DCHECK_GE(thr->shadow_stack_pos, &thr->shadow_stack[0]);
 | 
					  DCHECK_GE(thr->shadow_stack_pos, &thr->shadow_stack[0]);
 | 
				
			||||||
 | 
					#ifndef TSAN_GO
 | 
				
			||||||
  DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);
 | 
					  DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  if (thr->shadow_stack_pos == thr->shadow_stack_end) {
 | 
				
			||||||
 | 
					    const int sz = thr->shadow_stack_end - thr->shadow_stack;
 | 
				
			||||||
 | 
					    const int newsz = 2 * sz;
 | 
				
			||||||
 | 
					    uptr *newstack = (uptr*)internal_alloc(MBlockShadowStack,
 | 
				
			||||||
 | 
					        newsz * sizeof(uptr));
 | 
				
			||||||
 | 
					    internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr));
 | 
				
			||||||
 | 
					    internal_free(thr->shadow_stack);
 | 
				
			||||||
 | 
					    thr->shadow_stack = newstack;
 | 
				
			||||||
 | 
					    thr->shadow_stack_pos = newstack + sz;
 | 
				
			||||||
 | 
					    thr->shadow_stack_end = newstack + newsz;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  thr->shadow_stack_pos[0] = pc;
 | 
					  thr->shadow_stack_pos[0] = pc;
 | 
				
			||||||
  thr->shadow_stack_pos++;
 | 
					  thr->shadow_stack_pos++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -466,12 +480,14 @@ void FuncEntry(ThreadState *thr, uptr pc) {
 | 
				
			||||||
void FuncExit(ThreadState *thr) {
 | 
					void FuncExit(ThreadState *thr) {
 | 
				
			||||||
  DCHECK_EQ(thr->in_rtl, 0);
 | 
					  DCHECK_EQ(thr->in_rtl, 0);
 | 
				
			||||||
  StatInc(thr, StatFuncExit);
 | 
					  StatInc(thr, StatFuncExit);
 | 
				
			||||||
  DPrintf2("#%d: tsan::FuncExit\n", (int)thr->fast_state.tid());
 | 
					  DPrintf2("#%d: FuncExit\n", (int)thr->fast_state.tid());
 | 
				
			||||||
  thr->fast_state.IncrementEpoch();
 | 
					  thr->fast_state.IncrementEpoch();
 | 
				
			||||||
  TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncExit, 0);
 | 
					  TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncExit, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  DCHECK_GT(thr->shadow_stack_pos, &thr->shadow_stack[0]);
 | 
					  DCHECK_GT(thr->shadow_stack_pos, &thr->shadow_stack[0]);
 | 
				
			||||||
 | 
					#ifndef TSAN_GO
 | 
				
			||||||
  DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);
 | 
					  DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  thr->shadow_stack_pos--;
 | 
					  thr->shadow_stack_pos--;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -228,7 +228,14 @@ struct ThreadState {
 | 
				
			||||||
  u64 *racy_shadow_addr;
 | 
					  u64 *racy_shadow_addr;
 | 
				
			||||||
  u64 racy_state[2];
 | 
					  u64 racy_state[2];
 | 
				
			||||||
  Trace trace;
 | 
					  Trace trace;
 | 
				
			||||||
 | 
					#ifndef TSAN_GO
 | 
				
			||||||
 | 
					  // C/C++ uses embed shadow stack of fixed size.
 | 
				
			||||||
  uptr shadow_stack[kShadowStackSize];
 | 
					  uptr shadow_stack[kShadowStackSize];
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  // Go uses satellite shadow stack with dynamic size.
 | 
				
			||||||
 | 
					  uptr *shadow_stack;
 | 
				
			||||||
 | 
					  uptr *shadow_stack_end;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  ThreadClock clock;
 | 
					  ThreadClock clock;
 | 
				
			||||||
  u64 stat[StatCnt];
 | 
					  u64 stat[StatCnt];
 | 
				
			||||||
  const int tid;
 | 
					  const int tid;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,6 +173,14 @@ void ThreadStart(ThreadState *thr, int tid) {
 | 
				
			||||||
  tctx->epoch1 = (u64)-1;
 | 
					  tctx->epoch1 = (u64)-1;
 | 
				
			||||||
  new(thr) ThreadState(CTX(), tid, tctx->epoch0, stk_addr, stk_size,
 | 
					  new(thr) ThreadState(CTX(), tid, tctx->epoch0, stk_addr, stk_size,
 | 
				
			||||||
                       tls_addr, tls_size);
 | 
					                       tls_addr, tls_size);
 | 
				
			||||||
 | 
					#ifdef TSAN_GO
 | 
				
			||||||
 | 
					  // Setup dynamic shadow stack.
 | 
				
			||||||
 | 
					  const int kInitStackSize = 8;
 | 
				
			||||||
 | 
					  thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack,
 | 
				
			||||||
 | 
					      kInitStackSize * sizeof(uptr));
 | 
				
			||||||
 | 
					  thr->shadow_stack_pos = thr->shadow_stack;
 | 
				
			||||||
 | 
					  thr->shadow_stack_end = thr->shadow_stack + kInitStackSize;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  tctx->thr = thr;
 | 
					  tctx->thr = thr;
 | 
				
			||||||
  thr->fast_synch_epoch = tctx->epoch0;
 | 
					  thr->fast_synch_epoch = tctx->epoch0;
 | 
				
			||||||
  thr->clock.set(tid, tctx->epoch0);
 | 
					  thr->clock.set(tid, tctx->epoch0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ void StackTrace::Init(const uptr *pcs, uptr cnt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) {
 | 
					void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) {
 | 
				
			||||||
  Reset();
 | 
					  Reset();
 | 
				
			||||||
  n_ = thr->shadow_stack_pos - &thr->shadow_stack[0];
 | 
					  n_ = thr->shadow_stack_pos - thr->shadow_stack;
 | 
				
			||||||
  if (n_ + !!toppc == 0)
 | 
					  if (n_ + !!toppc == 0)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  if (c_) {
 | 
					  if (c_) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,10 +42,16 @@ typedef u64 Event;
 | 
				
			||||||
struct TraceHeader {
 | 
					struct TraceHeader {
 | 
				
			||||||
  StackTrace stack0;  // Start stack for the trace.
 | 
					  StackTrace stack0;  // Start stack for the trace.
 | 
				
			||||||
  u64        epoch0;  // Start epoch for the trace.
 | 
					  u64        epoch0;  // Start epoch for the trace.
 | 
				
			||||||
 | 
					#ifndef TSAN_GO
 | 
				
			||||||
  uptr       stack0buf[kShadowStackSize];
 | 
					  uptr       stack0buf[kShadowStackSize];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TraceHeader()
 | 
					  TraceHeader()
 | 
				
			||||||
 | 
					#ifndef TSAN_GO
 | 
				
			||||||
      : stack0(stack0buf, kShadowStackSize)
 | 
					      : stack0(stack0buf, kShadowStackSize)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					      : stack0()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
      , epoch0() {
 | 
					      , epoch0() {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue