Title: [236599] trunk
Revision
236599
Author
[email protected]
Date
2018-09-28 08:56:54 -0700 (Fri, 28 Sep 2018)

Log Message

[WTF] Add ExternalStringImpl, a StringImpl for user controlled buffers
https://bugs.webkit.org/show_bug.cgi?id=189991

Patch by Koby Boyango <[email protected]> on 2018-09-28
Reviewed by Yusuke Suzuki.

Source/WTF:

* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/text/ExternalStringImpl.cpp: Added.
* wtf/text/ExternalStringImpl.h: Added.
* wtf/text/StringImpl.cpp:
* wtf/text/StringImpl.h:

Tools:

* TestWebKitAPI/Tests/WTF/StringImpl.cpp:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (236598 => 236599)


--- trunk/Source/WTF/ChangeLog	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Source/WTF/ChangeLog	2018-09-28 15:56:54 UTC (rev 236599)
@@ -1,3 +1,17 @@
+2018-09-28  Koby Boyango  <[email protected]>
+
+        [WTF] Add ExternalStringImpl, a StringImpl for user controlled buffers
+        https://bugs.webkit.org/show_bug.cgi?id=189991
+
+        Reviewed by Yusuke Suzuki.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/CMakeLists.txt:
+        * wtf/text/ExternalStringImpl.cpp: Added.
+        * wtf/text/ExternalStringImpl.h: Added.
+        * wtf/text/StringImpl.cpp:
+        * wtf/text/StringImpl.h:
+
 2018-09-27  Saam barati  <[email protected]>
 
         Verify the contents of AssemblerBuffer on arm64e

Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (236598 => 236599)


--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2018-09-28 15:56:54 UTC (rev 236599)
@@ -66,6 +66,7 @@
 		2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CDED0EE18115C38004DBA70 /* RunLoopCF.cpp */; };
 		2CDED0F318115C85004DBA70 /* RunLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CDED0F118115C85004DBA70 /* RunLoop.cpp */; };
 		3337DB9CE743410FAF076E17 /* StackTrace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 313EDEC9778E49C9BEA91CFC /* StackTrace.cpp */; };
+		50DE35F5215BB01500B979C7 /* ExternalStringImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50DE35F3215BB01500B979C7 /* ExternalStringImpl.cpp */; };
 		515F794E1CFC9F4A00CCED93 /* CrossThreadCopier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 515F794B1CFC9F4A00CCED93 /* CrossThreadCopier.cpp */; };
 		517F82D71FD22F3000DA3DEA /* CrossThreadTaskHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517F82D51FD22F2F00DA3DEA /* CrossThreadTaskHandler.cpp */; };
 		51F1752B1F3D486000C74950 /* PersistentCoders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F175261F3D486000C74950 /* PersistentCoders.cpp */; };
@@ -338,6 +339,8 @@
 		413FE8F51F8D2EAB00F6D7D7 /* CallbackAggregator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackAggregator.h; sourceTree = "<group>"; };
 		430B47871AAAAC1A001223DA /* StringCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringCommon.h; sourceTree = "<group>"; };
 		46BA9EAB1F4CD61E009A2BBC /* CompletionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompletionHandler.h; sourceTree = "<group>"; };
+		50DE35F3215BB01500B979C7 /* ExternalStringImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExternalStringImpl.cpp; sourceTree = "<group>"; };
+		50DE35F4215BB01500B979C7 /* ExternalStringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExternalStringImpl.h; sourceTree = "<group>"; };
 		513E170A1CD7D5BF00E3650B /* LoggingAccumulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoggingAccumulator.h; sourceTree = "<group>"; };
 		515F794B1CFC9F4A00CCED93 /* CrossThreadCopier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossThreadCopier.cpp; sourceTree = "<group>"; };
 		515F794C1CFC9F4A00CCED93 /* CrossThreadCopier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadCopier.h; sourceTree = "<group>"; };
@@ -1211,6 +1214,8 @@
 				0F8F2B9B172F2594007DBDA5 /* ConversionMode.h */,
 				A8A47321151A825B004123FF /* CString.cpp */,
 				A8A47322151A825B004123FF /* CString.h */,
+				50DE35F3215BB01500B979C7 /* ExternalStringImpl.cpp */,
+				50DE35F4215BB01500B979C7 /* ExternalStringImpl.h */,
 				26147B0815DDCCDC00DDB907 /* IntegerToStringConversion.h */,
 				93AC91A718942FC400244939 /* LChar.h */,
 				1C181C811D30797C00F5FA16 /* LineBreakIteratorPoolICU.h */,
@@ -1498,6 +1503,7 @@
 				A8A473B0151A825B004123FF /* double-conversion.cc in Sources */,
 				A8A473BA151A825B004123FF /* dtoa.cpp in Sources */,
 				143DDE9620C8BC37007F76FA /* Entitlements.mm in Sources */,
+				50DE35F5215BB01500B979C7 /* ExternalStringImpl.cpp in Sources */,
 				A8A473B3151A825B004123FF /* fast-dtoa.cc in Sources */,
 				0F7C5FB61D885CF20044F5E2 /* FastBitVector.cpp in Sources */,
 				A8A473C3151A825B004123FF /* FastMalloc.cpp in Sources */,

Modified: trunk/Source/WTF/wtf/CMakeLists.txt (236598 => 236599)


--- trunk/Source/WTF/wtf/CMakeLists.txt	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Source/WTF/wtf/CMakeLists.txt	2018-09-28 15:56:54 UTC (rev 236599)
@@ -287,6 +287,7 @@
     text/Base64.h
     text/CString.h
     text/ConversionMode.h
+    text/ExternalStringImpl.h
     text/IntegerToStringConversion.h
     text/LChar.h
     text/LineBreakIteratorPoolICU.h
@@ -418,6 +419,7 @@
     text/AtomicStringTable.cpp
     text/Base64.cpp
     text/CString.cpp
+    text/ExternalStringImpl.cpp
     text/LineEnding.cpp
     text/StringBuilder.cpp
     text/StringBuilderJSON.cpp

Added: trunk/Source/WTF/wtf/text/ExternalStringImpl.cpp (0 => 236599)


--- trunk/Source/WTF/wtf/text/ExternalStringImpl.cpp	                        (rev 0)
+++ trunk/Source/WTF/wtf/text/ExternalStringImpl.cpp	2018-09-28 15:56:54 UTC (rev 236599)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 mce sys Ltd. 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 "ExternalStringImpl.h"
+
+namespace WTF {
+
+WTF_EXPORT_PRIVATE Ref<ExternalStringImpl> ExternalStringImpl::create(const LChar* characters, unsigned length, ExternalStringImplFreeFunction&& free)
+{
+    return adoptRef(*new ExternalStringImpl(characters, length, WTFMove(free)));
+}
+
+WTF_EXPORT_PRIVATE Ref<ExternalStringImpl> ExternalStringImpl::create(const UChar* characters, unsigned length, ExternalStringImplFreeFunction&& free)
+{
+    return adoptRef(*new ExternalStringImpl(characters, length, WTFMove(free)));
+}
+
+ExternalStringImpl::ExternalStringImpl(const LChar* characters, unsigned length, ExternalStringImplFreeFunction&& free) 
+    : StringImpl(characters, length, ConstructWithoutCopying)
+    , m_free(WTFMove(free))
+{
+    ASSERT(m_free);
+    m_hashAndFlags = (m_hashAndFlags & ~s_hashMaskBufferOwnership) | BufferExternal;
+}
+
+ExternalStringImpl::ExternalStringImpl(const UChar* characters, unsigned length, ExternalStringImplFreeFunction&& free)
+    : StringImpl(characters, length, ConstructWithoutCopying)
+    , m_free(WTFMove(free))
+{
+    ASSERT(m_free);
+    m_hashAndFlags = (m_hashAndFlags & ~s_hashMaskBufferOwnership) | BufferExternal;
+}
+
+} // namespace WTF

Added: trunk/Source/WTF/wtf/text/ExternalStringImpl.h (0 => 236599)


--- trunk/Source/WTF/wtf/text/ExternalStringImpl.h	                        (rev 0)
+++ trunk/Source/WTF/wtf/text/ExternalStringImpl.h	2018-09-28 15:56:54 UTC (rev 236599)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 mce sys Ltd. 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/Function.h>
+#include <wtf/text/StringImpl.h>
+
+namespace WTF {
+
+class ExternalStringImpl;
+
+using ExternalStringImplFreeFunction = Function<void(ExternalStringImpl*, void*, unsigned)>;
+
+class ExternalStringImpl : public StringImpl {
+public:
+    WTF_EXPORT_PRIVATE static Ref<ExternalStringImpl> create(const LChar* characters, unsigned length, ExternalStringImplFreeFunction&&);
+    WTF_EXPORT_PRIVATE static Ref<ExternalStringImpl> create(const UChar* characters, unsigned length, ExternalStringImplFreeFunction&&);
+
+private:
+    friend class StringImpl;
+
+    ExternalStringImpl(const LChar* characters, unsigned length, ExternalStringImplFreeFunction&&);
+    ExternalStringImpl(const UChar* characters, unsigned length, ExternalStringImplFreeFunction&&);
+
+    ALWAYS_INLINE void freeExternalBuffer(void* buffer, unsigned bufferSize)
+    {
+        m_free(this, buffer, bufferSize);
+    }
+
+    ExternalStringImplFreeFunction m_free;
+};
+
+} // namespace WTF
+
+using WTF::ExternalStringImpl;

Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (236598 => 236599)


--- trunk/Source/WTF/wtf/text/StringImpl.cpp	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp	2018-09-28 15:56:54 UTC (rev 236599)
@@ -26,6 +26,7 @@
 #include "StringImpl.h"
 
 #include "AtomicString.h"
+#include "ExternalStringImpl.h"
 #include "StringBuffer.h"
 #include "StringHash.h"
 #include <wtf/ProcessID.h>
@@ -132,6 +133,12 @@
         fastFree(const_cast<LChar*>(m_data8));
         return;
     }
+    if (ownership == BufferExternal) {
+        auto* external = static_cast<ExternalStringImpl*>(this);
+        external->freeExternalBuffer(const_cast<LChar*>(m_data8), sizeInBytes());
+        external->m_free.~ExternalStringImplFreeFunction();
+        return;
+    }
 
     ASSERT(ownership == BufferSubstring);
     ASSERT(substringBuffer());

Modified: trunk/Source/WTF/wtf/text/StringImpl.h (236598 => 236599)


--- trunk/Source/WTF/wtf/text/StringImpl.h	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Source/WTF/wtf/text/StringImpl.h	2018-09-28 15:56:54 UTC (rev 236599)
@@ -166,6 +166,7 @@
     friend class PrivateSymbolImpl;
     friend class RegisteredSymbolImpl;
     friend class SymbolImpl;
+    friend class ExternalStringImpl;
 
     friend struct WTF::CStringTranslator;
     friend struct WTF::HashAndUTF8CharactersTranslator;
@@ -177,7 +178,7 @@
     template<typename> friend struct WTF::HashAndCharactersTranslator;
 
 public:
-    enum BufferOwnership { BufferInternal, BufferOwned, BufferSubstring };
+    enum BufferOwnership { BufferInternal, BufferOwned, BufferSubstring, BufferExternal };
 
     // The bottom 6 bits in the hash are flags.
     static constexpr const unsigned s_flagCount = 6;
@@ -281,6 +282,8 @@
     bool isSymbol() const { return m_hashAndFlags & s_hashFlagStringKindIsSymbol; }
     bool isAtomic() const { return m_hashAndFlags & s_hashFlagStringKindIsAtomic; }
     void setIsAtomic(bool);
+    
+    bool isExternal() const { return bufferOwnership() == BufferExternal; }
 
 #if STRING_STATS
     bool isSubString() const { return bufferOwnership() == BufferSubstring; }

Modified: trunk/Tools/ChangeLog (236598 => 236599)


--- trunk/Tools/ChangeLog	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Tools/ChangeLog	2018-09-28 15:56:54 UTC (rev 236599)
@@ -1,3 +1,12 @@
+2018-09-28  Koby Boyango  <[email protected]>
+
+        [WTF] Add ExternalStringImpl, a StringImpl for user controlled buffers
+        https://bugs.webkit.org/show_bug.cgi?id=189991
+
+        Reviewed by Yusuke Suzuki.
+
+        * TestWebKitAPI/Tests/WTF/StringImpl.cpp:
+
 2018-09-27  Ryan Haddad  <[email protected]>
 
         Update flakiness dashboard configuration for Mojave queues

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp (236598 => 236599)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp	2018-09-28 15:43:17 UTC (rev 236598)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp	2018-09-28 15:56:54 UTC (rev 236599)
@@ -27,6 +27,7 @@
 
 #include <wtf/Hasher.h>
 #include <wtf/NeverDestroyed.h>
+#include <wtf/text/ExternalStringImpl.h>
 #include <wtf/text/SymbolImpl.h>
 #include <wtf/text/WTFString.h>
 
@@ -737,4 +738,120 @@
     ASSERT_TRUE(symbol.isPrivate());
 }
 
+TEST(WTF, ExternalStringImplCreate8bit)
+{
+    constexpr LChar buffer[] = "hello";
+    constexpr size_t bufferStringLength = sizeof(buffer) - 1;
+    bool freeFunctionCalled = false;
+
+    {
+        auto external = ExternalStringImpl::create(buffer, bufferStringLength, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable {
+            freeFunctionCalled = true;
+        });
+
+        ASSERT_TRUE(external->isExternal());
+        ASSERT_TRUE(external->is8Bit());
+        ASSERT_FALSE(external->isSymbol());
+        ASSERT_FALSE(external->isAtomic());
+        ASSERT_EQ(external->length(), bufferStringLength);
+        ASSERT_EQ(external->characters8(), buffer);
+    }
+
+    ASSERT_TRUE(freeFunctionCalled);
+}
+
+TEST(WTF, ExternalStringImplCreate16bit)
+{
+    constexpr UChar buffer[] = { L'h', L'e', L'l', L'l', L'o', L'\0' };
+    constexpr size_t bufferStringLength = (sizeof(buffer) - 1) / sizeof(UChar);
+    bool freeFunctionCalled = false;
+
+    {
+        auto external = ExternalStringImpl::create(buffer, bufferStringLength, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable {
+            freeFunctionCalled = true;
+        });
+
+        ASSERT_TRUE(external->isExternal());
+        ASSERT_FALSE(external->is8Bit());
+        ASSERT_FALSE(external->isSymbol());
+        ASSERT_FALSE(external->isAtomic());
+        ASSERT_EQ(external->length(), bufferStringLength);
+        ASSERT_EQ(external->characters16(), buffer);
+    }
+
+    ASSERT_TRUE(freeFunctionCalled);
+}
+
+TEST(WTF, StringImplNotExternal)
+{
+    auto notExternal = stringFromUTF8("hello");
+    ASSERT_FALSE(notExternal->isExternal());
+}
+
+
+TEST(WTF, ExternalStringAtomic)
+{
+    constexpr LChar buffer[] = "hello";
+    constexpr size_t bufferStringLength = sizeof(buffer) - 1;
+    bool freeFunctionCalled = false;
+
+    {
+        auto external = ExternalStringImpl::create(buffer, bufferStringLength, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable {
+            freeFunctionCalled = true;
+        });    
+
+        ASSERT_TRUE(external->isExternal());
+        ASSERT_FALSE(external->isAtomic());
+        ASSERT_FALSE(external->isSymbol());
+        ASSERT_TRUE(external->is8Bit());
+        ASSERT_EQ(external->length(), bufferStringLength);
+        ASSERT_EQ(external->characters8(), buffer);
+
+        auto result = AtomicStringImpl::lookUp(external.ptr());
+        ASSERT_FALSE(result);
+
+        auto atomic = AtomicStringImpl::add(external.ptr());
+        ASSERT_TRUE(atomic->isExternal());
+        ASSERT_TRUE(atomic->isAtomic());
+        ASSERT_FALSE(atomic->isSymbol());
+        ASSERT_TRUE(atomic->is8Bit());
+        ASSERT_EQ(atomic->length(), external->length());
+        ASSERT_EQ(atomic->characters8(), external->characters8());
+
+        auto result2 = AtomicStringImpl::lookUp(external.ptr());
+        ASSERT_TRUE(result2);
+        ASSERT_EQ(atomic, result2);
+    }
+
+    ASSERT_TRUE(freeFunctionCalled);
+}
+
+TEST(WTF, ExternalStringToSymbol)
+{
+    constexpr LChar buffer[] = "hello";
+    constexpr size_t bufferStringLength = sizeof(buffer) - 1;
+    bool freeFunctionCalled = false;
+
+    {
+        auto external = ExternalStringImpl::create(buffer, bufferStringLength, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable {
+            freeFunctionCalled = true;
+        });    
+
+        ASSERT_TRUE(external->isExternal());
+        ASSERT_FALSE(external->isSymbol());
+        ASSERT_FALSE(external->isAtomic());
+
+        auto symbol = SymbolImpl::create(external);
+        ASSERT_FALSE(symbol->isExternal());
+        ASSERT_TRUE(symbol->isSymbol());
+        ASSERT_FALSE(symbol->isAtomic());
+        ASSERT_FALSE(symbol->isPrivate());
+        ASSERT_FALSE(symbol->isNullSymbol());
+        ASSERT_EQ(external->length(), symbol->length());
+        ASSERT_TRUE(equal(symbol.ptr(), buffer));
+    }
+
+    ASSERT_TRUE(freeFunctionCalled);
+}
+
 } // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to