diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2012-12-21 13:23:48 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2012-12-21 13:23:48 +0000 |
commit | a33bf2701e22a34005d02b62af857ca30c02d0e9 (patch) | |
tree | 3e6bd0846fe3a900146fabfab4e7fe4068199370 /compiler-rt/lib/tsan/rtl/tsan_interface_java.cc | |
parent | 92e37d31e7ad24e712e83ecbc6a8a53eb3a36fd6 (diff) | |
download | bcm5719-llvm-a33bf2701e22a34005d02b62af857ca30c02d0e9.tar.gz bcm5719-llvm-a33bf2701e22a34005d02b62af857ca30c02d0e9.zip |
tsan: fix Java memory move operations and add the test
llvm-svn: 170891
Diffstat (limited to 'compiler-rt/lib/tsan/rtl/tsan_interface_java.cc')
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interface_java.cc | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc index 2bebed8eb21..e425c75800b 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc @@ -37,14 +37,6 @@ struct BlockDesc { begin = true; } - explicit BlockDesc(BlockDesc *b) - : mtx(MutexTypeJavaMBlock, StatMtxJavaMBlock) - , head(b->head) { - CHECK_EQ(begin, false); - begin = true; - b->head = 0; - } - ~BlockDesc() { CHECK_EQ(begin, true); begin = false; @@ -108,6 +100,14 @@ static BlockDesc *getblock(uptr addr) { return &jctx->heap_shadow[i]; } +static uptr USED getmem(BlockDesc *b) { + uptr i = b - jctx->heap_shadow; + uptr p = jctx->heap_begin + i * kHeapAlignment; + CHECK_GE(p, jctx->heap_begin); + CHECK_LT(p, jctx->heap_begin + jctx->heap_size); + return p; +} + static BlockDesc *getblockbegin(uptr addr) { for (BlockDesc *b = getblock(addr);; b--) { CHECK_GE(b, jctx->heap_shadow); @@ -123,13 +123,17 @@ SyncVar* GetJavaSync(ThreadState *thr, uptr pc, uptr addr, || addr >= jctx->heap_begin + jctx->heap_size) return 0; BlockDesc *b = getblockbegin(addr); + DPrintf("#%d: GetJavaSync %p->%p\n", thr->tid, addr, b); Lock l(&b->mtx); SyncVar *s = b->head; for (; s; s = s->next) { - if (s->addr == addr) + if (s->addr == addr) { + DPrintf("#%d: found existing sync for %p\n", thr->tid, addr); break; + } } if (s == 0 && create) { + DPrintf("#%d: creating new sync for %p\n", thr->tid, addr); s = CTX()->synctab.Create(thr, pc, addr); s->next = b->head; b->head = s; @@ -233,8 +237,17 @@ void __tsan_java_move(jptr src, jptr dst, jptr size) { BlockDesc *d = getblock(dst); BlockDesc *send = getblock(src + size); for (; s != send; s++, d++) { + CHECK_EQ(d->begin, false); if (s->begin) { - new(d) BlockDesc(s); + DPrintf("#%d: moving block %p->%p\n", thr->tid, getmem(s), getmem(d)); + new(d) BlockDesc; + d->head = s->head; + for (SyncVar *sync = d->head; sync; sync = sync->next) { + uptr newaddr = sync->addr - src + dst; + DPrintf("#%d: moving sync %p->%p\n", thr->tid, sync->addr, newaddr); + sync->addr = newaddr; + } + s->head = 0; s->~BlockDesc(); } } |