Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (181480 => 181481)
--- trunk/Source/_javascript_Core/ChangeLog 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-03-13 18:02:40 UTC (rev 181481)
@@ -1,3 +1,20 @@
+2015-03-13 Mark Lam <[email protected]>
+
+ Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.
+ <https://webkit.org/b/142661>
+
+ Reviewed by Filip Pizlo.
+
+ Changed CodeBlock, and the DFG's crashLock to use WTF::Atomic instead of
+ std::atomic.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::visitAggregate):
+ * bytecode/CodeBlock.h:
+ * dfg/DFGCommon.cpp:
+ (JSC::DFG::startCrashing):
+
2015-03-12 Mark Lam <[email protected]>
Change the DFG crashLock to use std::atomic.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (181480 => 181481)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-03-13 18:02:40 UTC (rev 181481)
@@ -1645,7 +1645,6 @@
, m_isStrictMode(other.m_isStrictMode)
, m_needsActivation(other.m_needsActivation)
, m_mayBeExecuting(false)
- , m_visitAggregateHasBeenCalled(false)
, m_source(other.m_source)
, m_sourceOffset(other.m_sourceOffset)
, m_firstLineColumnOffset(other.m_firstLineColumnOffset)
@@ -1662,6 +1661,8 @@
, m_capabilityLevelState(DFG::CapabilityLevelNotSet)
#endif
{
+ m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+
ASSERT(m_heap->isDeferred());
ASSERT(m_scopeRegister.isLocal());
@@ -1707,7 +1708,6 @@
, m_isStrictMode(unlinkedCodeBlock->isStrictMode())
, m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
, m_mayBeExecuting(false)
- , m_visitAggregateHasBeenCalled(false)
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
, m_firstLineColumnOffset(firstLineColumnOffset)
@@ -1719,6 +1719,8 @@
, m_capabilityLevelState(DFG::CapabilityLevelNotSet)
#endif
{
+ m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+
ASSERT(m_heap->isDeferred());
ASSERT(m_scopeRegister.isLocal());
@@ -2202,8 +2204,7 @@
// I may be asked to scan myself more than once, and it may even happen concurrently.
// To this end, use an atomic operation to check (and set) if I've been called already.
// Only one thread may proceed past this point - whichever one wins the atomic set race.
- bool expected = false;
- bool setByMe = m_visitAggregateHasBeenCalled.compare_exchange_strong(expected, true, std::memory_order_acquire);
+ bool setByMe = m_visitAggregateHasBeenCalled.compare_exchange_strong(false, true, std::memory_order_acquire);
if (!setByMe)
return;
#endif // ENABLE(PARALLEL_GC)
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (181480 => 181481)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-03-13 18:02:40 UTC (rev 181481)
@@ -1065,7 +1065,7 @@
bool m_isStrictMode;
bool m_needsActivation;
bool m_mayBeExecuting;
- std::atomic<bool> m_visitAggregateHasBeenCalled;
+ Atomic<bool> m_visitAggregateHasBeenCalled;
RefPtr<SourceProvider> m_source;
unsigned m_sourceOffset;
Modified: trunk/Source/_javascript_Core/dfg/DFGCommon.cpp (181480 => 181481)
--- trunk/Source/_javascript_Core/dfg/DFGCommon.cpp 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/_javascript_Core/dfg/DFGCommon.cpp 2015-03-13 18:02:40 UTC (rev 181481)
@@ -34,15 +34,12 @@
namespace JSC { namespace DFG {
-static std::atomic<unsigned> crashLock;
+static Atomic<unsigned> crashLock;
void startCrashing()
{
- unsigned expected = 0;
- while (!crashLock.compare_exchange_weak(expected, 1, std::memory_order_acquire)) {
+ while (!crashLock.compare_exchange_weak(0, 1, std::memory_order_acquire))
std::this_thread::yield();
- expected = 0;
- }
}
bool isCrashing()
Modified: trunk/Source/WTF/ChangeLog (181480 => 181481)
--- trunk/Source/WTF/ChangeLog 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/WTF/ChangeLog 2015-03-13 18:02:40 UTC (rev 181481)
@@ -1,3 +1,31 @@
+2015-03-13 Mark Lam <[email protected]>
+
+ Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.
+ <https://webkit.org/b/142661>
+
+ Reviewed by Filip Pizlo.
+
+ The CAS functions provided by std::atomic takes a reference to the expected
+ value and modifies it if the CAS fails. However, in a lot of our CAS usage,
+ we don't want the expected value to change. The solution to this is to
+ provide a WTF::Atomic struct that wraps std::atomic, and provide CAS
+ methods that won't alter the expected value if the CAS fails.
+
+ The method names in WTF::Atomic are chosen to be identical to those
+ in std::atomic so that WTF::Atomic can be a simple drop in replacement
+ for std::atomic.
+
+ Also changed ByteSpinLock to use WTF::Atomic instead of std::atomic.
+
+ * wtf/Atomics.h:
+ (WTF::Atomic::load):
+ (WTF::Atomic::store):
+ (WTF::Atomic::compare_exchange_weak):
+ (WTF::Atomic::compare_exchange_strong):
+ * wtf/ByteSpinLock.h:
+ (WTF::ByteSpinLock::ByteSpinLock):
+ (WTF::ByteSpinLock::lock):
+
2015-03-12 Filip Pizlo <[email protected]>
Bytecode liveness analysis should have more lambdas and fewer sets
Modified: trunk/Source/WTF/wtf/Atomics.h (181480 => 181481)
--- trunk/Source/WTF/wtf/Atomics.h 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/WTF/wtf/Atomics.h 2015-03-13 18:02:40 UTC (rev 181481)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2010, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2008, 2010, 2012-2013, 2015 Apple Inc. All rights reserved.
* Copyright (C) 2007 Justin Haygood ([email protected])
*
* Redistribution and use in source and binary forms, with or without
@@ -59,6 +59,7 @@
#ifndef Atomics_h
#define Atomics_h
+#include <atomic>
#include <wtf/StdLibExtras.h>
#if OS(WINDOWS)
@@ -71,6 +72,35 @@
namespace WTF {
+// Atomic wraps around std::atomic with the sole purpose of making the compare_exchange
+// operations not alter the expected value. This is more in line with how we typically
+// use CAS in our code.
+//
+// Atomic is a struct without explicitly defined constructors so that it can be
+// initialized at compile time.
+
+template<typename T>
+struct Atomic {
+
+ T load(std::memory_order order) const { return value.load(order); }
+
+ void store(T desired, std::memory_order order) { value.store(desired, order); }
+
+ bool compare_exchange_weak(T expected, T desired, std::memory_order order)
+ {
+ T expectedOrActual = expected;
+ return value.compare_exchange_weak(expectedOrActual, desired, order);
+ }
+
+ bool compare_exchange_strong(T expected, T desired, std::memory_order order)
+ {
+ T expectedOrActual = expected;
+ return value.compare_exchange_strong(expectedOrActual, desired, order);
+ }
+
+ std::atomic<T> value;
+};
+
#if OS(WINDOWS)
inline bool weakCompareAndSwap(volatile unsigned* location, unsigned expected, unsigned newValue)
{
@@ -345,4 +375,6 @@
} // namespace WTF
+using WTF::Atomic;
+
#endif // Atomics_h
Modified: trunk/Source/WTF/wtf/ByteSpinLock.h (181480 => 181481)
--- trunk/Source/WTF/wtf/ByteSpinLock.h 2015-03-13 17:58:50 UTC (rev 181480)
+++ trunk/Source/WTF/wtf/ByteSpinLock.h 2015-03-13 18:02:40 UTC (rev 181481)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,9 +26,9 @@
#ifndef ByteSpinLock_h
#define ByteSpinLock_h
-#include <atomic>
#include <thread>
#include <wtf/Assertions.h>
+#include <wtf/Atomics.h>
#include <wtf/Locker.h>
#include <wtf/Noncopyable.h>
@@ -38,17 +38,14 @@
WTF_MAKE_NONCOPYABLE(ByteSpinLock);
public:
ByteSpinLock()
- : m_lock(false)
{
+ m_lock.store(false, std::memory_order_relaxed);
}
void lock()
{
- bool expected = false;
- while (!m_lock.compare_exchange_weak(expected, true, std::memory_order_acquire)) {
+ while (!m_lock.compare_exchange_weak(false, true, std::memory_order_acquire))
std::this_thread::yield();
- expected = false;
- }
}
void unlock()
@@ -59,7 +56,7 @@
bool isHeld() const { return m_lock.load(std::memory_order_acquire); }
private:
- std::atomic<bool> m_lock;
+ Atomic<bool> m_lock;
};
typedef Locker<ByteSpinLock> ByteSpinLocker;