From aeubanks at google.com Tue Sep 3 21:34:30 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Tue, 3 Sep 2019 14:34:30 -0700 Subject: RFR: Finalizer support Message-ID: webrev: http://cr.openjdk.java.net/~aeubanks/tsanfinalizer/webrev.00/ This patch makes the finalizer thread call __tsan_java_finalize(), preventing reports of false positives in finalizers. From jcbeyler at google.com Mon Sep 9 22:26:28 2019 From: jcbeyler at google.com (Jean Christophe Beyler) Date: Mon, 9 Sep 2019 15:26:28 -0700 Subject: RFR: Finalizer support In-Reply-To: References: Message-ID: Took me a while to get to this, my apologies Arthur :) I looks good to me! Jc On Tue, Sep 3, 2019 at 2:45 PM Arthur Eubanks wrote: > webrev: http://cr.openjdk.java.net/~aeubanks/tsanfinalizer/webrev.00/ > > This patch makes the finalizer thread call __tsan_java_finalize(), > preventing reports of false positives in finalizers. > -- Thanks, Jc From manc at google.com Tue Sep 10 01:03:10 2019 From: manc at google.com (Man Cao) Date: Mon, 9 Sep 2019 18:03:10 -0700 Subject: RFR: Finalizer support In-Reply-To: References: Message-ID: Apology for the delay. I don't see how the TSAN code is guarded by the build-time option. Does it work with "--with-jvm-features=-tsan". For checking whether TSAN is enabled, is it possible to use the following directly? Then we don't need to change jvm.h/cpp and symbols-unix. ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+ThreadSanitizer"); In Finalizer.java private static boolean TSAN_ENABLED = isTsanEnabled(); It is better to mark TSAN_ENABLED field as "final". if (TSAN_ENABLED) { tsanFinalize(); } I think we can keep the TODO for this code, that it could be moved to when a batch of finalizers was queued. In Finalizer.c, should it add this line? #include "java_lang_ref_Finalizer.h" I see other files in the directory have includes for corresponding .h files. In NonRacyFinalizerLoopTest.java: * @build AbstractLoop TsanRunner public static void main(String[] args) throws InterruptedException { We can remove "AbstractLoop" and "throws InterruptedException", right? -Man On Mon, Sep 9, 2019 at 3:27 PM Jean Christophe Beyler wrote: > Took me a while to get to this, my apologies Arthur :) > > I looks good to me! > Jc > > On Tue, Sep 3, 2019 at 2:45 PM Arthur Eubanks wrote: > > > webrev: http://cr.openjdk.java.net/~aeubanks/tsanfinalizer/webrev.00/ > > > > This patch makes the finalizer thread call __tsan_java_finalize(), > > preventing reports of false positives in finalizers. > > > > > -- > > Thanks, > Jc > From manc at google.com Tue Sep 10 01:34:15 2019 From: manc at google.com (Man Cao) Date: Mon, 9 Sep 2019 18:34:15 -0700 Subject: RFR: Finalizer support In-Reply-To: References: Message-ID: > For checking whether TSAN is enabled, is it possible to use the following directly? Then we don't need to change jvm.h/cpp and symbols-unix. > ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+ThreadSanitizer"); I take it back. It is a bad practice to depend on string matching here. And it would incorrectly return true for "java -XX:+ThreadSanitizer -XX:-ThreadSanitizer Foo". -Man On Mon, Sep 9, 2019 at 6:03 PM Man Cao wrote: > Apology for the delay. > > I don't see how the TSAN code is guarded by the build-time option. Does it > work with "--with-jvm-features=-tsan". > > For checking whether TSAN is enabled, is it possible to use the following > directly? Then we don't need to change jvm.h/cpp and symbols-unix. > > ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+ThreadSanitizer"); > > In Finalizer.java > private static boolean TSAN_ENABLED = isTsanEnabled(); > It is better to mark TSAN_ENABLED field as "final". > > if (TSAN_ENABLED) { > tsanFinalize(); > } > I think we can keep the TODO for this code, that it could be moved to > when a batch of finalizers was queued. > > In Finalizer.c, should it add this line? > #include "java_lang_ref_Finalizer.h" > I see other files in the directory have includes for corresponding .h > files. > > In NonRacyFinalizerLoopTest.java: > * @build AbstractLoop TsanRunner > > public static void main(String[] args) throws InterruptedException { > > We can remove "AbstractLoop" and "throws InterruptedException", right? > > > -Man > > > On Mon, Sep 9, 2019 at 3:27 PM Jean Christophe Beyler > wrote: > >> Took me a while to get to this, my apologies Arthur :) >> >> I looks good to me! >> Jc >> >> On Tue, Sep 3, 2019 at 2:45 PM Arthur Eubanks >> wrote: >> >> > webrev: http://cr.openjdk.java.net/~aeubanks/tsanfinalizer/webrev.00/ >> > >> > This patch makes the finalizer thread call __tsan_java_finalize(), >> > preventing reports of false positives in finalizers. >> > >> >> >> -- >> >> Thanks, >> Jc >> > From aeubanks at google.com Thu Sep 12 18:50:53 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Thu, 12 Sep 2019 11:50:53 -0700 Subject: RFR: Finalizer support In-Reply-To: References: Message-ID: On Mon, Sep 9, 2019 at 6:03 PM Man Cao wrote: > Apology for the delay. > > I don't see how the TSAN code is guarded by the build-time option. Does it > work with "--with-jvm-features=-tsan". > Fixed by adding a NOT_TSAN macro and only returning ThreadSanitizer when TSAN is enabled as a JVM feature, else always return false. Made sure it compiled with --with-jvm-features=-tsan. > > For checking whether TSAN is enabled, is it possible to use the following > directly? Then we don't need to change jvm.h/cpp and symbols-unix. > > ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+ThreadSanitizer"); > > In Finalizer.java > private static boolean TSAN_ENABLED = isTsanEnabled(); > It is better to mark TSAN_ENABLED field as "final". > Done. > > if (TSAN_ENABLED) { > tsanFinalize(); > } > I think we can keep the TODO for this code, that it could be moved to > when a batch of finalizers was queued. > Done. > > > In Finalizer.c, should it add this line? > #include "java_lang_ref_Finalizer.h" > I see other files in the directory have includes for corresponding .h > files. > Done. > > In NonRacyFinalizerLoopTest.java: > * @build AbstractLoop TsanRunner > > public static void main(String[] args) throws InterruptedException { > > We can remove "AbstractLoop" and "throws InterruptedException", right? > > Removed AbstractLoop. TsanRunner.runTsanTestExpectSuccess() throws an IOException, threw that instead. > > -Man > New webrev: http://cr.openjdk.java.net/~aeubanks/tsanfinalizer/webrev.01/ Thanks for the thorough review! From manc at google.com Thu Sep 12 19:55:09 2019 From: manc at google.com (Man Cao) Date: Thu, 12 Sep 2019 12:55:09 -0700 Subject: RFR: Finalizer support In-Reply-To: References: Message-ID: Looks good! Thanks for fixing. -Man On Thu, Sep 12, 2019 at 11:51 AM Arthur Eubanks wrote: > > > On Mon, Sep 9, 2019 at 6:03 PM Man Cao wrote: > >> Apology for the delay. >> >> I don't see how the TSAN code is guarded by the build-time option. Does >> it work with "--with-jvm-features=-tsan". >> > Fixed by adding a NOT_TSAN macro and only returning ThreadSanitizer when > TSAN is enabled as a JVM feature, else always return false. > Made sure it compiled with --with-jvm-features=-tsan. > >> >> For checking whether TSAN is enabled, is it possible to use the following >> directly? Then we don't need to change jvm.h/cpp and symbols-unix. >> >> ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+ThreadSanitizer"); >> >> In Finalizer.java >> private static boolean TSAN_ENABLED = isTsanEnabled(); >> It is better to mark TSAN_ENABLED field as "final". >> > Done. > >> >> if (TSAN_ENABLED) { >> tsanFinalize(); >> } >> I think we can keep the TODO for this code, that it could be moved to >> when a batch of finalizers was queued. >> > Done. > >> >> >> In Finalizer.c, should it add this line? >> #include "java_lang_ref_Finalizer.h" >> I see other files in the directory have includes for corresponding .h >> files. >> > Done. > >> >> In NonRacyFinalizerLoopTest.java: >> * @build AbstractLoop TsanRunner >> >> public static void main(String[] args) throws InterruptedException { >> >> We can remove "AbstractLoop" and "throws InterruptedException", right? >> >> Removed AbstractLoop. > TsanRunner.runTsanTestExpectSuccess() throws an IOException, threw that > instead. > >> >> -Man >> > > New webrev: http://cr.openjdk.java.net/~aeubanks/tsanfinalizer/webrev.01/ > Thanks for the thorough review! > From aeubanks at google.com Thu Sep 12 20:32:54 2019 From: aeubanks at google.com (aeubanks at google.com) Date: Thu, 12 Sep 2019 20:32:54 +0000 Subject: hg: tsan/dev: Don't mark finalizers as racy due to running in a different thread Message-ID: <201909122032.x8CKWsnD013844@aojmv0008.oracle.com> Changeset: ee18163ecd60 Author: aeubanks Date: 2019-09-03 14:30 -0700 URL: https://hg.openjdk.java.net/tsan/dev/rev/ee18163ecd60 Don't mark finalizers as racy due to running in a different thread "There is a happens-before edge from the end of a constructor of an object to the start of a finalizer for that object." This change is too coarse and will have false negatives, but this is a relatively simple solution that gets rid of false positives. ! make/hotspot/symbols/symbols-unix ! src/hotspot/share/include/jvm.h ! src/hotspot/share/prims/jvm.cpp ! src/hotspot/share/utilities/macros.hpp ! src/java.base/share/classes/java/lang/ref/Finalizer.java + src/java.base/share/native/libjava/Finalizer.c + test/hotspot/jtreg/tsan/NonRacyFinalizerLoopTest.java From aeubanks at google.com Tue Sep 17 16:34:23 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Tue, 17 Sep 2019 09:34:23 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get Message-ID: webrev: http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html This change adds instrumentation for the interpreter Unsafe implementation, only for Unsafe_{Get,Put}{Reference,primitive}. Other Unsafe instrumentation will come later. From aeubanks at google.com Tue Sep 17 16:36:37 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Tue, 17 Sep 2019 09:36:37 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get In-Reply-To: References: Message-ID: Forgot to mention: This does slow down usage of Unsafe in the interpreter when the TSAN feature is enabled at compile time, but since the interpreter is so slow, it doesn't matter anyway. C1/C2 have their own implementation of Unsafe, so those should not be affected. On Tue, Sep 17, 2019 at 9:34 AM Arthur Eubanks wrote: > webrev: > http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html > > This change adds instrumentation for the interpreter Unsafe > implementation, only for Unsafe_{Get,Put}{Reference,primitive}. Other > Unsafe instrumentation will come later. > From manc at google.com Wed Sep 18 23:34:21 2019 From: manc at google.com (Man Cao) Date: Wed, 18 Sep 2019 16:34:21 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get In-Reply-To: References: Message-ID: For Unsafe_GetReference/Unsafe_PutReference, do you really need the backslashes "\" for code within TSAN_RUNTIME_ONLY? In Unsafe_GetReference: void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); "JNIHandles::resolve(obj)" could be replaced with "p", right? For RacyUnsafe*Test, the stack trace check could be a bit more relaxed to avoid flaky tests. E.g. in RacyUnsafePutIntLoopTest.java: .shouldContain(" #1 sun.misc.Unsafe.getInt(Ljava/lang/Object;J)I Unsafe.java:"); could become: .shouldMatch(" #1 sun.misc.Unsafe.(get|put)Int\(Ljava/lang/Object;JI?)I? Unsafe.java:"); In RacyUnsafePutStringLoopTest.java, Character.toString(c) may not create new String object or change the reference value of the field x. Can we update the value of the character as in the original test, so it changes? I.e. char c = (char) (x.charAt(0) + 1); Nits: 337 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ 338 TSAN_RUNTIME_ONLY( \ 339 void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \ 340 __tsan_write##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)) \ 341 ); \ Missing a ";" after __tsan_write##size##_pc. Indention for "void* addr = ..." is off. In AbstractLoop.java: * The second thread calls this method, defaults to calling run(). I think the original comments for run() and run2() are better: For run(): Implement only this method for symmetric behavior. For run2(): Override this method for asymmetric behavior. -Man On Tue, Sep 17, 2019 at 9:37 AM Arthur Eubanks wrote: > Forgot to mention: > This does slow down usage of Unsafe in the interpreter when the TSAN > feature is enabled at compile time, but since the interpreter is so slow, > it doesn't matter anyway. C1/C2 have their own implementation of Unsafe, so > those should not be affected. > > On Tue, Sep 17, 2019 at 9:34 AM Arthur Eubanks > wrote: > > > webrev: > > > http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html > > > > This change adds instrumentation for the interpreter Unsafe > > implementation, only for Unsafe_{Get,Put}{Reference,primitive}. Other > > Unsafe instrumentation will come later. > > > From aeubanks at google.com Thu Sep 19 16:52:38 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Thu, 19 Sep 2019 09:52:38 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get In-Reply-To: References: Message-ID: New webrev: http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.01/index.html On Wed, Sep 18, 2019 at 4:34 PM Man Cao wrote: > For Unsafe_GetReference/Unsafe_PutReference, do you really need the > backslashes "\" for code within TSAN_RUNTIME_ONLY? > > In Unsafe_GetReference: > void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), > offset); > "JNIHandles::resolve(obj)" could be replaced with "p", right? > Done > > For RacyUnsafe*Test, the stack trace check could be a bit more relaxed to > avoid flaky tests. E.g. in RacyUnsafePutIntLoopTest.java: > .shouldContain(" #1 sun.misc.Unsafe.getInt(Ljava/lang/Object;J)I > Unsafe.java:"); > could become: > .shouldMatch(" #1 sun.misc.Unsafe.(get|put)Int\(Ljava/lang/Object;JI?)I? > Unsafe.java:"); > I separated put and get into their own tests. I also made run() synchronized, and did the normal read/write in run2() synchronized, so the only racy access is the Unsafe access in run2() and the accesses in run(). > > > In RacyUnsafePutStringLoopTest.java, Character.toString(c) may not create > new String object or change the reference value of the field x. > Can we update the value of the character as in the original test, so it > changes? I.e. char c = (char) (x.charAt(0) + 1); > I don't think it matters, right? Anyway, changed it. > > > Nits: > > 337 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ 338 TSAN_RUNTIME_ONLY( \ 339 void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \ 340 __tsan_write##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)) \ 341 ); \ > > Missing a ";" after __tsan_write##size##_pc. > Indention for "void* addr = ..." is off. > Done > > In AbstractLoop.java: > * The second thread calls this method, defaults to calling run(). > I think the original comments for run() and run2() are better: > For run(): Implement only this method for symmetric behavior. > For run2(): Override this method for asymmetric behavior. > Done > > -Man > > > On Tue, Sep 17, 2019 at 9:37 AM Arthur Eubanks > wrote: > >> Forgot to mention: >> This does slow down usage of Unsafe in the interpreter when the TSAN >> feature is enabled at compile time, but since the interpreter is so slow, >> it doesn't matter anyway. C1/C2 have their own implementation of Unsafe, >> so >> those should not be affected. >> >> On Tue, Sep 17, 2019 at 9:34 AM Arthur Eubanks >> wrote: >> >> > webrev: >> > >> http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html >> > >> > This change adds instrumentation for the interpreter Unsafe >> > implementation, only for Unsafe_{Get,Put}{Reference,primitive}. Other >> > Unsafe instrumentation will come later. >> > > > From manc at google.com Thu Sep 19 18:18:36 2019 From: manc at google.com (Man Cao) Date: Thu, 19 Sep 2019 11:18:36 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get In-Reply-To: References: Message-ID: Looks good. Thanks for improving the tests! -Man On Thu, Sep 19, 2019 at 9:52 AM Arthur Eubanks wrote: > New webrev: > http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.01/index.html > > On Wed, Sep 18, 2019 at 4:34 PM Man Cao wrote: > >> For Unsafe_GetReference/Unsafe_PutReference, do you really need the >> backslashes "\" for code within TSAN_RUNTIME_ONLY? >> >> In Unsafe_GetReference: >> void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), >> offset); >> "JNIHandles::resolve(obj)" could be replaced with "p", right? >> > Done > >> >> For RacyUnsafe*Test, the stack trace check could be a bit more relaxed to >> avoid flaky tests. E.g. in RacyUnsafePutIntLoopTest.java: >> .shouldContain(" #1 sun.misc.Unsafe.getInt(Ljava/lang/Object;J)I >> Unsafe.java:"); >> could become: >> .shouldMatch(" #1 sun.misc.Unsafe.(get|put)Int\(Ljava/lang/Object;JI?)I? >> Unsafe.java:"); >> > I separated put and get into their own tests. I also made run() > synchronized, and did the normal read/write in run2() synchronized, so the > only racy access is the Unsafe access in run2() and the accesses in run(). > >> >> >> In RacyUnsafePutStringLoopTest.java, Character.toString(c) may not create >> new String object or change the reference value of the field x. >> Can we update the value of the character as in the original test, so it >> changes? I.e. char c = (char) (x.charAt(0) + 1); >> > I don't think it matters, right? Anyway, changed it. > >> >> >> Nits: >> >> 337 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ 338 TSAN_RUNTIME_ONLY( \ 339 void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \ 340 __tsan_write##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)) \ 341 ); \ >> >> Missing a ";" after __tsan_write##size##_pc. >> Indention for "void* addr = ..." is off. >> > Done > >> >> In AbstractLoop.java: >> * The second thread calls this method, defaults to calling run(). >> I think the original comments for run() and run2() are better: >> For run(): Implement only this method for symmetric behavior. >> For run2(): Override this method for asymmetric behavior. >> > Done > >> >> -Man >> >> >> On Tue, Sep 17, 2019 at 9:37 AM Arthur Eubanks >> wrote: >> >>> Forgot to mention: >>> This does slow down usage of Unsafe in the interpreter when the TSAN >>> feature is enabled at compile time, but since the interpreter is so slow, >>> it doesn't matter anyway. C1/C2 have their own implementation of Unsafe, >>> so >>> those should not be affected. >>> >>> On Tue, Sep 17, 2019 at 9:34 AM Arthur Eubanks >>> wrote: >>> >>> > webrev: >>> > >>> http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html >>> > >>> > This change adds instrumentation for the interpreter Unsafe >>> > implementation, only for Unsafe_{Get,Put}{Reference,primitive}. Other >>> > Unsafe instrumentation will come later. >>> > >> >> From jcbeyler at google.com Thu Sep 19 18:55:54 2019 From: jcbeyler at google.com (Jean Christophe Beyler) Date: Thu, 19 Sep 2019 11:55:54 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get In-Reply-To: References: Message-ID: Hi Arthur, Tiny nit: http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.01/src/hotspot/share/prims/unsafe.cpp.udiff.html There is a: + } else { \ that is not needed in Unsafe_GetReference. Apart from that : LGTM && great job :), Jc On Thu, Sep 19, 2019 at 11:19 AM Man Cao wrote: > Looks good. Thanks for improving the tests! > > -Man > > > On Thu, Sep 19, 2019 at 9:52 AM Arthur Eubanks > wrote: > > > New webrev: > > > http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.01/index.html > > > > On Wed, Sep 18, 2019 at 4:34 PM Man Cao wrote: > > > >> For Unsafe_GetReference/Unsafe_PutReference, do you really need the > >> backslashes "\" for code within TSAN_RUNTIME_ONLY? > >> > >> In Unsafe_GetReference: > >> void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), > >> offset); > >> "JNIHandles::resolve(obj)" could be replaced with "p", right? > >> > > Done > > > >> > >> For RacyUnsafe*Test, the stack trace check could be a bit more relaxed > to > >> avoid flaky tests. E.g. in RacyUnsafePutIntLoopTest.java: > >> .shouldContain(" #1 sun.misc.Unsafe.getInt(Ljava/lang/Object;J)I > >> Unsafe.java:"); > >> could become: > >> .shouldMatch(" #1 sun.misc.Unsafe.(get|put)Int\(Ljava/lang/Object;JI?)I? > >> Unsafe.java:"); > >> > > I separated put and get into their own tests. I also made run() > > synchronized, and did the normal read/write in run2() synchronized, so > the > > only racy access is the Unsafe access in run2() and the accesses in > run(). > > > >> > >> > >> In RacyUnsafePutStringLoopTest.java, Character.toString(c) may not > create > >> new String object or change the reference value of the field x. > >> Can we update the value of the character as in the original test, so it > >> changes? I.e. char c = (char) (x.charAt(0) + 1); > >> > > I don't think it matters, right? Anyway, changed it. > > > >> > >> > >> Nits: > >> > >> 337 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, > jobject obj, jlong offset, java_type x)) { \ 338 TSAN_RUNTIME_ONLY( \ > 339 void* addr = > index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \ 340 > __tsan_write##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)) \ > 341 ); \ > >> > >> Missing a ";" after __tsan_write##size##_pc. > >> Indention for "void* addr = ..." is off. > >> > > Done > > > >> > >> In AbstractLoop.java: > >> * The second thread calls this method, defaults to calling run(). > >> I think the original comments for run() and run2() are better: > >> For run(): Implement only this method for symmetric behavior. > >> For run2(): Override this method for asymmetric behavior. > >> > > Done > > > >> > >> -Man > >> > >> > >> On Tue, Sep 17, 2019 at 9:37 AM Arthur Eubanks > >> wrote: > >> > >>> Forgot to mention: > >>> This does slow down usage of Unsafe in the interpreter when the TSAN > >>> feature is enabled at compile time, but since the interpreter is so > slow, > >>> it doesn't matter anyway. C1/C2 have their own implementation of > Unsafe, > >>> so > >>> those should not be affected. > >>> > >>> On Tue, Sep 17, 2019 at 9:34 AM Arthur Eubanks > >>> wrote: > >>> > >>> > webrev: > >>> > > >>> > http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html > >>> > > >>> > This change adds instrumentation for the interpreter Unsafe > >>> > implementation, only for Unsafe_{Get,Put}{Reference,primitive}. Other > >>> > Unsafe instrumentation will come later. > >>> > > >> > >> > -- Thanks, Jc From aeubanks at google.com Thu Sep 19 20:13:10 2019 From: aeubanks at google.com (aeubanks at google.com) Date: Thu, 19 Sep 2019 20:13:10 +0000 Subject: hg: tsan/dev: Instrument normal Unsafe puts and gets Message-ID: <201909192013.x8JKDBdW013577@aojmv0008.oracle.com> Changeset: 1824d8e5b993 Author: aeubanks Date: 2019-09-17 09:05 -0700 URL: https://hg.openjdk.java.net/tsan/dev/rev/1824d8e5b993 Instrument normal Unsafe puts and gets ! src/hotspot/share/prims/unsafe.cpp ! test/hotspot/jtreg/tsan/AbstractLoop.java + test/hotspot/jtreg/tsan/NonRacyUnsafeLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetBooleanLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetByteLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetCharLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetDoubleLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetFloatLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetIntLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetLongLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetShortLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafeGetStringLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutBooleanLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutByteLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutCharLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutDoubleLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutFloatLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutIntLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutLongLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutShortLoopTest.java + test/hotspot/jtreg/tsan/RacyUnsafePutStringLoopTest.java + test/hotspot/jtreg/tsan/UnsafeUtil.java From aeubanks at google.com Thu Sep 19 20:13:05 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Thu, 19 Sep 2019 13:13:05 -0700 Subject: [RFR] Instrumentation for basic Unsafe put/get In-Reply-To: References: Message-ID: On Thu, Sep 19, 2019 at 11:56 AM Jean Christophe Beyler wrote: > Hi Arthur, > > Tiny nit: > > http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.01/src/hotspot/share/prims/unsafe.cpp.udiff.html > > There is a: > + } else { \ > > that is not needed in Unsafe_GetReference. > Done and pushed. > > Apart from that : LGTM && great job :), > Jc > > > > On Thu, Sep 19, 2019 at 11:19 AM Man Cao wrote: > >> Looks good. Thanks for improving the tests! >> >> -Man >> >> >> On Thu, Sep 19, 2019 at 9:52 AM Arthur Eubanks >> wrote: >> >> > New webrev: >> > >> http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.01/index.html >> > >> > On Wed, Sep 18, 2019 at 4:34 PM Man Cao wrote: >> > >> >> For Unsafe_GetReference/Unsafe_PutReference, do you really need the >> >> backslashes "\" for code within TSAN_RUNTIME_ONLY? >> >> >> >> In Unsafe_GetReference: >> >> void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), >> >> offset); >> >> "JNIHandles::resolve(obj)" could be replaced with "p", right? >> >> >> > Done >> > >> >> >> >> For RacyUnsafe*Test, the stack trace check could be a bit more relaxed >> to >> >> avoid flaky tests. E.g. in RacyUnsafePutIntLoopTest.java: >> >> .shouldContain(" #1 sun.misc.Unsafe.getInt(Ljava/lang/Object;J)I >> >> Unsafe.java:"); >> >> could become: >> >> .shouldMatch(" #1 >> sun.misc.Unsafe.(get|put)Int\(Ljava/lang/Object;JI?)I? >> >> Unsafe.java:"); >> >> >> > I separated put and get into their own tests. I also made run() >> > synchronized, and did the normal read/write in run2() synchronized, so >> the >> > only racy access is the Unsafe access in run2() and the accesses in >> run(). >> > >> >> >> >> >> >> In RacyUnsafePutStringLoopTest.java, Character.toString(c) may not >> create >> >> new String object or change the reference value of the field x. >> >> Can we update the value of the character as in the original test, so it >> >> changes? I.e. char c = (char) (x.charAt(0) + 1); >> >> >> > I don't think it matters, right? Anyway, changed it. >> > >> >> >> >> >> >> Nits: >> >> >> >> 337 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, >> jobject obj, jlong offset, java_type x)) { \ 338 TSAN_RUNTIME_ONLY( \ >> 339 void* addr = >> index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \ 340 >> __tsan_write##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)) \ >> 341 ); \ >> >> >> >> Missing a ";" after __tsan_write##size##_pc. >> >> Indention for "void* addr = ..." is off. >> >> >> > Done >> > >> >> >> >> In AbstractLoop.java: >> >> * The second thread calls this method, defaults to calling run(). >> >> I think the original comments for run() and run2() are better: >> >> For run(): Implement only this method for symmetric behavior. >> >> For run2(): Override this method for asymmetric behavior. >> >> >> > Done >> > >> >> >> >> -Man >> >> >> >> >> >> On Tue, Sep 17, 2019 at 9:37 AM Arthur Eubanks >> >> wrote: >> >> >> >>> Forgot to mention: >> >>> This does slow down usage of Unsafe in the interpreter when the TSAN >> >>> feature is enabled at compile time, but since the interpreter is so >> slow, >> >>> it doesn't matter anyway. C1/C2 have their own implementation of >> Unsafe, >> >>> so >> >>> those should not be affected. >> >>> >> >>> On Tue, Sep 17, 2019 at 9:34 AM Arthur Eubanks >> >>> wrote: >> >>> >> >>> > webrev: >> >>> > >> >>> >> http://cr.openjdk.java.net/~aeubanks/tsannormalunsafe/webrev.00/index.html >> >>> > >> >>> > This change adds instrumentation for the interpreter Unsafe >> >>> > implementation, only for Unsafe_{Get,Put}{Reference,primitive}. >> Other >> >>> > Unsafe instrumentation will come later. >> >>> > >> >> >> >> >> > > > -- > > Thanks, > Jc > From aeubanks at google.com Fri Sep 20 15:39:25 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Fri, 20 Sep 2019 08:39:25 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get Message-ID: webrev: http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html I also added a test that normal volatile accesses (not through unsafe) are not considered racy, since we didn't have a test for that before. From manc at google.com Fri Sep 20 18:10:17 2019 From: manc at google.com (Man Cao) Date: Fri, 20 Sep 2019 11:10:17 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get In-Reply-To: References: Message-ID: In unsafe.cpp: Calls to __tsan_java_acquire and __tsan_java_release should be swapped. I.e., Get*Volatile should use __tsan_java_acquire, and Put*Volatile should use __tsan_java_release. I think the tests should check that proper use of volatile establishes happens-before, instead of "no race on volatile access". E.g.: volatile byte b = 0; int data = 0; T1: data = 42; b = 1; T2: while (b == 0); int t = data; In NonRacyUnsafeVolatileLoopTest.java: private byte b = 0x42; Should this field be "volatile"? -Man On Fri, Sep 20, 2019 at 8:40 AM Arthur Eubanks wrote: > webrev: > > http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html > > I also added a test that normal volatile accesses (not through unsafe) are > not considered racy, since we didn't have a test for that before. > From aeubanks at google.com Fri Sep 20 20:12:14 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Fri, 20 Sep 2019 13:12:14 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get In-Reply-To: References: Message-ID: On Fri, Sep 20, 2019 at 11:10 AM Man Cao wrote: > In unsafe.cpp: > Calls to __tsan_java_acquire and __tsan_java_release should be swapped. > I.e., Get*Volatile should use __tsan_java_acquire, and Put*Volatile should > use __tsan_java_release. > Oof sorry, bad mistake, fixed. Writing the tests below actually helped catch that. > > I think the tests should check that proper use of volatile establishes > happens-before, instead of "no race on volatile access". E.g.: > > volatile byte b = 0; > int data = 0; > T1: > data = 42; > b = 1; > > T2: > while (b == 0); > int t = data; > Done. Added some functionality to AbstractLoop.java to properly do this. > > In NonRacyUnsafeVolatileLoopTest.java: > > private byte b = 0x42; > > Should this field be "volatile"? > I don't believe these need to be volatile, just the access itself needs to be volatile. volatile is a property of a specific memory access, not a field. Martin agrees. > -Man > > > > On Fri, Sep 20, 2019 at 8:40 AM Arthur Eubanks > wrote: > >> webrev: >> >> http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html >> >> I also added a test that normal volatile accesses (not through unsafe) are >> not considered racy, since we didn't have a test for that before. >> > From aeubanks at google.com Fri Sep 20 20:14:49 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Fri, 20 Sep 2019 13:14:49 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get In-Reply-To: References: Message-ID: New webrev: http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.01/index.html On Fri, Sep 20, 2019 at 1:12 PM Arthur Eubanks wrote: > > > On Fri, Sep 20, 2019 at 11:10 AM Man Cao wrote: > >> In unsafe.cpp: >> Calls to __tsan_java_acquire and __tsan_java_release should be swapped. >> I.e., Get*Volatile should use __tsan_java_acquire, and Put*Volatile should >> use __tsan_java_release. >> > Oof sorry, bad mistake, fixed. Writing the tests below actually helped > catch that. > >> >> I think the tests should check that proper use of volatile establishes >> happens-before, instead of "no race on volatile access". E.g.: >> >> volatile byte b = 0; >> int data = 0; >> T1: >> data = 42; >> b = 1; >> >> T2: >> while (b == 0); >> int t = data; >> > Done. Added some functionality to AbstractLoop.java to properly do this. > >> >> In NonRacyUnsafeVolatileLoopTest.java: >> >> private byte b = 0x42; >> >> Should this field be "volatile"? >> > I don't believe these need to be volatile, just the access itself needs to > be volatile. volatile is a property of a specific memory access, not a > field. Martin agrees. > >> -Man >> >> >> >> On Fri, Sep 20, 2019 at 8:40 AM Arthur Eubanks >> wrote: >> >>> webrev: >>> >>> http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html >>> >>> I also added a test that normal volatile accesses (not through unsafe) >>> are >>> not considered racy, since we didn't have a test for that before. >>> >> From manc at google.com Sat Sep 21 00:34:18 2019 From: manc at google.com (Man Cao) Date: Fri, 20 Sep 2019 17:34:18 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get In-Reply-To: References: Message-ID: Looks good. No need for new webrev for following nits: Is this change necessary? - // Default constructors will call this- AbstractLoop() {++ public AbstractLoop() { I'm not a fan of the names "runInTwoThreadsSync" and "syncSetup". There is no obvious extra synchronization compared to runInTwoThreads(). Maybe "runOnceInTwoThreads" and "runOnceSetup" are better? Another option might be to create a subclass of AbstractLoop, which overrides runInTwoThreads(). But I don't insist on adding the subclass and it's up to you. There could be comments for "runInTwoThreads" and "runOnceInTwoThreads" to document their differences. -Man On Fri, Sep 20, 2019 at 1:15 PM Arthur Eubanks wrote: > New webrev: > http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.01/index.html > > On Fri, Sep 20, 2019 at 1:12 PM Arthur Eubanks > wrote: > >> >> >> On Fri, Sep 20, 2019 at 11:10 AM Man Cao wrote: >> >>> In unsafe.cpp: >>> Calls to __tsan_java_acquire and __tsan_java_release should be swapped. >>> I.e., Get*Volatile should use __tsan_java_acquire, and Put*Volatile should >>> use __tsan_java_release. >>> >> Oof sorry, bad mistake, fixed. Writing the tests below actually helped >> catch that. >> >>> >>> I think the tests should check that proper use of volatile establishes >>> happens-before, instead of "no race on volatile access". E.g.: >>> >>> volatile byte b = 0; >>> int data = 0; >>> T1: >>> data = 42; >>> b = 1; >>> >>> T2: >>> while (b == 0); >>> int t = data; >>> >> Done. Added some functionality to AbstractLoop.java to properly do this. >> >>> >>> In NonRacyUnsafeVolatileLoopTest.java: >>> >>> private byte b = 0x42; >>> >>> Should this field be "volatile"? >>> >> I don't believe these need to be volatile, just the access itself needs >> to be volatile. volatile is a property of a specific memory access, not a >> field. Martin agrees. >> >>> -Man >>> >>> >>> >>> On Fri, Sep 20, 2019 at 8:40 AM Arthur Eubanks >>> wrote: >>> >>>> webrev: >>>> >>>> http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html >>>> >>>> I also added a test that normal volatile accesses (not through unsafe) >>>> are >>>> not considered racy, since we didn't have a test for that before. >>>> >>> From aeubanks at google.com Mon Sep 23 15:28:09 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Mon, 23 Sep 2019 08:28:09 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get In-Reply-To: References: Message-ID: On Fri, Sep 20, 2019 at 5:34 PM Man Cao wrote: > Looks good. No need for new webrev for following nits: > > Is this change necessary? > > - // Default constructors will call this- AbstractLoop() {++ public AbstractLoop() { > > I don't see why we should restrict it to a specific package. > I'm not a fan of the names "runInTwoThreadsSync" and "syncSetup". There is > no obvious extra synchronization compared to runInTwoThreads(). > It's equivalent to adding a barrier at the end of each iteration in each thread (I think). > Maybe "runOnceInTwoThreads" and "runOnceSetup" are better? > I initially sort of liked this, but "once" is clearly not right, the whole point of the setup is that it's run multiple times. I think I'll keep the name for now. If somebody wants to change the name in the future, go for it. > Another option might be to create a subclass of AbstractLoop, which > overrides runInTwoThreads(). But I don't insist on adding the subclass and > it's up to you. > That seems very confusing. I think separating it out into two different methods is clearer. > There could be comments for "runInTwoThreads" and "runOnceInTwoThreads" to > document their differences. > Done. > > -Man > > > On Fri, Sep 20, 2019 at 1:15 PM Arthur Eubanks > wrote: > >> New webrev: >> http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.01/index.html >> >> On Fri, Sep 20, 2019 at 1:12 PM Arthur Eubanks >> wrote: >> >>> >>> >>> On Fri, Sep 20, 2019 at 11:10 AM Man Cao wrote: >>> >>>> In unsafe.cpp: >>>> Calls to __tsan_java_acquire and __tsan_java_release should be swapped. >>>> I.e., Get*Volatile should use __tsan_java_acquire, and Put*Volatile should >>>> use __tsan_java_release. >>>> >>> Oof sorry, bad mistake, fixed. Writing the tests below actually helped >>> catch that. >>> >>>> >>>> I think the tests should check that proper use of volatile establishes >>>> happens-before, instead of "no race on volatile access". E.g.: >>>> >>>> volatile byte b = 0; >>>> int data = 0; >>>> T1: >>>> data = 42; >>>> b = 1; >>>> >>>> T2: >>>> while (b == 0); >>>> int t = data; >>>> >>> Done. Added some functionality to AbstractLoop.java to properly do this. >>> >>>> >>>> In NonRacyUnsafeVolatileLoopTest.java: >>>> >>>> private byte b = 0x42; >>>> >>>> Should this field be "volatile"? >>>> >>> I don't believe these need to be volatile, just the access itself needs >>> to be volatile. volatile is a property of a specific memory access, not a >>> field. Martin agrees. >>> >>>> -Man >>>> >>>> >>>> >>>> On Fri, Sep 20, 2019 at 8:40 AM Arthur Eubanks >>>> wrote: >>>> >>>>> webrev: >>>>> >>>>> http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html >>>>> >>>>> I also added a test that normal volatile accesses (not through unsafe) >>>>> are >>>>> not considered racy, since we didn't have a test for that before. >>>>> >>>> From aeubanks at google.com Mon Sep 23 19:51:16 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Mon, 23 Sep 2019 12:51:16 -0700 Subject: [RFR] Instrumentation for Unsafe CAS Message-ID: webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html This is fairly self explanatory. I went down the route of using a C++ class's constructor/destructor for the release/acquire so I didn't have to touch the existing code too much. From aeubanks at google.com Mon Sep 23 21:29:20 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Mon, 23 Sep 2019 14:29:20 -0700 Subject: [RFR] Instrumentation for Unsafe CAS In-Reply-To: References: Message-ID: As discussed with Man offline, index_oop_from_field_offset_long() probably works in all cases, so I removed the version of ScopedReleaseAcquire that calls AccessInternal::field_addr(). http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.01/index.html On Mon, Sep 23, 2019 at 12:51 PM Arthur Eubanks wrote: > webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html > > This is fairly self explanatory. I went down the route of using a C++ > class's constructor/destructor for the release/acquire so I didn't have to > touch the existing code too much. > From manc at google.com Mon Sep 23 21:30:20 2019 From: manc at google.com (Man Cao) Date: Mon, 23 Sep 2019 14:30:20 -0700 Subject: [RFR] Instrumentation for Unsafe CAS In-Reply-To: References: Message-ID: My main comment is: + ScopedReleaseAcquire(oop obj, ptrdiff_t offset): addr_(AccessInternal::field_addr(obj, offset)) { This could use "index_oop_from_field_offset_long(obj, offset)", right? Also discussed with Arthur that when TSAN is disabled at build-time, the code would still create the ScopedReleaseAcquire object, but hopefully the C++ compiler will optimize out no-op objects. Minor comments: +class ScopedReleaseAcquire {+private:+ void* addr_; This class should inherit from "public StackObj". HotSpot style guide says instance variable name should start with _, so "_addr". -Man On Mon, Sep 23, 2019 at 12:52 PM Arthur Eubanks wrote: > webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html > > This is fairly self explanatory. I went down the route of using a C++ > class's constructor/destructor for the release/acquire so I didn't have to > touch the existing code too much. > From aeubanks at google.com Mon Sep 23 21:50:33 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Mon, 23 Sep 2019 14:50:33 -0700 Subject: [RFR] Instrumentation for Unsafe CAS In-Reply-To: References: Message-ID: New webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.02 On Mon, Sep 23, 2019 at 2:30 PM Man Cao wrote: > My main comment is: > > + ScopedReleaseAcquire(oop obj, ptrdiff_t offset): addr_(AccessInternal::field_addr(obj, offset)) { > > This could use "index_oop_from_field_offset_long(obj, offset)", right? > > Went back to the original version but used index_oop_from_field_offset_long() instead of AccessInternal::field_addr(). > Also discussed with Arthur that when TSAN is disabled at build-time, the code would still create the ScopedReleaseAcquire object, but hopefully the C++ compiler will optimize out no-op objects. > > Minor comments: > > +class ScopedReleaseAcquire {+private:+ void* addr_; > > This class should inherit from "public StackObj". > > Done > HotSpot style guide says instance variable name should start with _, so "_addr". > > Done > -Man > > > > On Mon, Sep 23, 2019 at 12:52 PM Arthur Eubanks > wrote: > >> webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html >> >> This is fairly self explanatory. I went down the route of using a C++ >> class's constructor/destructor for the release/acquire so I didn't have to >> touch the existing code too much. >> > From manc at google.com Mon Sep 23 21:58:43 2019 From: manc at google.com (Man Cao) Date: Mon, 23 Sep 2019 14:58:43 -0700 Subject: [RFR] Instrumentation for Unsafe CAS In-Reply-To: References: Message-ID: Looks good. Last nit, no need for webrev: ScopedReleaseAcquire(oop obj, ptrdiff_t offset) { This could use "jlong offset" now. -Man On Mon, Sep 23, 2019 at 2:50 PM Arthur Eubanks wrote: > New webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.02 > > On Mon, Sep 23, 2019 at 2:30 PM Man Cao wrote: > >> My main comment is: >> >> + ScopedReleaseAcquire(oop obj, ptrdiff_t offset): addr_(AccessInternal::field_addr(obj, offset)) { >> >> This could use "index_oop_from_field_offset_long(obj, offset)", right? >> >> Went back to the original version but used > index_oop_from_field_offset_long() instead of AccessInternal::field_addr(). > >> Also discussed with Arthur that when TSAN is disabled at build-time, the code would still create the ScopedReleaseAcquire object, but hopefully the C++ compiler will optimize out no-op objects. >> >> Minor comments: >> >> +class ScopedReleaseAcquire {+private:+ void* addr_; >> >> This class should inherit from "public StackObj". >> >> Done > >> HotSpot style guide says instance variable name should start with _, so "_addr". >> >> Done > >> -Man >> >> >> >> On Mon, Sep 23, 2019 at 12:52 PM Arthur Eubanks >> wrote: >> >>> webrev: >>> http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html >>> >>> This is fairly self explanatory. I went down the route of using a C++ >>> class's constructor/destructor for the release/acquire so I didn't have >>> to >>> touch the existing code too much. >>> >> From aeubanks at google.com Mon Sep 23 22:10:34 2019 From: aeubanks at google.com (Arthur Eubanks) Date: Mon, 23 Sep 2019 15:10:34 -0700 Subject: [RFR] Instrumentation for Unsafe CAS In-Reply-To: References: Message-ID: On Mon, Sep 23, 2019 at 2:58 PM Man Cao wrote: > Looks good. > Last nit, no need for webrev: > > ScopedReleaseAcquire(oop obj, ptrdiff_t offset) { > > This could use "jlong offset" now. > > Done. > -Man > > > > On Mon, Sep 23, 2019 at 2:50 PM Arthur Eubanks > wrote: > >> New webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.02 >> >> On Mon, Sep 23, 2019 at 2:30 PM Man Cao wrote: >> >>> My main comment is: >>> >>> + ScopedReleaseAcquire(oop obj, ptrdiff_t offset): addr_(AccessInternal::field_addr(obj, offset)) { >>> >>> This could use "index_oop_from_field_offset_long(obj, offset)", right? >>> >>> Went back to the original version but used >> index_oop_from_field_offset_long() instead of AccessInternal::field_addr(). >> >>> Also discussed with Arthur that when TSAN is disabled at build-time, the code would still create the ScopedReleaseAcquire object, but hopefully the C++ compiler will optimize out no-op objects. >>> >>> Minor comments: >>> >>> +class ScopedReleaseAcquire {+private:+ void* addr_; >>> >>> This class should inherit from "public StackObj". >>> >>> Done >> >>> HotSpot style guide says instance variable name should start with _, so "_addr". >>> >>> Done >> >>> -Man >>> >>> >>> >>> On Mon, Sep 23, 2019 at 12:52 PM Arthur Eubanks >>> wrote: >>> >>>> webrev: >>>> http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html >>>> >>>> This is fairly self explanatory. I went down the route of using a C++ >>>> class's constructor/destructor for the release/acquire so I didn't have >>>> to >>>> touch the existing code too much. >>>> >>> From jcbeyler at google.com Mon Sep 23 22:16:36 2019 From: jcbeyler at google.com (Jean Christophe Beyler) Date: Mon, 23 Sep 2019 15:16:36 -0700 Subject: [RFR] Instrumentation for Unsafe volatile put/get In-Reply-To: References: Message-ID: Hi Arthur, Version 01 looks good to me :) Jc On Mon, Sep 23, 2019 at 8:29 AM Arthur Eubanks wrote: > On Fri, Sep 20, 2019 at 5:34 PM Man Cao wrote: > > > Looks good. No need for new webrev for following nits: > > > > Is this change necessary? > > > > - // Default constructors will call this- AbstractLoop() {++ public > AbstractLoop() { > > > > I don't see why we should restrict it to a specific package. > > > I'm not a fan of the names "runInTwoThreadsSync" and "syncSetup". There > is > > no obvious extra synchronization compared to runInTwoThreads(). > > > It's equivalent to adding a barrier at the end of each iteration in each > thread (I think). > > > Maybe "runOnceInTwoThreads" and "runOnceSetup" are better? > > > I initially sort of liked this, but "once" is clearly not right, the whole > point of the setup is that it's run multiple times. I think I'll keep the > name for now. If somebody wants to change the name in the future, go for > it. > > > Another option might be to create a subclass of AbstractLoop, which > > overrides runInTwoThreads(). But I don't insist on adding the subclass > and > > it's up to you. > > > That seems very confusing. I think separating it out into two different > methods is clearer. > > > There could be comments for "runInTwoThreads" and "runOnceInTwoThreads" > to > > document their differences. > > > Done. > > > > > -Man > > > > > > On Fri, Sep 20, 2019 at 1:15 PM Arthur Eubanks > > wrote: > > > >> New webrev: > >> > http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.01/index.html > >> > >> On Fri, Sep 20, 2019 at 1:12 PM Arthur Eubanks > >> wrote: > >> > >>> > >>> > >>> On Fri, Sep 20, 2019 at 11:10 AM Man Cao wrote: > >>> > >>>> In unsafe.cpp: > >>>> Calls to __tsan_java_acquire and __tsan_java_release should be > swapped. > >>>> I.e., Get*Volatile should use __tsan_java_acquire, and Put*Volatile > should > >>>> use __tsan_java_release. > >>>> > >>> Oof sorry, bad mistake, fixed. Writing the tests below actually helped > >>> catch that. > >>> > >>>> > >>>> I think the tests should check that proper use of volatile establishes > >>>> happens-before, instead of "no race on volatile access". E.g.: > >>>> > >>>> volatile byte b = 0; > >>>> int data = 0; > >>>> T1: > >>>> data = 42; > >>>> b = 1; > >>>> > >>>> T2: > >>>> while (b == 0); > >>>> int t = data; > >>>> > >>> Done. Added some functionality to AbstractLoop.java to properly do > this. > >>> > >>>> > >>>> In NonRacyUnsafeVolatileLoopTest.java: > >>>> > >>>> private byte b = 0x42; > >>>> > >>>> Should this field be "volatile"? > >>>> > >>> I don't believe these need to be volatile, just the access itself needs > >>> to be volatile. volatile is a property of a specific memory access, > not a > >>> field. Martin agrees. > >>> > >>>> -Man > >>>> > >>>> > >>>> > >>>> On Fri, Sep 20, 2019 at 8:40 AM Arthur Eubanks > >>>> wrote: > >>>> > >>>>> webrev: > >>>>> > >>>>> > http://cr.openjdk.java.net/~aeubanks/tsanvolatileunsafe/webrev.00/index.html > >>>>> > >>>>> I also added a test that normal volatile accesses (not through > unsafe) > >>>>> are > >>>>> not considered racy, since we didn't have a test for that before. > >>>>> > >>>> > -- Thanks, Jc From aeubanks at google.com Mon Sep 23 22:21:16 2019 From: aeubanks at google.com (aeubanks at google.com) Date: Mon, 23 Sep 2019 22:21:16 +0000 Subject: hg: tsan/dev: Instrument unsafe volatile memory accesses Message-ID: <201909232221.x8NMLG6j013144@aojmv0008.oracle.com> Changeset: 0ba46d34c0be Author: aeubanks Date: 2019-09-20 08:33 -0700 URL: https://hg.openjdk.java.net/tsan/dev/rev/0ba46d34c0be Instrument unsafe volatile memory accesses ! src/hotspot/share/prims/unsafe.cpp ! test/hotspot/jtreg/tsan/AbstractLoop.java + test/hotspot/jtreg/tsan/NonRacyUnsafeVolatileLoopTest.java + test/hotspot/jtreg/tsan/NonRacyVolatileLoopTest.java From jcbeyler at google.com Mon Sep 23 22:24:15 2019 From: jcbeyler at google.com (Jean Christophe Beyler) Date: Mon, 23 Sep 2019 15:24:15 -0700 Subject: [RFR] Instrumentation for Unsafe CAS In-Reply-To: References: Message-ID: Hi Man, Looks good to me too :) Jc On Mon, Sep 23, 2019 at 3:12 PM Arthur Eubanks wrote: > On Mon, Sep 23, 2019 at 2:58 PM Man Cao wrote: > > > Looks good. > > Last nit, no need for webrev: > > > > ScopedReleaseAcquire(oop obj, ptrdiff_t offset) { > > > > This could use "jlong offset" now. > > > > Done. > > > -Man > > > > > > > > On Mon, Sep 23, 2019 at 2:50 PM Arthur Eubanks > > wrote: > > > >> New webrev: http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.02 > >> > >> On Mon, Sep 23, 2019 at 2:30 PM Man Cao wrote: > >> > >>> My main comment is: > >>> > >>> + ScopedReleaseAcquire(oop obj, ptrdiff_t offset): > addr_(AccessInternal::field_addr(obj, offset)) { > >>> > >>> This could use "index_oop_from_field_offset_long(obj, offset)", right? > >>> > >>> Went back to the original version but used > >> index_oop_from_field_offset_long() instead of > AccessInternal::field_addr(). > >> > >>> Also discussed with Arthur that when TSAN is disabled at build-time, > the code would still create the ScopedReleaseAcquire object, but hopefully > the C++ compiler will optimize out no-op objects. > >>> > >>> Minor comments: > >>> > >>> +class ScopedReleaseAcquire {+private:+ void* addr_; > >>> > >>> This class should inherit from "public StackObj". > >>> > >>> Done > >> > >>> HotSpot style guide < > https://wiki.openjdk.java.net/display/HotSpot/StyleGuide#StyleGuide-Names> > says instance variable name should start with _, so "_addr". > >>> > >>> Done > >> > >>> -Man > >>> > >>> > >>> > >>> On Mon, Sep 23, 2019 at 12:52 PM Arthur Eubanks > >>> wrote: > >>> > >>>> webrev: > >>>> http://cr.openjdk.java.net/~aeubanks/tsancas/webrev.00/index.html > >>>> > >>>> This is fairly self explanatory. I went down the route of using a C++ > >>>> class's constructor/destructor for the release/acquire so I didn't > have > >>>> to > >>>> touch the existing code too much. > >>>> > >>> > -- Thanks, Jc From aeubanks at google.com Mon Sep 23 22:25:54 2019 From: aeubanks at google.com (aeubanks at google.com) Date: Mon, 23 Sep 2019 22:25:54 +0000 Subject: hg: tsan/dev: Instrument Unsafe CAS Message-ID: <201909232225.x8NMPsIQ017219@aojmv0008.oracle.com> Changeset: 78018a0c84f8 Author: aeubanks Date: 2019-09-23 12:35 -0700 URL: https://hg.openjdk.java.net/tsan/dev/rev/78018a0c84f8 Instrument Unsafe CAS ! src/hotspot/share/prims/unsafe.cpp + test/hotspot/jtreg/tsan/NonRacyCasLoopTest.java