Summary: | Fix uses of Dependency::fence with respect to the compiler outsmarting us | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | Saam Barati <saam> | ||||||||
Component: | JavaScriptCore | Assignee: | Saam Barati <saam> | ||||||||
Status: | RESOLVED FIXED | ||||||||||
Severity: | Normal | CC: | benjamin, cdumez, cmarcelo, ews-watchlist, keith_miller, mark.lam, msaboff, rmorisset, tzagallo, webkit-bug-importer | ||||||||
Priority: | P2 | Keywords: | InRadar | ||||||||
Version: | WebKit Nightly Build | ||||||||||
Hardware: | Unspecified | ||||||||||
OS: | Unspecified | ||||||||||
Attachments: |
|
Description
Saam Barati
2021-07-07 11:22:00 PDT
Been looking into this since yesterday. Adding more logging. Current status is that I'm pretty confused, and not sure what's going on. My logging is indicating something different than what the verifier is saying. Some of my logging is saying an object is marked or that we're marking it, but the verifier is disagreeing Still getting some weird data. We're seeing a cell that is marked, but then somehow the verifier sees it as unmarked when it look at the normal mark bits. Need to spend some more time verifying that this is actually what's happening, because it's very peculiar. Issue seems to go away if I turn off parallel marking constraint solver (In reply to Saam Barati from comment #4) > Issue seems to go away if I turn off parallel marking constraint solver This is wrong. It doesn't go away. But it becomes less common. What I'm seeing is truly bizarre at this point. Starting to look into the low level details. We're seeing an isMarked check return true then return false for the same object, inside the same function. Like: if (visitor.isMarked(this)) { // do some things RELEASE_ASSERT(visitor.isMarked(this)); // <---- crashes!!!! } Created attachment 433916 [details]
patch I'm using to test
The only change needed to apply to ToT to get things to crash is: Index: Source/JavaScriptCore/bytecode/CodeBlock.cpp =================================================================== --- Source/JavaScriptCore/bytecode/CodeBlock.cpp (revision 280124) +++ Source/JavaScriptCore/bytecode/CodeBlock.cpp (working copy) @@ -1214,8 +1214,16 @@ void CodeBlock::determineLiveness(const #if ENABLE(DFG_JIT) VM& vm = *m_vm; - if (visitor.isMarked(this)) + if (visitor.isMarked(this)) { + WTF::compilerFence(); + if (!visitor.isMarked(this)) { + dataLogLn("bit flip, crashing"); + dataLogLn(); + RELEASE_ASSERT_NOT_REACHED(); + } + return; + } // In rare and weird cases, this could be called on a baseline CodeBlock. One that I found was // that we might decide that the CodeBlock should be jettisoned due to old age, so the Created attachment 433981 [details]
patch
Comment on attachment 433981 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=433981&action=review > Source/WTF/wtf/Atomics.h:439 > + static Dependency loadAndFence(T* pointer, T& output) I could also change the API to be pair based instead of using an out parameter. Comment on attachment 433981 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=433981&action=review r=me > Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp:-170 > -JSValue SparseArrayEntry::getConcurrently() const I'm a bit surprised that you had to remove const here. Could this be fixed by also having a version of loadAndFence that takes a const T* ? >> Source/WTF/wtf/Atomics.h:439 >> + static Dependency loadAndFence(T* pointer, T& output) > > I could also change the API to be pair based instead of using an out parameter. It would be cleaner, but considering that this is going to be on very hot paths, and my lack of trust in LLVM's abilitiy to optimize a struct return type, I'm in favor of sticking with the out param. Comment on attachment 433981 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=433981&action=review >> Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp:-170 >> -JSValue SparseArrayEntry::getConcurrently() const > > I'm a bit surprised that you had to remove const here. > Could this be fixed by also having a version of loadAndFence that takes a const T* ? Good point. I think it'll be as easy as taking 'const T*' in that function. >>> Source/WTF/wtf/Atomics.h:439 >>> + static Dependency loadAndFence(T* pointer, T& output) >> >> I could also change the API to be pair based instead of using an out parameter. > > It would be cleaner, but considering that this is going to be on very hot paths, and my lack of trust in LLVM's abilitiy to optimize a struct return type, I'm in favor of sticking with the out param. ok, I'll leave it as is for now. Created attachment 434025 [details]
patch for landing
Committed r280195 (239883@main): <https://commits.webkit.org/239883@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 434025 [details]. |