Diff
Modified: branches/safari-537-branch/Source/_javascript_Core/API/JSStringRef.cpp (152471 => 152472)
--- branches/safari-537-branch/Source/_javascript_Core/API/JSStringRef.cpp 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/_javascript_Core/API/JSStringRef.cpp 2013-07-08 23:47:25 UTC (rev 152472)
@@ -25,6 +25,7 @@
#include "config.h"
#include "JSStringRef.h"
+#include "JSStringRefPrivate.h"
#include "InitializeThreading.h"
#include "OpaqueJSString.h"
@@ -59,6 +60,12 @@
return OpaqueJSString::create().leakRef();
}
+JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars)
+{
+ initializeThreading();
+ return OpaqueJSString::create(StringImpl::createWithoutCopying(chars, numChars, WTF::DoesNotHaveTerminatingNullCharacter)).leakRef();
+}
+
JSStringRef JSStringRetain(JSStringRef string)
{
string->ref();
Copied: branches/safari-537-branch/Source/_javascript_Core/API/JSStringRefPrivate.h (from rev 152052, trunk/Source/_javascript_Core/API/JSStringRefPrivate.h) (0 => 152472)
--- branches/safari-537-branch/Source/_javascript_Core/API/JSStringRefPrivate.h (rev 0)
+++ branches/safari-537-branch/Source/_javascript_Core/API/JSStringRefPrivate.h 2013-07-08 23:47:25 UTC (rev 152472)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef JSStringRefPrivate_h
+#define JSStringRefPrivate_h
+
+#include <_javascript_Core/JSStringRef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JS_EXPORT JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSStringRefPrivate_h */
Modified: branches/safari-537-branch/Source/_javascript_Core/API/OpaqueJSString.h (152471 => 152472)
--- branches/safari-537-branch/Source/_javascript_Core/API/OpaqueJSString.h 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/_javascript_Core/API/OpaqueJSString.h 2013-07-08 23:47:25 UTC (rev 152472)
@@ -70,12 +70,8 @@
}
OpaqueJSString(const String& string)
+ : m_string(string.isolatedCopy())
{
- // Make a copy of the source string.
- if (string.is8Bit())
- m_string = String(string.characters8(), string.length());
- else
- m_string = String(string.characters16(), string.length());
}
OpaqueJSString(const LChar* characters, unsigned length)
Modified: branches/safari-537-branch/Source/_javascript_Core/API/tests/testapi.c (152471 => 152472)
--- branches/safari-537-branch/Source/_javascript_Core/API/tests/testapi.c 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/_javascript_Core/API/tests/testapi.c 2013-07-08 23:47:25 UTC (rev 152472)
@@ -28,6 +28,7 @@
#include "JSContextRefPrivate.h"
#include "JSObjectRefPrivate.h"
#include "JSScriptRefPrivate.h"
+#include "JSStringRefPrivate.h"
#include <math.h>
#define ASSERT_DISABLED 0
#include <wtf/Assertions.h>
@@ -1205,6 +1206,11 @@
free(buffer);
JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);
+ JSChar constantString[] = { 'H', 'e', 'l', 'l', 'o', };
+ JSStringRef constantStringRef = JSStringCreateWithCharactersNoCopy(constantString, sizeof(constantString) / sizeof(constantString[0]));
+ ASSERT(JSStringGetCharactersPtr(constantStringRef) == constantString);
+ JSStringRelease(constantStringRef);
+
ASSERT(JSValueGetType(context, NULL) == kJSTypeNull);
ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
Modified: branches/safari-537-branch/Source/_javascript_Core/ChangeLog (152471 => 152472)
--- branches/safari-537-branch/Source/_javascript_Core/ChangeLog 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/_javascript_Core/ChangeLog 2013-07-08 23:47:25 UTC (rev 152472)
@@ -1,5 +1,34 @@
2013-07-08 Lucas Forschler <[email protected]>
+ Merge r152052
+
+ 2013-06-26 Anders Carlsson <[email protected]>
+
+ Add JSStringCreateWithCharactersNoCopy SPI
+ https://bugs.webkit.org/show_bug.cgi?id=118074
+ <rdar://problem/14279905>
+
+ Reviewed by Geoffrey Garen.
+
+ * API/JSStringRef.cpp:
+ (JSStringCreateWithCharactersNoCopy):
+ Create a new OpaqueJSString, using the newly added StringImpl::createWithoutCopying function.
+
+ * API/JSStringRefPrivate.h: Added.
+ Add a home for the JSStringCreateWithCharactersNoCopy function.
+
+ * API/OpaqueJSString.h:
+ (OpaqueJSString::OpaqueJSString):
+ Just call isolatedCopy on the passed in string.
+
+ * API/tests/testapi.c:
+ Add an API test for JSStringCreateWithCharactersNoCopy.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ Add new files.
+
+2013-07-08 Lucas Forschler <[email protected]>
+
Merge r152314
2013-07-02 Mark Hahnenberg <[email protected]>
Modified: branches/safari-537-branch/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (152471 => 152472)
--- branches/safari-537-branch/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-07-08 23:47:25 UTC (rev 152472)
@@ -506,6 +506,7 @@
14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */; };
14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F7256414EE265E00B1652B /* WeakHandleOwner.h */; settings = {ATTRIBUTES = (Private, ); }; };
14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACF7376171CA6FB00C9BB1E /* Weak.cpp */; };
2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */; };
2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; };
@@ -1378,6 +1379,7 @@
14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakHandleOwner.cpp; sourceTree = "<group>"; };
14F7256414EE265E00B1652B /* WeakHandleOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHandleOwner.h; sourceTree = "<group>"; };
14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
+ 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRefPrivate.h; sourceTree = "<group>"; };
1ACF7376171CA6FB00C9BB1E /* Weak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Weak.cpp; sourceTree = "<group>"; };
1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
1C9051430BA9E8A70081E9D0 /* _javascript_Core.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = _javascript_Core.xcconfig; sourceTree = "<group>"; };
@@ -2247,6 +2249,7 @@
E124A8F60E555775003091F1 /* OpaqueJSString.cpp */,
E124A8F50E555775003091F1 /* OpaqueJSString.h */,
5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */,
+ 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */,
C25D709916DE99F400FCA6BC /* JSManagedValue.mm */,
C25D709A16DE99F400FCA6BC /* JSManagedValue.h */,
C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */,
@@ -3038,6 +3041,7 @@
144836E7132DA7BE005BE785 /* ConservativeRoots.h in Headers */,
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */,
C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
+ 1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */,
C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
Modified: branches/safari-537-branch/Source/WTF/ChangeLog (152471 => 152472)
--- branches/safari-537-branch/Source/WTF/ChangeLog 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/WTF/ChangeLog 2013-07-08 23:47:25 UTC (rev 152472)
@@ -1,5 +1,39 @@
2013-07-08 Lucas Forschler <[email protected]>
+ Merge r152052
+
+ 2013-06-26 Anders Carlsson <[email protected]>
+
+ Add JSStringCreateWithCharactersNoCopy SPI
+ https://bugs.webkit.org/show_bug.cgi?id=118074
+ <rdar://problem/14279905>
+
+ Reviewed by Geoffrey Garen.
+
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::createFromLiteral):
+ Use the new ConstructWithoutCopying constructor, passing DoesHaveTerminatingNullCharacter to it.
+ Change the other createFromLiteral overload to just call the first.
+
+ (WTF::StringImpl::createWithoutCopying):
+ Add helper functions for creating strings that shouldn't copy their underlying data.
+
+ * wtf/text/StringImpl.h:
+ (WTF::StringImpl::StringImpl):
+ Rename the ConstructFromLiteralTag constructor enum to ConstructWithoutCopyingTag. Change the constructor
+ to take an enum that states whether the string has a terminating null character or not.
+
+ (WTF::StringImpl::createFromLiteral):
+ Call createWithoutCopying.
+
+ (WTF::StringImpl::requiresCopy):
+ Rename this from isASCIILiteral() and make it more generic so it can handle 16-bit strings as well.
+
+ (WTF::StringImpl::isolatedCopy):
+ If this string doesn't have to be copied, just create a new StringImpl object that references the current data.
+
+2013-07-08 Lucas Forschler <[email protected]>
+
Merge r152306
2013-07-02 Geoffrey Garen <[email protected]>
Modified: branches/safari-537-branch/Source/WTF/wtf/text/StringImpl.cpp (152471 => 152472)
--- branches/safari-537-branch/Source/WTF/wtf/text/StringImpl.cpp 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/WTF/wtf/text/StringImpl.cpp 2013-07-08 23:47:25 UTC (rev 152472)
@@ -158,17 +158,30 @@
{
ASSERT_WITH_MESSAGE(length, "Use StringImpl::empty() to create an empty string");
ASSERT(charactersAreAllASCII<LChar>(reinterpret_cast<const LChar*>(characters), length));
- return adoptRef(new StringImpl(characters, length, ConstructFromLiteral));
+ return adoptRef(new StringImpl(reinterpret_cast<const LChar*>(characters), length, DoesHaveTerminatingNullCharacter, ConstructWithoutCopying));
}
PassRefPtr<StringImpl> StringImpl::createFromLiteral(const char* characters)
{
- size_t length = strlen(characters);
- ASSERT_WITH_MESSAGE(length, "Use StringImpl::empty() to create an empty string");
- ASSERT(charactersAreAllASCII<LChar>(reinterpret_cast<const LChar*>(characters), length));
- return adoptRef(new StringImpl(characters, length, ConstructFromLiteral));
+ return createFromLiteral(characters, strlen(characters));
}
+PassRefPtr<StringImpl> StringImpl::createWithoutCopying(const UChar* characters, unsigned length, HasTerminatingNullCharacter hasTerminatingNullCharacter)
+{
+ if (!length)
+ return empty();
+
+ return adoptRef(new StringImpl(characters, length, hasTerminatingNullCharacter, ConstructWithoutCopying));
+}
+
+PassRefPtr<StringImpl> StringImpl::createWithoutCopying(const LChar* characters, unsigned length, HasTerminatingNullCharacter hasTerminatingNullCharacter)
+{
+ if (!length)
+ return empty();
+
+ return adoptRef(new StringImpl(characters, length, hasTerminatingNullCharacter, ConstructWithoutCopying));
+}
+
PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
{
if (!length) {
Modified: branches/safari-537-branch/Source/WTF/wtf/text/StringImpl.h (152471 => 152472)
--- branches/safari-537-branch/Source/WTF/wtf/text/StringImpl.h 2013-07-08 23:41:14 UTC (rev 152471)
+++ branches/safari-537-branch/Source/WTF/wtf/text/StringImpl.h 2013-07-08 23:47:25 UTC (rev 152472)
@@ -68,8 +68,17 @@
struct UCharBufferTranslator;
template<typename> class RetainPtr;
-enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
+enum TextCaseSensitivity {
+ TextCaseSensitive,
+ TextCaseInsensitive
+};
+enum HasTerminatingNullCharacter {
+ DoesNotHaveTerminatingNullCharacter,
+ DoesHaveTerminatingNullCharacter,
+};
+
+
typedef bool (*CharacterMatchFunctionPtr)(UChar);
typedef bool (*IsWhiteSpaceFunctionPtr)(UChar);
@@ -239,17 +248,31 @@
STRING_STATS_ADD_8BIT_STRING(m_length);
}
- enum ConstructFromLiteralTag { ConstructFromLiteral };
- StringImpl(const char* characters, unsigned length, ConstructFromLiteralTag)
+ enum ConstructWithoutCopyingTag { ConstructWithoutCopying };
+ StringImpl(const UChar* characters, unsigned length, HasTerminatingNullCharacter hasTerminatingNullCharacter, ConstructWithoutCopyingTag)
: m_refCount(s_refCountIncrement)
, m_length(length)
- , m_data8(reinterpret_cast<const LChar*>(characters))
+ , m_data16(characters)
, m_buffer(0)
- , m_hashAndFlags(s_hashFlag8BitBuffer | BufferInternal | s_hashFlagHasTerminatingNullCharacter)
+ , m_hashAndFlags(BufferInternal | (hasTerminatingNullCharacter ? s_hashFlagHasTerminatingNullCharacter : 0))
{
+ ASSERT(m_data16);
+ ASSERT(m_length);
+ ASSERT(!(m_hashAndFlags & s_hashFlagHasTerminatingNullCharacter) || !characters[length]);
+
+ STRING_STATS_ADD_16BIT_STRING(0);
+ }
+
+ StringImpl(const LChar* characters, unsigned length, HasTerminatingNullCharacter hasTerminatingNullCharacter, ConstructWithoutCopyingTag)
+ : m_refCount(s_refCountIncrement)
+ , m_length(length)
+ , m_data8(characters)
+ , m_buffer(0)
+ , m_hashAndFlags(s_hashFlag8BitBuffer | BufferInternal | (hasTerminatingNullCharacter ? s_hashFlagHasTerminatingNullCharacter : 0))
+ {
ASSERT(m_data8);
ASSERT(m_length);
- ASSERT(!characters[length]);
+ ASSERT(!(m_hashAndFlags & s_hashFlagHasTerminatingNullCharacter) || !characters[length]);
STRING_STATS_ADD_8BIT_STRING(0);
}
@@ -392,17 +415,22 @@
return adoptRef(new StringImpl(rep->m_data16 + offset, length, ownerRep));
}
- WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters, unsigned length);
template<unsigned charactersCount>
ALWAYS_INLINE static PassRefPtr<StringImpl> createFromLiteral(const char (&characters)[charactersCount])
{
COMPILE_ASSERT(charactersCount > 1, StringImplFromLiteralNotEmpty);
COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), StringImplFromLiteralCannotOverflow);
- return createFromLiteral(characters, charactersCount - 1);
+ return createWithoutCopying(reinterpret_cast<const LChar*>(characters), charactersCount - 1, DoesHaveTerminatingNullCharacter);
}
+
+ // FIXME: Transition off of these functions to createWithoutCopying instead.
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters, unsigned length);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters);
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createWithoutCopying(const UChar* characters, unsigned length, HasTerminatingNullCharacter);
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createWithoutCopying(const LChar* characters, unsigned length, HasTerminatingNullCharacter);
+
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createUninitialized(unsigned length, LChar*& data);
WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);
template <typename T> static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, T*& output)
@@ -736,10 +764,14 @@
#endif
private:
+ bool requiresCopy() const
+ {
+ if (bufferOwnership() != BufferInternal)
+ return true;
- bool isASCIILiteral() const
- {
- return is8Bit() && bufferOwnership() == BufferInternal && reinterpret_cast<const void*>(m_data8) != reinterpret_cast<const void*>(this + 1);
+ if (is8Bit())
+ return reinterpret_cast<const void*>(m_data8) == reinterpret_cast<const void*>(this + 1);
+ return reinterpret_cast<const void*>(m_data16) == reinterpret_cast<const void*>(this + 1);
}
// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
@@ -1328,8 +1360,12 @@
inline PassRefPtr<StringImpl> StringImpl::isolatedCopy() const
{
- if (isASCIILiteral())
- return StringImpl::createFromLiteral(reinterpret_cast<const char*>(m_data8), m_length);
+ if (!requiresCopy()) {
+ if (is8Bit())
+ return StringImpl::createWithoutCopying(m_data8, m_length, hasTerminatingNullCharacter() ? DoesHaveTerminatingNullCharacter : DoesNotHaveTerminatingNullCharacter);
+ return StringImpl::createWithoutCopying(m_data16, m_length, hasTerminatingNullCharacter() ? DoesHaveTerminatingNullCharacter : DoesNotHaveTerminatingNullCharacter);
+ }
+
if (is8Bit())
return create(m_data8, m_length);
return create(m_data16, m_length);