Skip to content
  • oliver@apple.com's avatar
    fourthTier: all inline caches should thread-safe enough to allow a concurrent... · 0c1b13e9
    oliver@apple.com authored
    fourthTier: all inline caches should thread-safe enough to allow a concurrent compilation thread to read them safely
    https://bugs.webkit.org/show_bug.cgi?id=114762
    
    Source/JavaScriptCore:
    
    Reviewed by Mark Hahnenberg.
    
    For most inline caches this is easy: the inline cache has a clean temporal
    separation between doing the requested action (which may take an unbounded
    amount of time, may recurse, and may do arbitrary things) and recording the
    relevant information in the cache. So, we just put locks around the
    recording bit. That part is always O(1) and does not recurse. The lock we
    use is per-CodeBlock to achieve a good balance between locking granularity
    and low space overhead. So a concurrent compilation thread will only block
    if an inline cache ping-pongs in the code block being compiled (or inlined)
    and never when other inline caches do things.
    
    For resolve operations, it's a bit tricky. The global resolve bit works
    like any other IC in that it has the clean temporal separation. But the
    operations vector itself doesn't have this separation, since we will be
    filling it in tandem with actions that may take a long time. This patch
    gets around this by having a m_ready bit in the ResolveOperations and
    PutToBaseOperation. This is set while holding the CodeBlock's lock. If the
    DFG observes the m_ready bit not set (while holding the lock) then it
    conservatively assumes that the resolve hasn't happened yet and just
    plants a ForceOSRExit.
    
    * bytecode/CallLinkStatus.cpp:
    (JSC::CallLinkStatus::computeFor):
    * bytecode/CodeBlock.h:
    (CodeBlock):
    * bytecode/GetByIdStatus.cpp:
    (JSC::GetByIdStatus::computeFor):
    * bytecode/PutByIdStatus.cpp:
    (JSC::PutByIdStatus::computeFor):
    * bytecode/ResolveGlobalStatus.cpp:
    (JSC::ResolveGlobalStatus::computeFor):
    * bytecode/ResolveOperation.h:
    (JSC::ResolveOperations::ResolveOperations):
    (ResolveOperations):
    (JSC::PutToBaseOperation::PutToBaseOperation):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::parseResolveOperations):
    (JSC::DFG::ByteCodeParser::parseBlock):
    * jit/JITStubs.cpp:
    (JSC::tryCachePutByID):
    (JSC::tryCacheGetByID):
    (JSC::DEFINE_STUB_FUNCTION):
    (JSC::lazyLinkFor):
    * llint/LLIntSlowPaths.cpp:
    (JSC::LLInt::LLINT_SLOW_PATH_DECL):
    (JSC::LLInt::setUpCall):
    * runtime/JSScope.cpp:
    (JSC::JSScope::resolveContainingScopeInternal):
    (JSC::JSScope::resolveContainingScope):
    (JSC::JSScope::resolvePut):
    
    Source/WTF:
    
    Reviewed by Mark Hahnenberg.
    
    Implemented a new spinlock that is optimized for compactness, by using just a byte.
    This will be useful as we start using fine-grained locking on a bunch of places.
    
    At some point I'll make these byte-sized spinlocks into adaptive mutexes, but for
    now I think it's fine to do the evil thing and use spinning particularly since we
    only use them for short critical sections.
    
    * WTF.xcodeproj/project.pbxproj:
    * wtf/Atomics.h:
    (WTF):
    (WTF::weakCompareAndSwap):
    * wtf/ByteSpinLock.h: Added.
    (WTF):
    (ByteSpinLock):
    (WTF::ByteSpinLock::ByteSpinLock):
    (WTF::ByteSpinLock::lock):
    (WTF::ByteSpinLock::unlock):
    (WTF::ByteSpinLock::isHeld):
    * wtf/ThreadingPrimitives.h:
    (WTF::pauseBriefly):
    (WTF):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153122 268f45cc-cd09-0410-ab3c-d52691b4dbfc
    0c1b13e9