Title: [157809] trunk/Source/_javascript_Core
- Revision
- 157809
- Author
- dba...@webkit.org
- Date
- 2013-10-22 13:40:34 -0700 (Tue, 22 Oct 2013)
Log Message
[iOS] Upstream JSLock changes
https://bugs.webkit.org/show_bug.cgi?id=123107
Reviewed by Geoffrey Garen.
* runtime/JSLock.cpp:
(JSC::JSLock::unlock):
(JSC::JSLock::dropAllLocks): Modified to take a SpinLock, used only on iOS.
(JSC::JSLock::dropAllLocksUnconditionally): Modified to take a SpinLock, used only on iOS. Also
use pre-increment instead of post-increment when we're not using the return value of the instruction.
(JSC::JSLock::grabAllLocks): Modified to take a SpinLock, used only on iOS. Also change
places where we were using post-increment/post-decrement to use pre-increment/pre-decrement,
since we don't use the return value of such instructions.
(JSC::JSLock::DropAllLocks::DropAllLocks): Modified to support releasing all locks unconditionally.
Take a spin lock before releasing all locks on iOS. Also, use nullptr instead of 0.
(JSC::JSLock::DropAllLocks::~DropAllLocks): Take a spin lock before acquiring all locks on iOS.
* runtime/JSLock.h: Remove extraneous argument name "exec" from DropAllLocks as the data type of
the argument is sufficiently descriptive of its purpose.
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (157808 => 157809)
--- trunk/Source/_javascript_Core/ChangeLog 2013-10-22 20:18:36 UTC (rev 157808)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-10-22 20:40:34 UTC (rev 157809)
@@ -1,3 +1,24 @@
+2013-10-22 Daniel Bates <daba...@apple.com>
+
+ [iOS] Upstream JSLock changes
+ https://bugs.webkit.org/show_bug.cgi?id=123107
+
+ Reviewed by Geoffrey Garen.
+
+ * runtime/JSLock.cpp:
+ (JSC::JSLock::unlock):
+ (JSC::JSLock::dropAllLocks): Modified to take a SpinLock, used only on iOS.
+ (JSC::JSLock::dropAllLocksUnconditionally): Modified to take a SpinLock, used only on iOS. Also
+ use pre-increment instead of post-increment when we're not using the return value of the instruction.
+ (JSC::JSLock::grabAllLocks): Modified to take a SpinLock, used only on iOS. Also change
+ places where we were using post-increment/post-decrement to use pre-increment/pre-decrement,
+ since we don't use the return value of such instructions.
+ (JSC::JSLock::DropAllLocks::DropAllLocks): Modified to support releasing all locks unconditionally.
+ Take a spin lock before releasing all locks on iOS. Also, use nullptr instead of 0.
+ (JSC::JSLock::DropAllLocks::~DropAllLocks): Take a spin lock before acquiring all locks on iOS.
+ * runtime/JSLock.h: Remove extraneous argument name "exec" from DropAllLocks as the data type of
+ the argument is sufficiently descriptive of its purpose.
+
2013-10-22 Julien Brianceau <jbria...@cisco.com>
[arm] Add missing setupArgumentsWithExecState() prototypes to fix build.
Modified: trunk/Source/_javascript_Core/runtime/JSLock.cpp (157808 => 157809)
--- trunk/Source/_javascript_Core/runtime/JSLock.cpp 2013-10-22 20:18:36 UTC (rev 157808)
+++ trunk/Source/_javascript_Core/runtime/JSLock.cpp 2013-10-22 20:40:34 UTC (rev 157809)
@@ -126,9 +126,9 @@
void JSLock::unlock()
{
+ SpinLockHolder holder(&m_spinLock);
ASSERT(currentThreadIsHoldingLock());
- SpinLockHolder holder(&m_spinLock);
m_lockCount--;
if (!m_lockCount)
@@ -192,51 +192,135 @@
//
// This function returns the number of locks that were dropped.
-unsigned JSLock::dropAllLocks()
+unsigned JSLock::dropAllLocks(SpinLock& spinLock)
{
+#if PLATFORM(IOS)
+ ASSERT_UNUSED(spinLock, spinLock.IsHeld());
+ // Check if this thread is currently holding the lock.
+ // FIXME: Maybe we want to require this, guard with an ASSERT?
+ unsigned lockCount = m_lockCount;
+ if (!lockCount || m_ownerThread != WTF::currentThread())
+ return 0;
+
+ // Don't drop the locks if they've already been dropped once.
+ // (If the prior drop came from another thread, and it resumed first,
+ // it could trash our register file).
+ if (m_lockDropDepth)
+ return 0;
+
+ // m_lockDropDepth is only incremented if any locks were dropped.
+ ++m_lockDropDepth;
+ m_lockCount = 0;
+ m_lock.unlock();
+ return lockCount;
+#else
if (m_lockDropDepth++)
return 0;
- return dropAllLocksUnconditionally();
+ return dropAllLocksUnconditionally(spinLock);
+#endif
}
-unsigned JSLock::dropAllLocksUnconditionally()
+unsigned JSLock::dropAllLocksUnconditionally(SpinLock& spinLock)
{
+#if PLATFORM(IOS)
+ ASSERT_UNUSED(spinLock, spinLock.IsHeld());
+ // Check if this thread is currently holding the lock.
+ // FIXME: Maybe we want to require this, guard with an ASSERT?
unsigned lockCount = m_lockCount;
- for (unsigned i = 0; i < lockCount; i++)
+ if (!lockCount || m_ownerThread != WTF::currentThread())
+ return 0;
+
+ // m_lockDropDepth is only incremented if any locks were dropped.
+ ++m_lockDropDepth;
+ m_lockCount = 0;
+ m_lock.unlock();
+ return lockCount;
+#else
+ UNUSED_PARAM(spinLock);
+ unsigned lockCount = m_lockCount;
+ for (unsigned i = 0; i < lockCount; ++i)
unlock();
return lockCount;
+#endif
}
-void JSLock::grabAllLocks(unsigned lockCount)
+void JSLock::grabAllLocks(unsigned lockCount, SpinLock& spinLock)
{
- for (unsigned i = 0; i < lockCount; i++)
+#if PLATFORM(IOS)
+ ASSERT(spinLock.IsHeld());
+ // If no locks were dropped, nothing to do!
+ if (!lockCount)
+ return;
+
+ ThreadIdentifier currentThread = WTF::currentThread();
+ // Check if this thread is currently holding the lock.
+ // FIXME: Maybe we want to prohibit this, guard against with an ASSERT?
+ if (m_ownerThread == currentThread && m_lockCount) {
+ m_lockCount += lockCount;
+ --m_lockDropDepth;
+ return;
+ }
+
+ spinLock.Unlock();
+ m_lock.lock();
+ spinLock.Lock();
+
+ m_ownerThread = currentThread;
+ ASSERT(!m_lockCount);
+ m_lockCount = lockCount;
+ --m_lockDropDepth;
+#else
+ UNUSED_PARAM(spinLock);
+ for (unsigned i = 0; i < lockCount; ++i)
lock();
- m_lockDropDepth--;
+ --m_lockDropDepth;
+#endif
}
-JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
+JSLock::DropAllLocks::DropAllLocks(ExecState* exec, AlwaysDropLocksTag alwaysDropLocks)
: m_lockCount(0)
- , m_vm(exec ? &exec->vm() : 0)
+ , m_vm(exec ? &exec->vm() : nullptr)
{
- if (m_vm)
- m_lockCount = m_vm->apiLock().dropAllLocks();
+ if (!m_vm)
+ return;
+ SpinLock& spinLock = m_vm->apiLock().m_spinLock;
+#if PLATFORM(IOS)
+ SpinLockHolder holder(&spinLock);
+#endif
+ if (alwaysDropLocks)
+ m_lockCount = m_vm->apiLock().dropAllLocksUnconditionally(spinLock);
+ else
+ m_lockCount = m_vm->apiLock().dropAllLocks(spinLock);
}
-JSLock::DropAllLocks::DropAllLocks(VM* vm)
+JSLock::DropAllLocks::DropAllLocks(VM* vm, AlwaysDropLocksTag alwaysDropLocks)
: m_lockCount(0)
, m_vm(vm)
{
- if (m_vm)
- m_lockCount = m_vm->apiLock().dropAllLocks();
+ if (!m_vm)
+ return;
+ SpinLock& spinLock = m_vm->apiLock().m_spinLock;
+#if PLATFORM(IOS)
+ SpinLockHolder holder(&spinLock);
+#endif
+ if (alwaysDropLocks)
+ m_lockCount = m_vm->apiLock().dropAllLocksUnconditionally(spinLock);
+ else
+ m_lockCount = m_vm->apiLock().dropAllLocks(spinLock);
}
JSLock::DropAllLocks::~DropAllLocks()
{
- if (m_vm)
- m_vm->apiLock().grabAllLocks(m_lockCount);
+ if (!m_vm)
+ return;
+ SpinLock& spinLock = m_vm->apiLock().m_spinLock;
+#if PLATFORM(IOS)
+ SpinLockHolder holder(&spinLock);
+#endif
+ m_vm->apiLock().grabAllLocks(m_lockCount, spinLock);
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSLock.h (157808 => 157809)
--- trunk/Source/_javascript_Core/runtime/JSLock.h 2013-10-22 20:18:36 UTC (rev 157808)
+++ trunk/Source/_javascript_Core/runtime/JSLock.h 2013-10-22 20:40:34 UTC (rev 157809)
@@ -95,17 +95,20 @@
JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
- unsigned dropAllLocks();
- unsigned dropAllLocksUnconditionally();
- void grabAllLocks(unsigned lockCount);
+ unsigned dropAllLocks(SpinLock&);
+ unsigned dropAllLocksUnconditionally(SpinLock&);
+ void grabAllLocks(unsigned lockCount, SpinLock&);
void willDestroyVM(VM*);
class DropAllLocks {
WTF_MAKE_NONCOPYABLE(DropAllLocks);
public:
- JS_EXPORT_PRIVATE DropAllLocks(ExecState* exec);
- JS_EXPORT_PRIVATE DropAllLocks(VM*);
+ // By default, we release all locks conditionally. Some clients, such as Mobile Safari,
+ // may require that we release all locks unconditionally.
+ enum AlwaysDropLocksTag { DontAlwaysDropLocks = 0, AlwaysDropLocks };
+ JS_EXPORT_PRIVATE DropAllLocks(ExecState*, AlwaysDropLocksTag = DontAlwaysDropLocks);
+ JS_EXPORT_PRIVATE DropAllLocks(VM*, AlwaysDropLocksTag = DontAlwaysDropLocks);
JS_EXPORT_PRIVATE ~DropAllLocks();
private:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes