summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@nokia.com>2010-04-06 10:36:47 (GMT)
committerJocelyn Turcotte <jocelyn.turcotte@nokia.com>2010-04-06 10:36:47 (GMT)
commitbb35b65bbfba82e0dd0ac306d3dab54436cdaff6 (patch)
tree8174cb262a960ff7b2e4aa8f1aaf154db71d2636 /src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp
parent4b27d0d887269583a0f76e922948f8c25e96ab88 (diff)
downloadQt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.zip
Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.tar.gz
Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.tar.bz2
Update src/3rdparty/webkit from trunk.
Imported from 839d8709327f925aacb3b6362c06152594def97e in branch qtwebkit-2.0 of repository git://gitorious.org/+qtwebkit-developers/webkit/qtwebkit.git Rubber-stamped-by: Simon Hausmann
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp
new file mode 100644
index 0000000..aba63ad
--- /dev/null
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/UStringImpl.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2009 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 "UStringImpl.h"
+
+#include "Identifier.h"
+#include "StdLibExtras.h"
+#include "UString.h"
+#include <wtf/unicode/UTF8.h>
+
+using namespace WTF::Unicode;
+using namespace std;
+
+namespace JSC {
+
+static const unsigned minLengthToShare = 20;
+
+UStringImpl::~UStringImpl()
+{
+ ASSERT(!isStatic());
+
+ if (isIdentifier())
+ Identifier::remove(this);
+
+ BufferOwnership ownership = bufferOwnership();
+ if (ownership != BufferInternal) {
+ if (ownership == BufferOwned) {
+ ASSERT(!m_sharedBuffer);
+ ASSERT(m_data);
+ fastFree(const_cast<UChar*>(m_data));
+ } else if (ownership == BufferSubstring) {
+ ASSERT(m_substringBuffer);
+ m_substringBuffer->deref();
+ } else {
+ ASSERT(ownership == BufferShared);
+ ASSERT(m_sharedBuffer);
+ m_sharedBuffer->deref();
+ }
+ }
+}
+
+UStringImpl* UStringImpl::empty()
+{
+ // FIXME: This works around a bug in our port of PCRE, that a regular expression
+ // run on the empty string may still perform a read from the first element, and
+ // as such we need this to be a valid pointer. No code should ever be reading
+ // from a zero length string, so this should be able to be a non-null pointer
+ // into the zero-page.
+ // Replace this with 'reinterpret_cast<UChar*>(static_cast<intptr_t>(1))' once
+ // PCRE goes away.
+ static UChar emptyUCharData = 0;
+ DEFINE_STATIC_LOCAL(UStringImpl, emptyString, (&emptyUCharData, 0, ConstructStaticString));
+ return &emptyString;
+}
+
+PassRefPtr<UStringImpl> UStringImpl::createUninitialized(unsigned length, UChar*& data)
+{
+ if (!length) {
+ data = 0;
+ return empty();
+ }
+
+ // Allocate a single buffer large enough to contain the StringImpl
+ // struct as well as the data which it contains. This removes one
+ // heap allocation from this call.
+ if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
+ CRASH();
+ size_t size = sizeof(UStringImpl) + length * sizeof(UChar);
+ UStringImpl* string = static_cast<UStringImpl*>(fastMalloc(size));
+
+ data = reinterpret_cast<UChar*>(string + 1);
+ return adoptRef(new (string) UStringImpl(length));
+}
+
+PassRefPtr<UStringImpl> UStringImpl::create(const UChar* characters, unsigned length)
+{
+ if (!characters || !length)
+ return empty();
+
+ UChar* data;
+ PassRefPtr<UStringImpl> string = createUninitialized(length, data);
+ memcpy(data, characters, length * sizeof(UChar));
+ return string;
+}
+
+PassRefPtr<UStringImpl> UStringImpl::create(const char* characters, unsigned length)
+{
+ if (!characters || !length)
+ return empty();
+
+ UChar* data;
+ PassRefPtr<UStringImpl> string = createUninitialized(length, data);
+ for (unsigned i = 0; i != length; ++i) {
+ unsigned char c = characters[i];
+ data[i] = c;
+ }
+ return string;
+}
+
+PassRefPtr<UStringImpl> UStringImpl::create(const char* string)
+{
+ if (!string)
+ return empty();
+ return create(string, strlen(string));
+}
+
+PassRefPtr<UStringImpl> UStringImpl::create(PassRefPtr<SharedUChar> sharedBuffer, const UChar* buffer, unsigned length)
+{
+ if (!length)
+ return empty();
+ return adoptRef(new UStringImpl(buffer, length, sharedBuffer));
+}
+
+SharedUChar* UStringImpl::sharedBuffer()
+{
+ if (m_length < minLengthToShare)
+ return 0;
+ // All static strings are smaller that the minimim length to share.
+ ASSERT(!isStatic());
+
+ BufferOwnership ownership = bufferOwnership();
+
+ if (ownership == BufferInternal)
+ return 0;
+ if (ownership == BufferSubstring)
+ return m_substringBuffer->sharedBuffer();
+ if (ownership == BufferOwned) {
+ ASSERT(!m_sharedBuffer);
+ m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).releaseRef();
+ m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared;
+ }
+
+ ASSERT(bufferOwnership() == BufferShared);
+ ASSERT(m_sharedBuffer);
+ return m_sharedBuffer;
+}
+
+void URopeImpl::derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue)
+{
+ unsigned length = fiberCount();
+ for (unsigned i = 0; i < length; ++i) {
+ Fiber& fiber = fibers(i);
+ if (fiber->isRope()) {
+ URopeImpl* nextRope = static_cast<URopeImpl*>(fiber);
+ if (nextRope->hasOneRef())
+ workQueue.append(nextRope);
+ else
+ nextRope->deref();
+ } else
+ static_cast<UStringImpl*>(fiber)->deref();
+ }
+}
+
+void URopeImpl::destructNonRecursive()
+{
+ Vector<URopeImpl*, 32> workQueue;
+
+ derefFibersNonRecursive(workQueue);
+ delete this;
+
+ while (!workQueue.isEmpty()) {
+ URopeImpl* rope = workQueue.last();
+ workQueue.removeLast();
+ rope->derefFibersNonRecursive(workQueue);
+ delete rope;
+ }
+}
+
+} // namespace JSC