Remove unused atomic utils

The removed building blocks have either been completely unused or have
already been replaced.

Bug: 
Change-Id: I68a4d5d42b7f1cc3c5f8d0e7ea7146c5a0f59048
Reviewed-on: https://chromium-review.googlesource.com/612163
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47304}
This commit is contained in:
Michael Lippautz 2017-08-11 11:16:31 +02:00 committed by Commit Bot
parent d9a036317c
commit f3d48f56a8
4 changed files with 12 additions and 289 deletions

View File

@ -54,61 +54,6 @@ class AtomicNumber {
base::AtomicWord value_;
};
// This type uses no barrier accessors to change atomic word. Be careful with
// data races.
template <typename T>
class NoBarrierAtomicValue {
public:
NoBarrierAtomicValue() : value_(0) {}
explicit NoBarrierAtomicValue(T initial)
: value_(cast_helper<T>::to_storage_type(initial)) {}
static NoBarrierAtomicValue* FromAddress(void* address) {
return reinterpret_cast<base::NoBarrierAtomicValue<T>*>(address);
}
V8_INLINE bool TrySetValue(T old_value, T new_value) {
return base::Relaxed_CompareAndSwap(
&value_, cast_helper<T>::to_storage_type(old_value),
cast_helper<T>::to_storage_type(new_value)) ==
cast_helper<T>::to_storage_type(old_value);
}
V8_INLINE T Value() const {
return cast_helper<T>::to_return_type(base::Relaxed_Load(&value_));
}
V8_INLINE void SetValue(T new_value) {
base::Relaxed_Store(&value_, cast_helper<T>::to_storage_type(new_value));
}
private:
STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
template <typename S>
struct cast_helper {
static base::AtomicWord to_storage_type(S value) {
return static_cast<base::AtomicWord>(value);
}
static S to_return_type(base::AtomicWord value) {
return static_cast<S>(value);
}
};
template <typename S>
struct cast_helper<S*> {
static base::AtomicWord to_storage_type(S* value) {
return reinterpret_cast<base::AtomicWord>(value);
}
static S* to_return_type(base::AtomicWord value) {
return reinterpret_cast<S*>(value);
}
};
base::AtomicWord value_;
};
// Flag using T atomically. Also accepts void* as T.
template <typename T>
class AtomicValue {
@ -175,82 +120,6 @@ class AtomicValue {
base::AtomicWord value_;
};
// See utils.h for EnumSet. Storage is always base::AtomicWord.
// Requirements on E:
// - No explicit values.
// - E::kLastValue defined to be the last actually used value.
//
// Example:
// enum E { kA, kB, kC, kLastValue = kC };
template <class E>
class AtomicEnumSet {
public:
explicit AtomicEnumSet(base::AtomicWord bits = 0) : bits_(bits) {}
bool IsEmpty() const { return ToIntegral() == 0; }
bool Contains(E element) const { return (ToIntegral() & Mask(element)) != 0; }
bool ContainsAnyOf(const AtomicEnumSet& set) const {
return (ToIntegral() & set.ToIntegral()) != 0;
}
void RemoveAll() { base::Release_Store(&bits_, 0); }
bool operator==(const AtomicEnumSet& set) const {
return ToIntegral() == set.ToIntegral();
}
bool operator!=(const AtomicEnumSet& set) const {
return ToIntegral() != set.ToIntegral();
}
AtomicEnumSet<E> operator|(const AtomicEnumSet& set) const {
return AtomicEnumSet<E>(ToIntegral() | set.ToIntegral());
}
// The following operations modify the underlying storage.
#define ATOMIC_SET_WRITE(OP, NEW_VAL) \
do { \
base::AtomicWord old; \
do { \
old = base::Acquire_Load(&bits_); \
} while (base::Release_CompareAndSwap(&bits_, old, old OP NEW_VAL) != \
old); \
} while (false)
void Add(E element) { ATOMIC_SET_WRITE(|, Mask(element)); }
void Add(const AtomicEnumSet& set) { ATOMIC_SET_WRITE(|, set.ToIntegral()); }
void Remove(E element) { ATOMIC_SET_WRITE(&, ~Mask(element)); }
void Remove(const AtomicEnumSet& set) {
ATOMIC_SET_WRITE(&, ~set.ToIntegral());
}
void Intersect(const AtomicEnumSet& set) {
ATOMIC_SET_WRITE(&, set.ToIntegral());
}
#undef ATOMIC_SET_OP
private:
// Check whether there's enough storage to hold E.
STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT));
V8_INLINE base::AtomicWord ToIntegral() const {
return base::Acquire_Load(&bits_);
}
V8_INLINE base::AtomicWord Mask(E element) const {
return static_cast<base::AtomicWord>(1) << element;
}
base::AtomicWord bits_;
};
class AsAtomic32 {
public:
template <typename T>

View File

@ -126,7 +126,8 @@ void LiveObjectRange<mode>::iterator::AdvanceToNextValidObject() {
// make sure that we skip all set bits in the black area until the
// object ends.
HeapObject* black_object = HeapObject::FromAddress(addr);
map = base::NoBarrierAtomicValue<Map*>::FromAddress(addr)->Value();
map =
base::AsAtomicPointer::Relaxed_Load(reinterpret_cast<Map**>(addr));
size = black_object->SizeFromMap(map);
Address end = addr + size - kPointerSize;
// One word filler objects do not borrow the second mark bit. We have
@ -153,7 +154,8 @@ void LiveObjectRange<mode>::iterator::AdvanceToNextValidObject() {
object = black_object;
}
} else if ((mode == kGreyObjects || mode == kAllLiveObjects)) {
map = base::NoBarrierAtomicValue<Map*>::FromAddress(addr)->Value();
map =
base::AsAtomicPointer::Relaxed_Load(reinterpret_cast<Map**>(addr));
object = HeapObject::FromAddress(addr);
size = object->SizeFromMap(map);
}

View File

@ -597,21 +597,18 @@ class MemoryChunk {
void set_prev_chunk(MemoryChunk* prev) { prev_chunk_.SetValue(prev); }
Space* owner() const {
intptr_t owner_value = base::NoBarrierAtomicValue<intptr_t>::FromAddress(
const_cast<Address*>(&owner_))
->Value();
if ((owner_value & kPageHeaderTagMask) == kPageHeaderTag) {
return reinterpret_cast<Space*>(owner_value - kPageHeaderTag);
} else {
return nullptr;
}
uintptr_t owner_value = base::AsAtomicWord::Relaxed_Load(
reinterpret_cast<const uintptr_t*>(&owner_));
return ((owner_value & kPageHeaderTagMask) == kPageHeaderTag)
? reinterpret_cast<Space*>(owner_value - kPageHeaderTag)
: nullptr;
}
void set_owner(Space* space) {
DCHECK((reinterpret_cast<intptr_t>(space) & kPageHeaderTagMask) == 0);
DCHECK_EQ(0, reinterpret_cast<intptr_t>(space) & kPageHeaderTagMask);
owner_ = reinterpret_cast<Address>(space) + kPageHeaderTag;
DCHECK((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) ==
kPageHeaderTag);
DCHECK_EQ(kPageHeaderTag,
reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask);
}
bool HasPageHeader() { return owner() != nullptr; }

View File

@ -125,150 +125,5 @@ TEST(AtomicValue, WithVoidStar) {
EXPECT_EQ(&dummy, a.Value());
}
TEST(NoBarrierAtomicValue, Initial) {
NoBarrierAtomicValue<TestFlag> a(kA);
EXPECT_EQ(TestFlag::kA, a.Value());
}
TEST(NoBarrierAtomicValue, SetValue) {
NoBarrierAtomicValue<TestFlag> a(kB);
a.SetValue(kC);
EXPECT_EQ(TestFlag::kC, a.Value());
}
TEST(NoBarrierAtomicValue, WithVoidStar) {
NoBarrierAtomicValue<void*> a(nullptr);
NoBarrierAtomicValue<void*> dummy(nullptr);
EXPECT_EQ(nullptr, a.Value());
a.SetValue(&a);
EXPECT_EQ(&a, a.Value());
}
TEST(NoBarrierAtomicValue, Construction) {
NoBarrierAtomicValue<TestFlag> a(kA);
TestFlag b = kA;
NoBarrierAtomicValue<TestFlag>* ptr =
NoBarrierAtomicValue<TestFlag>::FromAddress(&b);
EXPECT_EQ(ptr->Value(), a.Value());
}
TEST(NoBarrierAtomicValue, ConstructionVoidStar) {
NoBarrierAtomicValue<void*> a(nullptr);
void* b = nullptr;
NoBarrierAtomicValue<void*>* ptr =
NoBarrierAtomicValue<void*>::FromAddress(&b);
EXPECT_EQ(ptr->Value(), a.Value());
}
namespace {
enum TestSetValue { kAA, kBB, kCC, kLastValue = kCC };
} // namespace
TEST(AtomicEnumSet, Constructor) {
AtomicEnumSet<TestSetValue> a;
EXPECT_TRUE(a.IsEmpty());
EXPECT_FALSE(a.Contains(kAA));
}
TEST(AtomicEnumSet, AddSingle) {
AtomicEnumSet<TestSetValue> a;
a.Add(kAA);
EXPECT_FALSE(a.IsEmpty());
EXPECT_TRUE(a.Contains(kAA));
EXPECT_FALSE(a.Contains(kBB));
EXPECT_FALSE(a.Contains(kCC));
}
TEST(AtomicEnumSet, AddOtherSet) {
AtomicEnumSet<TestSetValue> a;
AtomicEnumSet<TestSetValue> b;
a.Add(kAA);
EXPECT_FALSE(a.IsEmpty());
EXPECT_TRUE(b.IsEmpty());
b.Add(a);
EXPECT_FALSE(b.IsEmpty());
EXPECT_TRUE(a.Contains(kAA));
EXPECT_TRUE(b.Contains(kAA));
}
TEST(AtomicEnumSet, RemoveSingle) {
AtomicEnumSet<TestSetValue> a;
a.Add(kAA);
a.Add(kBB);
EXPECT_TRUE(a.Contains(kAA));
EXPECT_TRUE(a.Contains(kBB));
a.Remove(kAA);
EXPECT_FALSE(a.Contains(kAA));
EXPECT_TRUE(a.Contains(kBB));
}
TEST(AtomicEnumSet, RemoveOtherSet) {
AtomicEnumSet<TestSetValue> a;
AtomicEnumSet<TestSetValue> b;
a.Add(kAA);
a.Add(kBB);
b.Add(kBB);
a.Remove(b);
EXPECT_TRUE(a.Contains(kAA));
EXPECT_FALSE(a.Contains(kBB));
EXPECT_FALSE(a.Contains(kCC));
}
TEST(AtomicEnumSet, RemoveEmptySet) {
AtomicEnumSet<TestSetValue> a;
AtomicEnumSet<TestSetValue> b;
a.Add(kAA);
a.Add(kBB);
EXPECT_TRUE(a.Contains(kAA));
EXPECT_TRUE(a.Contains(kBB));
EXPECT_FALSE(a.Contains(kCC));
EXPECT_TRUE(b.IsEmpty());
a.Remove(b);
EXPECT_TRUE(a.Contains(kAA));
EXPECT_TRUE(a.Contains(kBB));
EXPECT_FALSE(a.Contains(kCC));
}
TEST(AtomicEnumSet, Intersect) {
AtomicEnumSet<TestSetValue> a;
AtomicEnumSet<TestSetValue> b;
a.Add(kAA);
b.Add(kCC);
a.Intersect(b);
EXPECT_TRUE(a.IsEmpty());
}
TEST(AtomicEnumSet, ContainsAnyOf) {
AtomicEnumSet<TestSetValue> a;
AtomicEnumSet<TestSetValue> b;
a.Add(kAA);
b.Add(kCC);
EXPECT_FALSE(a.ContainsAnyOf(b));
b.Add(kAA);
EXPECT_TRUE(a.ContainsAnyOf(b));
}
TEST(AtomicEnumSet, Equality) {
AtomicEnumSet<TestSetValue> a;
AtomicEnumSet<TestSetValue> b;
a.Add(kAA);
EXPECT_FALSE(a == b);
EXPECT_TRUE(a != b);
b.Add(kAA);
EXPECT_TRUE(a == b);
EXPECT_FALSE(a != b);
}
} // namespace base
} // namespace v8