[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.18-1-697-g2f78b87
barraclough at apple.com
barraclough at apple.com
Wed Jan 20 22:28:53 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 34721408b380637ef80d1d9562ed6ec109342403
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jan 19 07:22:51 2010 +0000
Revert r53454, since it causes much sadness in this world.
Patch by Gavin Barraclough <barraclough at apple.com> on 2010-01-18
Reviewed by NOBODY (build fix).
* runtime/UString.cpp:
(JSC::UString::spliceSubstringsWithSeparators):
(JSC::UString::replaceRange):
* runtime/UStringImpl.cpp:
(JSC::UStringImpl::baseSharedBuffer):
(JSC::UStringImpl::sharedBuffer):
(JSC::UStringImpl::~UStringImpl):
* runtime/UStringImpl.h:
(JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
(JSC::UntypedPtrAndBitfield::asPtr):
(JSC::UntypedPtrAndBitfield::operator&=):
(JSC::UntypedPtrAndBitfield::operator|=):
(JSC::UntypedPtrAndBitfield::operator&):
(JSC::UStringImpl::create):
(JSC::UStringImpl::cost):
(JSC::UStringImpl::isIdentifier):
(JSC::UStringImpl::setIsIdentifier):
(JSC::UStringImpl::ref):
(JSC::UStringImpl::deref):
(JSC::UStringImpl::checkConsistency):
(JSC::UStringImpl::UStringImpl):
(JSC::UStringImpl::bufferOwnerString):
(JSC::UStringImpl::bufferOwnership):
(JSC::UStringImpl::isStatic):
* wtf/StringHashFunctions.h:
(WTF::stringHash):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53456 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 50329b4..90d8e6d 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,36 @@
+2010-01-18 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Revert r53454, since it causes much sadness in this world.
+
+ * runtime/UString.cpp:
+ (JSC::UString::spliceSubstringsWithSeparators):
+ (JSC::UString::replaceRange):
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::baseSharedBuffer):
+ (JSC::UStringImpl::sharedBuffer):
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
+ (JSC::UntypedPtrAndBitfield::asPtr):
+ (JSC::UntypedPtrAndBitfield::operator&=):
+ (JSC::UntypedPtrAndBitfield::operator|=):
+ (JSC::UntypedPtrAndBitfield::operator&):
+ (JSC::UStringImpl::create):
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::isIdentifier):
+ (JSC::UStringImpl::setIsIdentifier):
+ (JSC::UStringImpl::ref):
+ (JSC::UStringImpl::deref):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::UStringImpl):
+ (JSC::UStringImpl::bufferOwnerString):
+ (JSC::UStringImpl::bufferOwnership):
+ (JSC::UStringImpl::isStatic):
+ * wtf/StringHashFunctions.h:
+ (WTF::stringHash):
+
2010-01-18 Geoffrey Garen <ggaren at apple.com>
Reviewed by Oliver Hunt.
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index 0c4dc05..e75a05c 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -348,6 +348,8 @@ UString UString::from(double d)
UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
{
+ m_rep->checkConsistency();
+
if (rangeCount == 1 && separatorCount == 0) {
int thisSize = size();
int position = substringRanges[0].position;
@@ -389,6 +391,8 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in
UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const
{
+ m_rep->checkConsistency();
+
int replacementLength = replacement.size();
int totalLength = size() - rangeLength + replacementLength;
if (totalLength == 0)
diff --git a/JavaScriptCore/runtime/UStringImpl.cpp b/JavaScriptCore/runtime/UStringImpl.cpp
index 813d45b..4b0d1c9 100644
--- a/JavaScriptCore/runtime/UStringImpl.cpp
+++ b/JavaScriptCore/runtime/UStringImpl.cpp
@@ -35,48 +35,48 @@ using namespace std;
namespace JSC {
+SharedUChar* UStringImpl::baseSharedBuffer()
+{
+ ASSERT((bufferOwnership() == BufferShared)
+ || ((bufferOwnership() == BufferOwned) && !m_dataBuffer.asPtr<void*>()));
+
+ if (bufferOwnership() != BufferShared)
+ m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef(), BufferShared);
+
+ return m_dataBuffer.asPtr<SharedUChar*>();
+}
+
SharedUChar* UStringImpl::sharedBuffer()
{
- if (m_length < s_minLengthToShare || isStatic())
+ if (m_length < s_minLengthToShare)
return 0;
+ ASSERT(!isStatic());
- switch (bufferOwnership()) {
- case BufferInternal:
+ UStringImpl* owner = bufferOwnerString();
+ if (owner->bufferOwnership() == BufferInternal)
return 0;
- case BufferOwned:
- m_bufferShared = SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef();
- m_refCountAndFlags &= ~s_refCountMaskBufferOwnership;
- m_refCountAndFlags |= BufferShared;
- return m_bufferShared;
- case BufferSubstring:
- return m_bufferSubstring->sharedBuffer();
- case BufferShared:
- return m_bufferShared;
- }
- ASSERT_NOT_REACHED();
- return 0;
+ return owner->baseSharedBuffer();
}
UStringImpl::~UStringImpl()
{
ASSERT(!isStatic());
+ checkConsistency();
if (isIdentifier())
Identifier::remove(this);
- switch (bufferOwnership()) {
- case BufferInternal:
- return;
- case BufferOwned:
- fastFree(m_data);
- return;
- case BufferSubstring:
- m_bufferSubstring->deref();
- return;
- case BufferShared:
- m_bufferSubstring->deref();
+ if (bufferOwnership() != BufferInternal) {
+ if (bufferOwnership() == BufferOwned)
+ fastFree(m_data);
+ else if (bufferOwnership() == BufferSubstring)
+ m_dataBuffer.asPtr<UStringImpl*>()->deref();
+ else {
+ ASSERT(bufferOwnership() == BufferShared);
+ m_dataBuffer.asPtr<SharedUChar*>()->deref();
+ }
}
}
-} // namespace JSC
+}
diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h
index acdd1b8..abed637 100644
--- a/JavaScriptCore/runtime/UStringImpl.h
+++ b/JavaScriptCore/runtime/UStringImpl.h
@@ -40,6 +40,48 @@ class IdentifierTable;
typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
+class UntypedPtrAndBitfield {
+public:
+ UntypedPtrAndBitfield() {}
+
+ UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue)
+ : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue)
+#ifndef NDEBUG
+ , m_leaksPtr(ptrValue)
+#endif
+ {
+ ASSERT(ptrValue == asPtr<void*>());
+ ASSERT((*this & ~s_alignmentMask) == bitValue);
+ }
+
+ template<typename T>
+ T asPtr() const { return reinterpret_cast<T>(m_value & s_alignmentMask); }
+
+ UntypedPtrAndBitfield& operator&=(uintptr_t bits)
+ {
+ m_value &= bits | s_alignmentMask;
+ return *this;
+ }
+
+ UntypedPtrAndBitfield& operator|=(uintptr_t bits)
+ {
+ m_value |= bits & ~s_alignmentMask;
+ return *this;
+ }
+
+ uintptr_t operator&(uintptr_t mask) const
+ {
+ return m_value & mask & ~s_alignmentMask;
+ }
+
+private:
+ static const uintptr_t s_alignmentMask = ~static_cast<uintptr_t>(0x7);
+ uintptr_t m_value;
+#ifndef NDEBUG
+ void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced.
+#endif
+};
+
class UStringImpl : Noncopyable {
public:
template<size_t inlineCapacity>
@@ -63,9 +105,8 @@ public:
static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, int offset, int length)
{
ASSERT(rep);
- if (rep->bufferOwnership() == BufferSubstring)
- return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->m_bufferSubstring));
- return adoptRef(new UStringImpl(rep->m_data + offset, length, rep));
+ rep->checkConsistency();
+ return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString()));
}
static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar> sharedBuffer, UChar* buffer, int length)
@@ -110,28 +151,21 @@ public:
{
// For substrings, return the cost of the base string.
if (bufferOwnership() == BufferSubstring)
- return m_bufferSubstring->cost();
- if (m_refCountAndFlags & s_refCountFlagHasReportedCost)
+ return m_dataBuffer.asPtr<UStringImpl*>()->cost();
+
+ if (m_dataBuffer & s_reportedCostBit)
return 0;
- ASSERT(!isStatic());
- m_refCountAndFlags |= s_refCountFlagHasReportedCost;
+ m_dataBuffer |= s_reportedCostBit;
return m_length;
}
unsigned hash() const { if (!m_hash) m_hash = computeHash(data(), m_length); return m_hash; }
unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers
void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers
- bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
- void setIsIdentifier(bool isIdentifier)
- {
- ASSERT(!isStatic());
- if (isIdentifier)
- m_refCountAndFlags |= s_refCountFlagIsIdentifier;
- else
- m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
- }
+ bool isIdentifier() const { return m_isIdentifier; }
+ void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; }
- UStringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; }
- ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) delete this; }
+ UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; }
+ ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; }
static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
{
@@ -149,6 +183,14 @@ public:
static UStringImpl& null() { return *s_null; }
static UStringImpl& empty() { return *s_empty; }
+ ALWAYS_INLINE void checkConsistency() const
+ {
+ // There is no recursion of substrings.
+ ASSERT(bufferOwnerString()->bufferOwnership() != BufferSubstring);
+ // Static strings cannot be put in identifier tables, because they are globally shared.
+ ASSERT(!isStatic() || !isIdentifier());
+ }
+
private:
enum BufferOwnership {
BufferInternal,
@@ -163,12 +205,14 @@ private:
// Used to construct normal strings with an internal or external buffer.
UStringImpl(UChar* data, int length, BufferOwnership ownership)
: m_data(data)
- , m_buffer(0)
, m_length(length)
- , m_refCountAndFlags(s_refCountIncrement | ownership)
+ , m_refCount(s_refCountIncrement)
, m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(0, ownership)
{
ASSERT((ownership == BufferInternal) || (ownership == BufferOwned));
+ checkConsistency();
}
// Used to construct static strings, which have an special refCount that can never hit zero.
@@ -177,37 +221,42 @@ private:
enum StaticStringConstructType { ConstructStaticString };
UStringImpl(UChar* data, int length, StaticStringConstructType)
: m_data(data)
- , m_buffer(0)
, m_length(length)
- , m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagHasReportedCost | BufferOwned)
+ , m_refCount(s_staticRefCountInitialValue)
, m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(0, BufferOwned)
{
+ checkConsistency();
}
// Used to create new strings that are a substring of an existing string.
UStringImpl(UChar* data, int length, PassRefPtr<UStringImpl> base)
: m_data(data)
- , m_bufferSubstring(base.releaseRef())
, m_length(length)
- , m_refCountAndFlags(s_refCountIncrement | BufferSubstring)
+ , m_refCount(s_refCountIncrement)
, m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(base.releaseRef(), BufferSubstring)
{
// Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes
// that all pointers will be at least 8-byte aligned, we cannot guarantee that of
// UStringImpls that are not heap allocated.
- ASSERT(m_bufferSubstring->size());
- ASSERT(!m_bufferSubstring->isStatic());
- ASSERT(m_bufferSubstring->bufferOwnership() != BufferSubstring);
+ ASSERT(m_dataBuffer.asPtr<UStringImpl*>()->size());
+ ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->isStatic());
+ checkConsistency();
}
// Used to construct new strings sharing an existing shared buffer.
UStringImpl(UChar* data, int length, PassRefPtr<SharedUChar> sharedBuffer)
: m_data(data)
- , m_bufferShared(sharedBuffer.releaseRef())
, m_length(length)
- , m_refCountAndFlags(s_refCountIncrement | BufferShared)
+ , m_refCount(s_refCountIncrement)
, m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared)
{
+ checkConsistency();
}
using Noncopyable::operator new;
@@ -216,30 +265,28 @@ private:
~UStringImpl();
// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
- static const unsigned s_minLengthToShare = 10;
+ static const int s_minLengthToShare = 10;
static const unsigned s_copyCharsInlineCutOff = 20;
-
- bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
- BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
-
+ static const uintptr_t s_bufferOwnershipMask = 3;
+ static const uintptr_t s_reportedCostBit = 4;
// We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2.
// We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero.
- static const unsigned s_refCountMask = 0xFFFFFFF0;
- static const unsigned s_refCountIncrement = 0x20;
- static const unsigned s_refCountFlagStatic = 0x10;
- static const unsigned s_refCountFlagHasReportedCost = 0x8;
- static const unsigned s_refCountFlagIsIdentifier = 0x4;
- static const unsigned s_refCountMaskBufferOwnership = 0x3;
+ static const int s_refCountIncrement = 2;
+ static const int s_staticRefCountInitialValue = 1;
+
+ UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; }
+ const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; }
+ SharedUChar* baseSharedBuffer();
+ unsigned bufferOwnership() const { return m_dataBuffer & s_bufferOwnershipMask; }
+ bool isStatic() const { return m_refCount & 1; }
+ // unshared data
UChar* m_data;
- union {
- void* m_buffer;
- UStringImpl* m_bufferSubstring;
- SharedUChar* m_bufferShared;
- };
- unsigned m_length;
- unsigned m_refCountAndFlags;
- mutable unsigned m_hash;
+ int m_length;
+ unsigned m_refCount;
+ mutable unsigned m_hash : 31;
+ mutable unsigned m_isIdentifier : 1;
+ UntypedPtrAndBitfield m_dataBuffer;
JS_EXPORTDATA static UStringImpl* s_null;
JS_EXPORTDATA static UStringImpl* s_empty;
diff --git a/JavaScriptCore/wtf/StringHashFunctions.h b/JavaScriptCore/wtf/StringHashFunctions.h
index 703182c..07f117f 100644
--- a/JavaScriptCore/wtf/StringHashFunctions.h
+++ b/JavaScriptCore/wtf/StringHashFunctions.h
@@ -60,11 +60,13 @@ inline unsigned stringHash(const UChar* data, unsigned length)
hash += hash >> 15;
hash ^= hash << 10;
+ hash &= 0x7fffffff;
+
// this avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet", using a value that is likely to be
// effectively the same as 0 when the low bits are masked
if (hash == 0)
- hash = 0x80000000;
+ hash = 0x40000000;
return hash;
}
@@ -98,11 +100,13 @@ inline unsigned stringHash(const char* data, unsigned length)
hash += hash >> 15;
hash ^= hash << 10;
+ hash &= 0x7fffffff;
+
// this avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet", using a value that is likely to be
// effectively the same as 0 when the low bits are masked
if (hash == 0)
- hash = 0x80000000;
+ hash = 0x40000000;
return hash;
}
@@ -137,11 +141,13 @@ inline unsigned stringHash(const char* data)
hash += hash >> 15;
hash ^= hash << 10;
+ hash &= 0x7fffffff;
+
// This avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet", using a value that is likely to be
// effectively the same as 0 when the low bits are masked.
if (hash == 0)
- hash = 0x80000000;
+ hash = 0x40000000;
return hash;
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list