Bug 202391

Summary: [JSC] Place VM* in TLS
Product: WebKit Reporter: Yusuke Suzuki <ysuzuki>
Component: New BugsAssignee: Yusuke Suzuki <ysuzuki>
Status: REOPENED    
Severity: Normal CC: achristensen, alecflett, beidson, benjamin, cdumez, cmarcelo, dbates, ews-watchlist, jsbell, keith_miller, mark.lam, msaboff, saam, tsavell, tzagallo, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
mark.lam: review+
Patch for landing none

Yusuke Suzuki
Reported 2019-09-30 22:36:17 PDT
[JSC] Place VM* in TLS
Attachments
Patch (9.23 KB, patch)
2019-09-30 22:36 PDT, Yusuke Suzuki
no flags
Patch (9.27 KB, patch)
2019-09-30 22:39 PDT, Yusuke Suzuki
no flags
Patch (9.27 KB, patch)
2019-09-30 22:40 PDT, Yusuke Suzuki
no flags
Patch (10.20 KB, patch)
2019-09-30 22:43 PDT, Yusuke Suzuki
no flags
Patch (12.77 KB, patch)
2019-10-01 13:53 PDT, Yusuke Suzuki
no flags
Patch (14.14 KB, patch)
2019-10-01 13:59 PDT, Yusuke Suzuki
mark.lam: review+
Patch for landing (14.26 KB, patch)
2019-10-01 14:29 PDT, Yusuke Suzuki
no flags
Yusuke Suzuki
Comment 1 2019-09-30 22:36:31 PDT
Yusuke Suzuki
Comment 2 2019-09-30 22:39:31 PDT
Yusuke Suzuki
Comment 3 2019-09-30 22:40:59 PDT
Yusuke Suzuki
Comment 4 2019-09-30 22:43:56 PDT
Mark Lam
Comment 5 2019-09-30 23:03:16 PDT
Comment on attachment 379879 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379879&action=review LGTM > Source/JavaScriptCore/runtime/JSLock.cpp:293 > + VM::exchange(nullptr); Maybe assert that the returned VM* == m_vm? > Source/JavaScriptCore/runtime/JSLock.cpp:311 > + VM::exchange(m_vm.get()); Assert that VM::exchange returns nullptr? > Source/JavaScriptCore/runtime/JSLock.h:91 > + friend class JSRunLoopTimer; Does JSRunLoopTimer really need to be a friend?
Mark Lam
Comment 6 2019-09-30 23:05:51 PDT
Looks like IDBBindingUtilities.cpp is being naughty and not using the JSLockHolder.
Keith Miller
Comment 7 2019-10-01 07:33:36 PDT
Comment on attachment 379879 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379879&action=review > Source/JavaScriptCore/runtime/VM.h:318 > + static constexpr pthread_key_t tlsKey = WTF_GC_TLC_KEY; Can we change this name? WTF_GC_TLC_KEY doesn't seem super accurate...
Yusuke Suzuki
Comment 8 2019-10-01 13:53:16 PDT
Yusuke Suzuki
Comment 9 2019-10-01 13:56:04 PDT
Comment on attachment 379879 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379879&action=review >> Source/JavaScriptCore/runtime/JSLock.cpp:293 >> + VM::exchange(nullptr); > > Maybe assert that the returned VM* == m_vm? Fixed. >> Source/JavaScriptCore/runtime/JSLock.cpp:311 >> + VM::exchange(m_vm.get()); > > Assert that VM::exchange returns nullptr? Fixed. >> Source/JavaScriptCore/runtime/JSLock.h:91 >> + friend class JSRunLoopTimer; > > Does JSRunLoopTimer really need to be a friend? Not necessary. Removed, nice. >> Source/JavaScriptCore/runtime/VM.h:318 >> + static constexpr pthread_key_t tlsKey = WTF_GC_TLC_KEY; > > Can we change this name? WTF_GC_TLC_KEY doesn't seem super accurate... Changed it to WTF_VM_KEY. Thanks.
Mark Lam
Comment 10 2019-10-01 13:57:53 PDT
Comment on attachment 379946 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379946&action=review > Source/JavaScriptCore/runtime/JSLock.cpp:90 > + VM::exchange(m_previousVMInTLS); // Change VM after unlocking. Otherwise, willReleaseLock will see previous VM. I suggest rephrasing this as "Change VM only after unlocking". I think that's what you meant.
Yusuke Suzuki
Comment 11 2019-10-01 13:59:14 PDT
Comment on attachment 379946 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379946&action=review >> Source/JavaScriptCore/runtime/JSLock.cpp:90 >> + VM::exchange(m_previousVMInTLS); // Change VM after unlocking. Otherwise, willReleaseLock will see previous VM. > > I suggest rephrasing this as "Change VM only after unlocking". I think that's what you meant. Fixed, thanks.
Yusuke Suzuki
Comment 12 2019-10-01 13:59:45 PDT
Mark Lam
Comment 13 2019-10-01 14:16:08 PDT
Comment on attachment 379947 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379947&action=review r=me with the ChangeLog fixed. > Source/JavaScriptCore/ChangeLog:10 > + And JSLockHolder's destructor restores it. Since DropAllLocks want to put `nullptr` in TLS, we place previous VM* > + in JSLockHolder itself. And now JSLock is only lockable by JSLockHolder. This part "Since DropAllLocks want to put `nullptr` in TLS, we place previous VM* in JSLockHolder itself." is not true. DropAllLocks knows the VM that it is dropping the lock for, and it doesn't interact with JSLockHolder, right? So, JSLockHolder::m_previousVMInTLS is not needed for this purpose. That said, let's say that we have 2 VM instances A and B, and that we were executing in A when it called a C++ host function. While still holding the JSLock for A, the thread now enters B. In this case, the TLS VM should be set to B, but when we exit, it should be restored to A. I think this is the reason for needing JSLockHolder::m_previousVMInTLS. This is also the reason why we should not generally use VM::current() as the source of truth of VM* rather than threading everywhere: it is only correct for some uses.
Yusuke Suzuki
Comment 14 2019-10-01 14:28:54 PDT
Comment on attachment 379947 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=379947&action=review Thanks! >> Source/JavaScriptCore/ChangeLog:10 >> + in JSLockHolder itself. And now JSLock is only lockable by JSLockHolder. > > This part "Since DropAllLocks want to put `nullptr` in TLS, we place previous VM* in JSLockHolder itself." is not true. DropAllLocks knows the VM that it is dropping the lock for, and it doesn't interact with JSLockHolder, right? So, JSLockHolder::m_previousVMInTLS is not needed for this purpose. > > That said, let's say that we have 2 VM instances A and B, and that we were executing in A when it called a C++ host function. While still holding the JSLock for A, the thread now enters B. In this case, the TLS VM should be set to B, but when we exit, it should be restored to A. I think this is the reason for needing JSLockHolder::m_previousVMInTLS. This is also the reason why we should not generally use VM::current() as the source of truth of VM* rather than threading everywhere: it is only correct for some uses. OK, fixed.
Yusuke Suzuki
Comment 15 2019-10-01 14:29:32 PDT
Created attachment 379951 [details] Patch for landing
Yusuke Suzuki
Comment 16 2019-10-01 15:21:46 PDT
Radar WebKit Bug Importer
Comment 17 2019-10-01 15:22:18 PDT
Alex Christensen
Comment 18 2019-10-01 19:51:58 PDT
Comment on attachment 379951 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=379951&action=review > Source/JavaScriptCore/runtime/JSLock.cpp:313 > + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS); This seems to assert in many debug tests https://build.webkit.org/builders/Apple%20Mojave%20Debug%20WK2%20(Tests)/builds/5020/steps/layout-test/logs/stdio
Yusuke Suzuki
Comment 19 2019-10-01 20:29:31 PDT
(In reply to Alex Christensen from comment #18) > Comment on attachment 379951 [details] > Patch for landing > > View in context: > https://bugs.webkit.org/attachment.cgi?id=379951&action=review > > > Source/JavaScriptCore/runtime/JSLock.cpp:313 > > + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS); > > This seems to assert in many debug tests > https://build.webkit.org/builders/Apple%20Mojave%20Debug%20WK2%20(Tests)/ > builds/5020/steps/layout-test/logs/stdio Looking.
Yusuke Suzuki
Comment 20 2019-10-01 20:30:01 PDT
Comment on attachment 379951 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=379951&action=review >>> Source/JavaScriptCore/runtime/JSLock.cpp:313 >>> + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS); >> >> This seems to assert in many debug tests >> https://build.webkit.org/builders/Apple%20Mojave%20Debug%20WK2%20(Tests)/builds/5020/steps/layout-test/logs/stdio > > Looking. This assertion should not be met. Removing.
Yusuke Suzuki
Comment 21 2019-10-01 20:41:23 PDT
Comment on attachment 379951 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=379951&action=review > Source/JavaScriptCore/runtime/JSLock.cpp:294 > + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS == m_vm.get()); I don't think this is guaranteed. At anytime, we can use DropAllLocks.
Yusuke Suzuki
Comment 22 2019-10-01 20:42:38 PDT
Comment on attachment 379951 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=379951&action=review >> Source/JavaScriptCore/runtime/JSLock.cpp:294 >> + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS == m_vm.get()); > > I don't think this is guaranteed. At anytime, we can use DropAllLocks. We should put VM* in m_previousVMInTLS field.
Yusuke Suzuki
Comment 23 2019-10-01 20:44:44 PDT
(In reply to Yusuke Suzuki from comment #22) > Comment on attachment 379951 [details] > Patch for landing > > View in context: > https://bugs.webkit.org/attachment.cgi?id=379951&action=review > > >> Source/JavaScriptCore/runtime/JSLock.cpp:294 > >> + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS == m_vm.get()); > > > > I don't think this is guaranteed. At anytime, we can use DropAllLocks. > > We should put VM* in m_previousVMInTLS field. Ah, no. After looking into DropAllLocks, it strongly assumes that VM is now used.
Yusuke Suzuki
Comment 24 2019-10-01 20:48:24 PDT
Saam Barati
Comment 25 2019-10-02 18:02:09 PDT
LGTM too with your assertion fix. Out of curiosity, if we make exec->vm() use this, do we get a speedup?
Saam Barati
Comment 26 2019-10-02 18:02:22 PDT
(In reply to Saam Barati from comment #25) > LGTM too with your assertion fix. > > Out of curiosity, if we make exec->vm() use this, do we get a speedup? (When FAST_TLS is enabled)
Truitt Savell
Comment 27 2019-10-04 08:34:11 PDT
Reverted r250594 for reason: Broke multiple internal API tests Committed r250724: <https://trac.webkit.org/changeset/250724>
Truitt Savell
Comment 28 2019-10-04 08:35:07 PDT
Reverted r250583 for reason: Broke multiple internal API tests Committed r250725: <https://trac.webkit.org/changeset/250725>
Yusuke Suzuki
Comment 29 2019-10-04 11:16:59 PDT
Comment on attachment 379951 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=379951&action=review >>>> Source/JavaScriptCore/runtime/JSLock.cpp:294 >>>> + ASSERT_UNUSED(previousVMInTLS, previousVMInTLS == m_vm.get()); >>> >>> I don't think this is guaranteed. At anytime, we can use DropAllLocks. >> >> We should put VM* in m_previousVMInTLS field. > > Ah, no. After looking into DropAllLocks, it strongly assumes that VM is now used. WebThread clients uses DropAllLocks even if they do not have a lock for VM. We should check m_droppedLockCount.
Note You need to log in before you can comment on or make changes to this bug.