Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (226246 => 226247)
--- trunk/Source/_javascript_Core/ChangeLog 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-12-21 23:05:11 UTC (rev 226247)
@@ -1,3 +1,14 @@
+2017-12-21 Mark Lam <mark....@apple.com>
+
+ Add WTF::PoisonedUniquePtr to replace std::unique_ptr when poisoning is desired.
+ https://bugs.webkit.org/show_bug.cgi?id=181062
+ <rdar://problem/36167040>
+
+ Reviewed by Chris Dumez.
+
+ * runtime/JSCPoisonedPtr.cpp:
+ - Added a needed #include.
+
2017-12-21 Jeremy Jones <jere...@apple.com>
Update FULLSCREEN_API feature defines.
Modified: trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.cpp (226246 => 226247)
--- trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.cpp 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/_javascript_Core/runtime/JSCPoisonedPtr.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -26,6 +26,8 @@
#include "config.h"
#include "JSCPoisonedPtr.h"
+#include <mutex>
+
namespace JSC {
uintptr_t g_globalDataPoison;
Modified: trunk/Source/WTF/ChangeLog (226246 => 226247)
--- trunk/Source/WTF/ChangeLog 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/WTF/ChangeLog 2017-12-21 23:05:11 UTC (rev 226247)
@@ -1,3 +1,34 @@
+2017-12-21 Mark Lam <mark....@apple.com>
+
+ Add WTF::PoisonedUniquePtr to replace std::unique_ptr when poisoning is desired.
+ https://bugs.webkit.org/show_bug.cgi?id=181062
+ <rdar://problem/36167040>
+
+ Reviewed by Chris Dumez.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/CMakeLists.txt:
+ * wtf/PointerAsserts.cpp: Copied from Source/WTF/wtf/RefPtr.cpp.
+ - renamed file because we asserts all kinds of pointers in here, not just RefPtr.
+
+ * wtf/Poisoned.h:
+ - added a missing #include.
+ - make constexpr poison values more scrambled.
+ (WTF::makePoison):
+
+ * wtf/PoisonedUniquePtr.h: Added.
+ (WTF::PoisonedUniquePtr::PoisonedUniquePtr):
+ (WTF::PoisonedUniquePtr::~PoisonedUniquePtr):
+ (WTF::PoisonedUniquePtr::create):
+ (WTF::PoisonedUniquePtr::operator=):
+ (WTF::PoisonedUniquePtr::get const):
+ (WTF::PoisonedUniquePtr::operator[] const):
+ (WTF::PoisonedUniquePtr::clear):
+ (WTF::PoisonedUniquePtr::destroy):
+ (WTF::PoisonedUniquePtr::clearWithoutDestroy):
+ (WTF::makePoisonedUnique):
+ * wtf/RefPtr.cpp: Removed.
+
2017-12-21 Jeremy Jones <jere...@apple.com>
Element fullscreen interface should display the location
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (226246 => 226247)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-12-21 23:05:11 UTC (rev 226247)
@@ -150,7 +150,7 @@
E3A32BC41FC830E2007D7E76 /* JSValueMalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A32BC21FC830E2007D7E76 /* JSValueMalloc.cpp */; };
E4A0AD391A96245500536DF6 /* WorkQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD371A96245500536DF6 /* WorkQueue.cpp */; };
E4A0AD3D1A96253C00536DF6 /* WorkQueueCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD3C1A96253C00536DF6 /* WorkQueueCocoa.cpp */; };
- FE05FAFF1FE5007500093230 /* RefPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAFE1FE5007500093230 /* RefPtr.cpp */; };
+ FE05FAFF1FE5007500093230 /* PointerAsserts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAFE1FE5007500093230 /* PointerAsserts.cpp */; };
FE85416E1FBE285D008DA5DA /* Poisoned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE85416C1FBE285B008DA5DA /* Poisoned.cpp */; };
FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; };
/* End PBXBuildFile section */
@@ -619,7 +619,8 @@
EF7D6CD59D8642A8A0DA86AD /* StackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackTrace.h; sourceTree = "<group>"; };
F72BBDB107FA424886178B9E /* SymbolImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolImpl.cpp; sourceTree = "<group>"; };
FE05FAE61FDB214300093230 /* DumbPtrTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumbPtrTraits.h; sourceTree = "<group>"; };
- FE05FAFE1FE5007500093230 /* RefPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefPtr.cpp; sourceTree = "<group>"; };
+ FE05FAFE1FE5007500093230 /* PointerAsserts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PointerAsserts.cpp; sourceTree = "<group>"; };
+ FE05FB041FE8453200093230 /* PoisonedUniquePtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoisonedUniquePtr.h; sourceTree = "<group>"; };
FE8225301B2A1E5B00BA68FD /* NakedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NakedPtr.h; sourceTree = "<group>"; };
FE85416C1FBE285B008DA5DA /* Poisoned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Poisoned.cpp; sourceTree = "<group>"; };
FE85416D1FBE285C008DA5DA /* Poisoned.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Poisoned.h; sourceTree = "<group>"; };
@@ -982,9 +983,11 @@
0F824A651B7443A0002E345D /* ParkingLot.h */,
A876DBD7151816E500DADB95 /* Platform.h */,
E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */,
+ FE05FAFE1FE5007500093230 /* PointerAsserts.cpp */,
0FF860941BCCBD740045127F /* PointerComparison.h */,
FE85416C1FBE285B008DA5DA /* Poisoned.cpp */,
FE85416D1FBE285C008DA5DA /* Poisoned.h */,
+ FE05FB041FE8453200093230 /* PoisonedUniquePtr.h */,
0F9D335D165DBA73005AD387 /* PrintStream.cpp */,
0F9D335E165DBA73005AD387 /* PrintStream.h */,
53EC253C1E95AD30000831B9 /* PriorityQueue.h */,
@@ -1010,7 +1013,6 @@
A8A47301151A825B004123FF /* RefCountedLeakCounter.cpp */,
A8A47302151A825B004123FF /* RefCountedLeakCounter.h */,
86F46F5F1A2840EE00CCBF22 /* RefCounter.h */,
- FE05FAFE1FE5007500093230 /* RefPtr.cpp */,
A8A47303151A825B004123FF /* RefPtr.h */,
A8A47305151A825B004123FF /* RetainPtr.h */,
2CDED0F118115C85004DBA70 /* RunLoop.cpp */,
@@ -1418,7 +1420,7 @@
0F66B28A1DC97BAB004A1D3F /* ClockType.cpp in Sources */,
A8A47460151A825B004123FF /* CollatorDefault.cpp in Sources */,
A8A47463151A825B004123FF /* CollatorICU.cpp in Sources */,
- FE05FAFF1FE5007500093230 /* RefPtr.cpp in Sources */,
+ FE05FAFF1FE5007500093230 /* PointerAsserts.cpp in Sources */,
0F8F2B92172E0103007DBDA5 /* CompilationThread.cpp in Sources */,
0F30CB5A1FCDF134004B5323 /* ConcurrentPtrHashSet.cpp in Sources */,
0F8E85DB1FD485B000691889 /* CountingLock.cpp in Sources */,
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (226246 => 226247)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2017-12-21 23:05:11 UTC (rev 226247)
@@ -111,6 +111,7 @@
Platform.h
PlatformRegisters.h
Poisoned.h
+ PoisonedUniquePtr.h
PrintStream.h
ProcessID.h
RAMSize.h
@@ -262,6 +263,7 @@
ParallelHelperPool.cpp
ParallelJobsGeneric.cpp
ParkingLot.cpp
+ PointerAsserts.cpp
Poisoned.cpp
PrintStream.cpp
RAMSize.cpp
@@ -269,7 +271,6 @@
RandomNumber.cpp
ReadWriteLock.cpp
RefCountedLeakCounter.cpp
- RefPtr.cpp
RunLoop.cpp
SHA1.cpp
Seconds.cpp
Copied: trunk/Source/WTF/wtf/PointerAsserts.cpp (from rev 226246, trunk/Source/WTF/wtf/RefPtr.cpp) (0 => 226247)
--- trunk/Source/WTF/wtf/PointerAsserts.cpp (rev 0)
+++ trunk/Source/WTF/wtf/PointerAsserts.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/Poisoned.h>
+#include <wtf/PoisonedUniquePtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WTF {
+
+namespace {
+struct DummyClass { };
+}
+
+static_assert(sizeof(Ref<DummyClass>) == sizeof(DummyClass*), "");
+static_assert(sizeof(PoisonedRef<0xffff, DummyClass>) == sizeof(DummyClass*), "");
+
+static_assert(sizeof(RefPtr<DummyClass>) == sizeof(DummyClass*), "");
+static_assert(sizeof(PoisonedRefPtr<0xffff, DummyClass>) == sizeof(DummyClass*), "");
+
+static_assert(sizeof(PoisonedUniquePtr<0xffff, DummyClass>) == sizeof(DummyClass*), "");
+static_assert(sizeof(PoisonedUniquePtr<0xffff, int[]>) == sizeof(int*), "");
+static_assert(sizeof(PoisonedUniquePtr<0xffff, DummyClass[]>) == sizeof(DummyClass*), "");
+
+} // namespace WTF
+
Modified: trunk/Source/WTF/wtf/Poisoned.h (226246 => 226247)
--- trunk/Source/WTF/wtf/Poisoned.h 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/WTF/wtf/Poisoned.h 2017-12-21 23:05:11 UTC (rev 226247)
@@ -25,6 +25,7 @@
#pragma once
+#include <utility>
#include <wtf/Assertions.h>
#define ENABLE_POISON 1
@@ -216,7 +217,9 @@
inline constexpr uintptr_t makePoison(uint32_t key)
{
#if ENABLE(POISON)
- return static_cast<uintptr_t>(0x80000000 | key) << 32;
+ uintptr_t poison1 = static_cast<uintptr_t>(key) * 6906969069 + 1234567;
+ uintptr_t poison2 = static_cast<uintptr_t>(key) * 8253729 + 2396403;
+ return ((poison1 << 3) ^ (poison2 << 32)) | (static_cast<uintptr_t>(1) << 63);
#else
return (void)key, 0;
#endif
Added: trunk/Source/WTF/wtf/PoisonedUniquePtr.h (0 => 226247)
--- trunk/Source/WTF/wtf/PoisonedUniquePtr.h (rev 0)
+++ trunk/Source/WTF/wtf/PoisonedUniquePtr.h 2017-12-21 23:05:11 UTC (rev 226247)
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/FastMalloc.h>
+#include <wtf/Poisoned.h>
+
+namespace WTF {
+
+template<uint32_t key, typename T, typename Enable = void>
+class PoisonedUniquePtr : public ConstExprPoisoned<key, T*> {
+ WTF_MAKE_FAST_ALLOCATED;
+ using Base = ConstExprPoisoned<key, T*>;
+public:
+ PoisonedUniquePtr() = default;
+ PoisonedUniquePtr(T* ptr) : Base(ptr) { }
+ PoisonedUniquePtr(PoisonedUniquePtr&& ptr) : Base(WTFMove(ptr)) { ptr.clearWithoutDestroy(); }
+
+ template<uint32_t key2, typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
+ PoisonedUniquePtr(PoisonedUniquePtr<key2, U>&& ptr)
+ : Base(ptr.unpoisoned())
+ {
+ ptr.clearWithoutDestroy();
+ }
+
+ PoisonedUniquePtr(const PoisonedUniquePtr&) = delete;
+
+ ~PoisonedUniquePtr() { destroy(); }
+
+ template<typename... Arguments>
+ static PoisonedUniquePtr create(Arguments&&... arguments)
+ {
+ return new T(std::forward<Arguments>(arguments)...);
+ }
+
+ PoisonedUniquePtr& operator=(T* ptr)
+ {
+ if (LIKELY(this->unpoisoned() != ptr)) {
+ this->clear();
+ this->Base::operator=(ptr);
+ }
+ return *this;
+ }
+
+ template<uint32_t key2, typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
+ PoisonedUniquePtr& operator=(PoisonedUniquePtr<key2, U>&& ptr)
+ {
+ ASSERT(this == static_cast<void*>(&ptr) || this->unpoisoned() != ptr.unpoisoned());
+ if (LIKELY(this != static_cast<void*>(&ptr))) {
+ this->clear();
+ this->Base::operator=(WTFMove(ptr));
+ ptr.clearWithoutDestroy();
+ }
+ return *this;
+ }
+
+ PoisonedUniquePtr& operator=(const PoisonedUniquePtr&) = delete;
+
+ T* get() const { return this->unpoisoned(); }
+ T& operator[](size_t index) const { return this->unpoisoned()[index]; }
+
+ void clear()
+ {
+ destroy();
+ clearWithoutDestroy();
+ }
+
+private:
+ void destroy()
+ {
+ if (!this->bits())
+ return;
+ delete this->unpoisoned();
+ }
+
+ void clearWithoutDestroy() { Base::clear(); }
+
+ template<uint32_t, typename, typename> friend class PoisonedUniquePtr;
+};
+
+template<uint32_t key, typename T, typename... Arguments, typename Enable = void>
+PoisonedUniquePtr<key, T> makePoisonedUnique(Arguments&&... arguments)
+{
+ return PoisonedUniquePtr<key, T>::create(std::forward<Arguments>(arguments)...);
+}
+
+template<uint32_t key, typename T>
+class PoisonedUniquePtr<key, T[]> : public ConstExprPoisoned<key, T*> {
+ WTF_MAKE_FAST_ALLOCATED;
+ using Base = ConstExprPoisoned<key, T*>;
+public:
+ PoisonedUniquePtr() = default;
+ PoisonedUniquePtr(T* ptr) : Base(ptr) { }
+ PoisonedUniquePtr(PoisonedUniquePtr&& ptr) : Base(WTFMove(ptr)) { ptr.clearWithoutDestroy(); }
+
+ template<uint32_t key2>
+ PoisonedUniquePtr(PoisonedUniquePtr<key2, T[]>&& ptr)
+ : Base(ptr.unpoisoned())
+ {
+ ptr.clearWithoutDestroy();
+ }
+
+ PoisonedUniquePtr(const PoisonedUniquePtr&) = delete;
+
+ ~PoisonedUniquePtr() { destroy(); }
+
+ template<typename... Arguments>
+ static PoisonedUniquePtr create(size_t count, Arguments&&... arguments)
+ {
+ T* result = new T[count];
+ while (count--)
+ new (result + count) T(std::forward<Arguments>(arguments)...);
+ return result;
+ }
+
+ PoisonedUniquePtr& operator=(T* ptr)
+ {
+ if (LIKELY(this->unpoisoned() != ptr)) {
+ this->clear();
+ this->Base::operator=(ptr);
+ }
+ return *this;
+ }
+
+ template<uint32_t key2>
+ PoisonedUniquePtr& operator=(PoisonedUniquePtr<key2, T[]>&& ptr)
+ {
+ ASSERT(this == static_cast<void*>(&ptr) || this->unpoisoned() != ptr.unpoisoned());
+ if (LIKELY(this != static_cast<void*>(&ptr))) {
+ this->clear();
+ this->Base::operator=(WTFMove(ptr));
+ ptr.clearWithoutDestroy();
+ }
+ return *this;
+ }
+
+ PoisonedUniquePtr& operator=(const PoisonedUniquePtr&) = delete;
+
+ T* get() const { return this->unpoisoned(); }
+ T& operator[](size_t index) const { return this->unpoisoned()[index]; }
+
+ void clear()
+ {
+ destroy();
+ clearWithoutDestroy();
+ }
+
+private:
+ void destroy()
+ {
+ if (!this->bits())
+ return;
+ delete[] this->unpoisoned();
+ }
+
+ void clearWithoutDestroy() { Base::clear(); }
+
+ template<uint32_t, typename, typename> friend class PoisonedUniquePtr;
+};
+
+template<uint32_t key, typename T, typename... Arguments>
+PoisonedUniquePtr<key, T[]> makePoisonedUnique(size_t count, Arguments&&... arguments)
+{
+ return PoisonedUniquePtr<key, T[]>::create(count, std::forward<Arguments>(arguments)...);
+}
+
+} // namespace WTF
+
+using WTF::PoisonedUniquePtr;
+using WTF::makePoisonedUnique;
+
Deleted: trunk/Source/WTF/wtf/RefPtr.cpp (226246 => 226247)
--- trunk/Source/WTF/wtf/RefPtr.cpp 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Source/WTF/wtf/RefPtr.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "RefPtr.h"
-
-#include "Poisoned.h"
-
-namespace WTF {
-
-struct DummyClass { };
-
-static_assert(sizeof(Ref<DummyClass>) == sizeof(DummyClass*), "");
-static_assert(sizeof(PoisonedRef<0xffff, DummyClass>) == sizeof(DummyClass*), "");
-
-static_assert(sizeof(RefPtr<DummyClass>) == sizeof(DummyClass*), "");
-static_assert(sizeof(PoisonedRefPtr<0xffff, DummyClass>) == sizeof(DummyClass*), "");
-
-} // namespace WTF
-
Modified: trunk/Tools/ChangeLog (226246 => 226247)
--- trunk/Tools/ChangeLog 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Tools/ChangeLog 2017-12-21 23:05:11 UTC (rev 226247)
@@ -1,3 +1,25 @@
+2017-12-21 Mark Lam <mark....@apple.com>
+
+ Add WTF::PoisonedUniquePtr to replace std::unique_ptr when poisoning is desired.
+ https://bugs.webkit.org/show_bug.cgi?id=181062
+ <rdar://problem/36167040>
+
+ Reviewed by Chris Dumez.
+
+ * TestWebKitAPI/CMakeLists.txt:
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
+ * TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp:
+ - Removed an unneeded #include.
+
+ * TestWebKitAPI/Tests/WTF/PoisonedUniquePtr.cpp: Added.
+ (TestWebKitAPI::TEST):
+ (TestWebKitAPI::poisonedPtrFoo):
+ * TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp: Added.
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForTriviallyDestructibleArrays.cpp: Added.
+ (TestWebKitAPI::TEST):
+
2017-12-21 Jeremy Jones <jere...@apple.com>
Update FULLSCREEN_API feature defines.
Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (226246 => 226247)
--- trunk/Tools/TestWebKitAPI/CMakeLists.txt 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt 2017-12-21 23:05:11 UTC (rev 226247)
@@ -126,6 +126,9 @@
${TESTWEBKITAPI_DIR}/Tests/WTF/Poisoned.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedRef.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedRefPtr.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedUniquePtr.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WTF/PoisonedUniquePtrForTriviallyDestructibleArrays.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/PriorityQueue.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/RedBlackTree.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/Ref.cpp
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (226246 => 226247)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-12-21 23:05:11 UTC (rev 226247)
@@ -762,6 +762,9 @@
FE05FAED1FDB510E00093230 /* PoisonedRefPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAEA1FDB510100093230 /* PoisonedRefPtr.cpp */; };
FE05FAEF1FE0645B00093230 /* Poisoned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAEE1FE0643D00093230 /* Poisoned.cpp */; };
FE05FAF11FE08CD400093230 /* ConstExprPoisoned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAF01FE08CCD00093230 /* ConstExprPoisoned.cpp */; };
+ FE05FB061FE84FB700093230 /* PoisonedUniquePtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FB051FE84FAE00093230 /* PoisonedUniquePtr.cpp */; };
+ FEC8F4E71FE9C9050056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC8F4E61FE9C8DE0056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp */; };
+ FEC8F4EB1FE9F5AF0056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC8F4EA1FE9F5A70056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -1869,7 +1872,10 @@
FE05FAEB1FDB510200093230 /* PoisonedRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoisonedRef.cpp; sourceTree = "<group>"; };
FE05FAEE1FE0643D00093230 /* Poisoned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Poisoned.cpp; sourceTree = "<group>"; };
FE05FAF01FE08CCD00093230 /* ConstExprPoisoned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstExprPoisoned.cpp; sourceTree = "<group>"; };
+ FE05FB051FE84FAE00093230 /* PoisonedUniquePtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoisonedUniquePtr.cpp; sourceTree = "<group>"; };
FEB6F74E1B2BA44E009E4922 /* NakedPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NakedPtr.cpp; sourceTree = "<group>"; };
+ FEC8F4E61FE9C8DE0056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoisonedUniquePtrForTriviallyDestructibleArrays.cpp; sourceTree = "<group>"; };
+ FEC8F4EA1FE9F5A70056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -2671,6 +2677,9 @@
FE05FAEE1FE0643D00093230 /* Poisoned.cpp */,
FE05FAEB1FDB510200093230 /* PoisonedRef.cpp */,
FE05FAEA1FDB510100093230 /* PoisonedRefPtr.cpp */,
+ FE05FB051FE84FAE00093230 /* PoisonedUniquePtr.cpp */,
+ FEC8F4EA1FE9F5A70056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp */,
+ FEC8F4E61FE9C8DE0056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp */,
53EC253F1E96BC80000831B9 /* PriorityQueue.cpp */,
0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */,
93A427AA180DA26400CD24D7 /* Ref.cpp */,
@@ -3211,6 +3220,7 @@
7C83DED41D0A590C00FEBCF3 /* HashSet.cpp in Sources */,
7C83DEE01D0A590C00FEBCF3 /* IntegerToStringConversion.cpp in Sources */,
7A0509411FB9F06400B33FB8 /* JSONValue.cpp in Sources */,
+ FE05FB061FE84FB700093230 /* PoisonedUniquePtr.cpp in Sources */,
531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */,
A57D54F91F3397B400A97AA7 /* LifecycleLogger.cpp in Sources */,
93E2C5551FD3204100E1DF6A /* LineEnding.cpp in Sources */,
@@ -3247,6 +3257,7 @@
7C83DF321D0A590C00FEBCF3 /* StringBuilder.cpp in Sources */,
7CD4C26E1E2C0E6E00929470 /* StringConcatenate.cpp in Sources */,
7C83DF361D0A590C00FEBCF3 /* StringHasher.cpp in Sources */,
+ FEC8F4E71FE9C9050056FD8A /* PoisonedUniquePtrForTriviallyDestructibleArrays.cpp in Sources */,
7C83DF371D0A590C00FEBCF3 /* StringImpl.cpp in Sources */,
7C83DF381D0A590C00FEBCF3 /* StringOperators.cpp in Sources */,
7C83DF3A1D0A590C00FEBCF3 /* StringView.cpp in Sources */,
@@ -3255,6 +3266,7 @@
9329AA291DE3F81E003ABD07 /* TextBreakIterator.cpp in Sources */,
E3DEA8111F0A589000CBC2E8 /* ThreadGroup.cpp in Sources */,
E38A0D351FD50CC300E98C8B /* Threading.cpp in Sources */,
+ FEC8F4EB1FE9F5AF0056FD8A /* PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp in Sources */,
5311BD5E1EA9490E00525281 /* ThreadMessages.cpp in Sources */,
0F2C20B81DCD545000542D9E /* Time.cpp in Sources */,
7C83E03B1D0A602700FEBCF3 /* UtilitiesCocoa.mm in Sources */,
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp (226246 => 226247)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp 2017-12-21 23:03:28 UTC (rev 226246)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/ConstExprPoisoned.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -26,7 +26,6 @@
#include "config.h"
#include "RefLogger.h"
-#include <mutex>
#include <wtf/Poisoned.h>
namespace TestWebKitAPI {
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtr.cpp (0 => 226247)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtr.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtr.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/PoisonedUniquePtr.h>
+
+namespace TestWebKitAPI {
+
+namespace {
+
+const uint32_t PoisonA = 0xaaaa;
+const uint32_t PoisonB = 0xbbbb;
+
+struct Logger {
+ Logger(const char* name, int& destructCount)
+ : name(*name)
+ , destructCount(destructCount)
+ { }
+
+ ~Logger() { ++destructCount; }
+
+ const char& name;
+ int& destructCount;
+};
+
+struct DerivedLogger : Logger {
+ DerivedLogger(const char* name, int& destructCount)
+ : Logger(name, destructCount)
+ { }
+};
+
+struct Other {
+ Other(const char*, int&)
+ { }
+};
+
+} // anonymous namespace
+
+TEST(WTF_PoisonedUniquePtr, Basic)
+{
+ {
+ PoisonedUniquePtr<PoisonA, Logger> empty;
+ ASSERT_EQ(nullptr, empty.unpoisoned());
+ ASSERT_EQ(0u, empty.bits());
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ ASSERT_EQ(&a->name, &ptr->name);
+
+#if ENABLE(POISON)
+ uintptr_t ptrBits;
+ std::memcpy(&ptrBits, &ptr, sizeof(ptrBits));
+ ASSERT_TRUE(ptrBits != bitwise_cast<uintptr_t>(a));
+#if ENABLE(POISON_ASSERTS)
+ ASSERT_TRUE((PoisonedUniquePtr<PoisonA, Logger>::isPoisoned(ptrBits)));
+#endif
+#endif // ENABLE(POISON)
+ }
+ ASSERT_EQ(1, aDestructCount);
+
+ int bDestructCount = 0;
+ DerivedLogger* b = new DerivedLogger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(b);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, ptr.unpoisoned());
+ ASSERT_EQ(b, &*ptr);
+ ASSERT_EQ(&b->name, &ptr->name);
+ }
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr = a;
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+
+ int bDestructCount = 0;
+ DerivedLogger* b = new DerivedLogger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr = b;
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ const char* aName = "a";
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr = PoisonedUniquePtr<PoisonA, Logger>::create(aName, aDestructCount);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ ASSERT_EQ(aName, &ptr->name);
+ }
+ ASSERT_EQ(1, aDestructCount);
+
+ int bDestructCount = 0;
+ const char* bName = "b";
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr = PoisonedUniquePtr<PoisonA, DerivedLogger>::create(bName, bDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ ASSERT_EQ(bName, &ptr->name);
+ }
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ const char* aName = "a";
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr = makePoisonedUnique<PoisonA, Logger>(aName, aDestructCount);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ ASSERT_EQ(aName, &ptr->name);
+ }
+ ASSERT_EQ(1, aDestructCount);
+
+ int bDestructCount = 0;
+ const char* bName = "b";
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr = makePoisonedUnique<PoisonA, DerivedLogger>(bName, bDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ ASSERT_EQ(bName, &ptr->name);
+ }
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ Logger* b = new Logger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger> p2 = WTFMove(p1);
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_EQ(nullptr, p1.unpoisoned());
+ ASSERT_EQ(0u, p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger> p4 = WTFMove(p3);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(nullptr, p3.unpoisoned());
+ ASSERT_EQ(0u, p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ Logger* b = new Logger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger> p2(WTFMove(p1));
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(nullptr, p1.unpoisoned());
+ ASSERT_EQ(0u, p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger> p4(WTFMove(p3));
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(nullptr, p3.unpoisoned());
+ ASSERT_EQ(0u, p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ DerivedLogger* a = new DerivedLogger("a", aDestructCount);
+ DerivedLogger* b = new DerivedLogger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger> p2 = WTFMove(p1);
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger> p4 = WTFMove(p3);
+ ASSERT_EQ(bDestructCount, 0);
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ DerivedLogger* a = new DerivedLogger("a", aDestructCount);
+ DerivedLogger* b = new DerivedLogger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger> p2(WTFMove(p1));
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger> p4(WTFMove(p3));
+ ASSERT_EQ(bDestructCount, 0);
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr.clear();
+ ASSERT_TRUE(!ptr.unpoisoned());
+ ASSERT_TRUE(!ptr.bits());
+ ASSERT_EQ(1, aDestructCount);
+ }
+ ASSERT_EQ(1, aDestructCount);
+ }
+}
+
+TEST(WTF_PoisonedUniquePtr, Assignment)
+{
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ Logger* b = new Logger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = b;
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = nullptr;
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(nullptr, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ int cDestructCount = 0;
+ int dDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ Logger* b = new Logger("b", bDestructCount);
+ Logger* c = new Logger("c", cDestructCount);
+ Logger* d = new Logger("d", dDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1(a);
+ PoisonedUniquePtr<PoisonA, Logger> p2(b);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_EQ(b, p2.unpoisoned());
+ p1 = WTFMove(p2);
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, p1.unpoisoned());
+ ASSERT_EQ(nullptr, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3(c);
+ PoisonedUniquePtr<PoisonB, Logger> p4(d);
+ ASSERT_EQ(0, cDestructCount);
+ ASSERT_EQ(0, dDestructCount);
+ ASSERT_EQ(c, p3.unpoisoned());
+ ASSERT_EQ(d, p4.unpoisoned());
+ p3 = WTFMove(p4);
+ ASSERT_EQ(1, cDestructCount);
+ ASSERT_EQ(0, dDestructCount);
+ ASSERT_EQ(d, p3.unpoisoned());
+ ASSERT_EQ(nullptr, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ ASSERT_EQ(1, cDestructCount);
+ ASSERT_EQ(1, dDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ DerivedLogger* a = new DerivedLogger("a", aDestructCount);
+ DerivedLogger* b = new DerivedLogger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = b;
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ int cDestructCount = 0;
+ int dDestructCount = 0;
+ DerivedLogger* a = new DerivedLogger("a", aDestructCount);
+ DerivedLogger* b = new DerivedLogger("b", bDestructCount);
+ DerivedLogger* c = new DerivedLogger("c", cDestructCount);
+ DerivedLogger* d = new DerivedLogger("d", dDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1(a);
+ PoisonedUniquePtr<PoisonA, DerivedLogger> p2(b);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_EQ(b, p2.unpoisoned());
+ p1 = WTFMove(p2);
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, p1.unpoisoned());
+ ASSERT_EQ(nullptr, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3(c);
+ PoisonedUniquePtr<PoisonB, DerivedLogger> p4(d);
+ ASSERT_EQ(0, cDestructCount);
+ ASSERT_EQ(0, dDestructCount);
+ ASSERT_EQ(c, p3.unpoisoned());
+ ASSERT_EQ(d, p4.unpoisoned());
+ p3 = WTFMove(p4);
+ ASSERT_EQ(1, cDestructCount);
+ ASSERT_EQ(0, dDestructCount);
+ ASSERT_EQ(d, p3.unpoisoned());
+ ASSERT_EQ(nullptr, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ ASSERT_EQ(1, cDestructCount);
+ ASSERT_EQ(1, dDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = a;
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+ ptr = WTFMove(ptr);
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ }
+}
+
+TEST(WTF_PoisonedUniquePtr, Swap)
+{
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ Logger* b = new Logger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger> p2;
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_TRUE(!p2.bits());
+ ASSERT_TRUE(!p2.unpoisoned());
+ p2.swap(p1);
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger> p4;
+ ASSERT_EQ(b, p3.unpoisoned());
+ ASSERT_TRUE(!p4.bits());
+ ASSERT_TRUE(!p4.unpoisoned());
+ p4.swap(p3);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ Logger* b = new Logger("b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger> p2;
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_TRUE(!p2.bits());
+ ASSERT_TRUE(!p2.unpoisoned());
+ swap(p1, p2);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger> p4;
+ ASSERT_EQ(b, p3.unpoisoned());
+ ASSERT_TRUE(!p4.bits());
+ ASSERT_TRUE(!p4.unpoisoned());
+ swap(p3, p4);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(1, aDestructCount);
+ ASSERT_EQ(1, bDestructCount);
+ }
+}
+
+static PoisonedUniquePtr<PoisonA, Logger> poisonedPtrFoo(Logger* logger)
+{
+ return PoisonedUniquePtr<PoisonA, Logger>(logger);
+}
+
+TEST(WTF_PoisonedUniquePtr, ReturnValue)
+{
+ {
+ int aDestructCount = 0;
+ Logger* a = new Logger("a", aDestructCount);
+ {
+ auto ptr = poisonedPtrFoo(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ ASSERT_EQ(&a->name, &ptr->name);
+ }
+ ASSERT_EQ(1, aDestructCount);
+ }
+}
+
+} // namespace TestWebKitAPI
+
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp (0 => 226247)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForNonTriviallyDestructibleArrays.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/PoisonedUniquePtr.h>
+
+namespace TestWebKitAPI {
+
+namespace {
+
+const uint32_t PoisonA = 0xaaaa;
+const uint32_t PoisonB = 0xbbbb;
+
+struct Logger {
+ Logger() { }
+ Logger(const char* name, int& destructCount)
+ : name(name)
+ , destructCount(&destructCount)
+ { }
+
+ ~Logger() { ++(*destructCount); }
+
+ const char* name;
+ int* destructCount;
+};
+
+template<typename T, typename... Arguments>
+T* makeArray(size_t count, Arguments&&... arguments)
+{
+ T* result = new T[count];
+ while (count--)
+ new (result + count) T(std::forward<Arguments>(arguments)...);
+ return result;
+}
+
+const int arraySize = 5;
+
+} // anonymous namespace
+
+TEST(WTF_PoisonedUniquePtrForNonTriviallyDestructibleArrays, Basic)
+{
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> empty;
+ ASSERT_EQ(nullptr, empty.unpoisoned());
+ ASSERT_EQ(0u, empty.bits());
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i].name, ptr[i].name);
+
+#if ENABLE(POISON)
+ uintptr_t ptrBits;
+ std::memcpy(&ptrBits, &ptr, sizeof(ptrBits));
+ ASSERT_TRUE(ptrBits != bitwise_cast<uintptr_t>(a));
+#if ENABLE(POISON_ASSERTS)
+ ASSERT_TRUE((PoisonedUniquePtr<PoisonA, Logger[]>::isPoisoned(ptrBits)));
+#endif
+#endif // ENABLE(POISON)
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr = a;
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i].name, ptr[i].name);
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ const char* aName = "a";
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr = PoisonedUniquePtr<PoisonA, Logger[]>::create(arraySize, aName, aDestructCount);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(aName, ptr[i].name);
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ const char* aName = "a";
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr = makePoisonedUnique<PoisonA, Logger[]>(arraySize, aName, aDestructCount);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(aName, ptr[i].name);
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ const char* aName = "a";
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr = makePoisonedUnique<PoisonA, Logger[]>(arraySize, aName, aDestructCount);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(aName, ptr[i].name);
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger[]> p2 = WTFMove(p1);
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_EQ(nullptr, p1.unpoisoned());
+ ASSERT_EQ(0u, p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger[]> p4 = WTFMove(p3);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(nullptr, p3.unpoisoned());
+ ASSERT_EQ(0u, p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger[]> p2(WTFMove(p1));
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(nullptr, p1.unpoisoned());
+ ASSERT_EQ(0u, p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger[]> p4(WTFMove(p3));
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(nullptr, p3.unpoisoned());
+ ASSERT_EQ(0u, p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger[]> p2 = WTFMove(p1);
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger[]> p4 = WTFMove(p3);
+ ASSERT_EQ(bDestructCount, 0);
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger[]> p2(WTFMove(p1));
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger[]> p4(WTFMove(p3));
+ ASSERT_EQ(bDestructCount, 0);
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr.clear();
+ ASSERT_TRUE(!ptr.unpoisoned());
+ ASSERT_TRUE(!ptr.bits());
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+}
+
+TEST(WTF_PoisonedUniquePtrForNonTriviallyDestructibleArrays, Assignment)
+{
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = b;
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, ptr.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = nullptr;
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(nullptr, ptr.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ int cDestructCount = 0;
+ int dDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ Logger* c = makeArray<Logger>(arraySize, "c", cDestructCount);
+ Logger* d = makeArray<Logger>(arraySize, "d", dDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1(a);
+ PoisonedUniquePtr<PoisonA, Logger[]> p2(b);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_EQ(b, p2.unpoisoned());
+ p1 = WTFMove(p2);
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_EQ(b, p1.unpoisoned());
+ ASSERT_EQ(nullptr, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3(c);
+ PoisonedUniquePtr<PoisonB, Logger[]> p4(d);
+ ASSERT_EQ(0, cDestructCount);
+ ASSERT_EQ(0, dDestructCount);
+ ASSERT_EQ(c, p3.unpoisoned());
+ ASSERT_EQ(d, p4.unpoisoned());
+ p3 = WTFMove(p4);
+ ASSERT_EQ(arraySize, cDestructCount);
+ ASSERT_EQ(0, dDestructCount);
+ ASSERT_EQ(d, p3.unpoisoned());
+ ASSERT_EQ(nullptr, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ ASSERT_EQ(arraySize, cDestructCount);
+ ASSERT_EQ(arraySize, dDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = a;
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> ptr(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+ ptr = WTFMove(ptr);
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+}
+
+TEST(WTF_PoisonedUniquePtrForNonTriviallyDestructibleArrays, Swap)
+{
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger[]> p2;
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_TRUE(!p2.bits());
+ ASSERT_TRUE(!p2.unpoisoned());
+ p2.swap(p1);
+ ASSERT_EQ(aDestructCount, 0);
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger[]> p4;
+ ASSERT_EQ(b, p3.unpoisoned());
+ ASSERT_TRUE(!p4.bits());
+ ASSERT_TRUE(!p4.unpoisoned());
+ p4.swap(p3);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+
+ {
+ int aDestructCount = 0;
+ int bDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ Logger* b = makeArray<Logger>(arraySize, "b", bDestructCount);
+ {
+ PoisonedUniquePtr<PoisonA, Logger[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, Logger[]> p2;
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_TRUE(!p2.bits());
+ ASSERT_TRUE(!p2.unpoisoned());
+ swap(p1, p2);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_EQ(a, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, Logger[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, Logger[]> p4;
+ ASSERT_EQ(b, p3.unpoisoned());
+ ASSERT_TRUE(!p4.bits());
+ ASSERT_TRUE(!p4.unpoisoned());
+ swap(p3, p4);
+ ASSERT_EQ(0, bDestructCount);
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_EQ(b, p4.unpoisoned());
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ ASSERT_EQ(arraySize, bDestructCount);
+ }
+}
+
+static PoisonedUniquePtr<PoisonA, Logger[]> poisonedPtrFoo(Logger* array)
+{
+ return PoisonedUniquePtr<PoisonA, Logger[]>(array);
+}
+
+TEST(WTF_PoisonedUniquePtrForNonTriviallyDestructibleArrays, ReturnValue)
+{
+ {
+ int aDestructCount = 0;
+ Logger* a = makeArray<Logger>(arraySize, "a", aDestructCount);
+ {
+ auto ptr = poisonedPtrFoo(a);
+ ASSERT_EQ(0, aDestructCount);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i].name, ptr[i].name);
+ }
+ ASSERT_EQ(arraySize, aDestructCount);
+ }
+}
+
+} // namespace TestWebKitAPI
+
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForTriviallyDestructibleArrays.cpp (0 => 226247)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForTriviallyDestructibleArrays.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/PoisonedUniquePtrForTriviallyDestructibleArrays.cpp 2017-12-21 23:05:11 UTC (rev 226247)
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/FastMalloc.h>
+#include <wtf/PoisonedUniquePtr.h>
+
+namespace TestWebKitAPI {
+
+namespace {
+
+const uint32_t PoisonA = 0xaaaa;
+const uint32_t PoisonB = 0xbbbb;
+
+template<typename T>
+static void fillArray(T& array, int size)
+{
+ for (int i = 0; i < size; ++i)
+ array[i] = i + 100;
+}
+
+static const int arraySize = 5;
+
+} // anonymous namespace
+
+TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, Basic)
+{
+ {
+ PoisonedUniquePtr<PoisonA, int[]> empty;
+ ASSERT_EQ(nullptr, empty.unpoisoned());
+ ASSERT_EQ(0u, empty.bits());
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+ {
+ PoisonedUniquePtr<PoisonA, int[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i], ptr[i]);
+
+#if ENABLE(POISON)
+ uintptr_t ptrBits;
+ std::memcpy(&ptrBits, &ptr, sizeof(ptrBits));
+ ASSERT_TRUE(ptrBits != bitwise_cast<uintptr_t>(a));
+#if ENABLE(POISON_ASSERTS)
+ ASSERT_TRUE((PoisonedUniquePtr<PoisonA, int[]>::isPoisoned(ptrBits)));
+#endif
+#endif // ENABLE(POISON)
+ }
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> ptr = a;
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i], ptr[i]);
+ }
+
+ {
+ PoisonedUniquePtr<PoisonA, int[]> ptr = PoisonedUniquePtr<PoisonA, int[]>::create(arraySize);
+ ASSERT_TRUE(nullptr != ptr.unpoisoned());
+ fillArray(ptr, arraySize);
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ((100 + i), ptr[i]);
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+ auto* b = new int[arraySize];
+ fillArray(b, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, int[]> p2 = WTFMove(p1);
+ ASSERT_EQ(nullptr, p1.unpoisoned());
+ ASSERT_EQ(0u, p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i], p2[i]);
+
+ PoisonedUniquePtr<PoisonA, int[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, int[]> p4 = WTFMove(p3);
+ ASSERT_EQ(nullptr, p3.unpoisoned());
+ ASSERT_EQ(0u, p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(b[i], p4[i]);
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+ auto* b = new int[arraySize];
+ fillArray(b, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, int[]> p2(WTFMove(p1));
+ ASSERT_EQ(nullptr, p1.unpoisoned());
+ ASSERT_EQ(0u, p1.bits());
+ ASSERT_EQ(a, p2.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i], p2[i]);
+
+ PoisonedUniquePtr<PoisonA, int[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, int[]> p4(WTFMove(p3));
+ ASSERT_EQ(nullptr, p3.unpoisoned());
+ ASSERT_EQ(0u, p3.bits());
+ ASSERT_EQ(b, p4.unpoisoned());
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(b[i], p4[i]);
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr.clear();
+ ASSERT_TRUE(!ptr.unpoisoned());
+ ASSERT_TRUE(!ptr.bits());
+ }
+}
+
+TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, Assignment)
+{
+ {
+ auto* a = new int[arraySize];
+ auto* b = new int[arraySize];
+ fillArray(a, arraySize);
+ fillArray(b, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = b;
+ ASSERT_EQ(b, ptr.unpoisoned());
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = nullptr;
+ ASSERT_EQ(nullptr, ptr.unpoisoned());
+ }
+
+ {
+ auto* a = new int[arraySize];
+ auto* b = new int[arraySize];
+ auto* c = new int[arraySize];
+ auto* d = new int[arraySize];
+ fillArray(a, arraySize);
+ fillArray(b, arraySize);
+ fillArray(c, arraySize);
+ fillArray(d, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> p1(a);
+ PoisonedUniquePtr<PoisonA, int[]> p2(b);
+ ASSERT_EQ(a, p1.unpoisoned());
+ ASSERT_EQ(b, p2.unpoisoned());
+ p1 = WTFMove(p2);
+ ASSERT_EQ(b, p1.unpoisoned());
+ ASSERT_EQ(nullptr, p2.unpoisoned());
+
+ PoisonedUniquePtr<PoisonA, int[]> p3(c);
+ PoisonedUniquePtr<PoisonB, int[]> p4(d);
+ ASSERT_EQ(c, p3.unpoisoned());
+ ASSERT_EQ(d, p4.unpoisoned());
+ p3 = WTFMove(p4);
+ ASSERT_EQ(d, p3.unpoisoned());
+ ASSERT_EQ(nullptr, p4.unpoisoned());
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ptr = a;
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> ptr(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+ ptr = WTFMove(ptr);
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
+ ASSERT_EQ(a, ptr.unpoisoned());
+ }
+}
+
+TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, Swap)
+{
+ {
+ auto* a = new int[arraySize];
+ auto* b = new int[arraySize];
+ fillArray(a, arraySize);
+ fillArray(b, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, int[]> p2;
+ ASSERT_EQ(p1.unpoisoned(), a);
+ ASSERT_TRUE(!p2.bits());
+ ASSERT_TRUE(!p2.unpoisoned());
+ p2.swap(p1);
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_EQ(p2.unpoisoned(), a);
+
+ PoisonedUniquePtr<PoisonA, int[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, int[]> p4;
+ ASSERT_EQ(p3.unpoisoned(), b);
+ ASSERT_TRUE(!p4.bits());
+ ASSERT_TRUE(!p4.unpoisoned());
+ p4.swap(p3);
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_EQ(p4.unpoisoned(), b);
+ }
+
+ {
+ auto* a = new int[arraySize];
+ auto* b = new int[arraySize];
+ fillArray(a, arraySize);
+ fillArray(b, arraySize);
+
+ PoisonedUniquePtr<PoisonA, int[]> p1 = a;
+ PoisonedUniquePtr<PoisonA, int[]> p2;
+ ASSERT_EQ(p1.unpoisoned(), a);
+ ASSERT_TRUE(!p2.bits());
+ ASSERT_TRUE(!p2.unpoisoned());
+ swap(p1, p2);
+ ASSERT_TRUE(!p1.bits());
+ ASSERT_TRUE(!p1.unpoisoned());
+ ASSERT_EQ(p2.unpoisoned(), a);
+
+ PoisonedUniquePtr<PoisonA, int[]> p3 = b;
+ PoisonedUniquePtr<PoisonB, int[]> p4;
+ ASSERT_EQ(p3.unpoisoned(), b);
+ ASSERT_TRUE(!p4.bits());
+ ASSERT_TRUE(!p4.unpoisoned());
+ swap(p3, p4);
+ ASSERT_TRUE(!p3.bits());
+ ASSERT_TRUE(!p3.unpoisoned());
+ ASSERT_EQ(p4.unpoisoned(), b);
+ }
+}
+
+static PoisonedUniquePtr<PoisonA, int[]> poisonedPtrFoo(int* ptr)
+{
+ return PoisonedUniquePtr<PoisonA, int[]>(ptr);
+}
+
+TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, ReturnValue)
+{
+ {
+ auto* a = new int[arraySize];
+ fillArray(a, arraySize);
+
+ auto ptr = poisonedPtrFoo(a);
+ ASSERT_EQ(a, ptr.unpoisoned());
+ ASSERT_EQ(a, &*ptr);
+ for (auto i = 0; i < arraySize; ++i)
+ ASSERT_EQ(a[i], ptr[i]);
+ }
+}
+
+} // namespace TestWebKitAPI
+