[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

barraclough at apple.com barraclough at apple.com
Thu Apr 8 01:12:04 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 2d208f8c09e32c6121054ffcea457450991b7fcb
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Jan 18 07:36:45 2010 +0000

    https://bugs.webkit.org/show_bug.cgi?id=33731
    Remove UntypedPtrAndBitfield from UStringImpl (akin to PtrAndFlags).
    
    Reviewed by Oliver Hunt.
    
    This break the OS X Leaks tool.  Instead, free up some more bits from the refCount.
    
    * runtime/UStringImpl.cpp:
    (JSC::UStringImpl::sharedBuffer):
    (JSC::UStringImpl::~UStringImpl):
    * runtime/UStringImpl.h:
    (JSC::UStringImpl::cost):
    (JSC::UStringImpl::checkConsistency):
    (JSC::UStringImpl::UStringImpl):
    (JSC::UStringImpl::bufferOwnerString):
    (JSC::UStringImpl::):
    * wtf/StringHashFunctions.h:
    (WTF::stringHash):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53392 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 46d65fb..c3baea1 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -3,6 +3,27 @@
         Reviewed by Oliver Hunt.
 
         https://bugs.webkit.org/show_bug.cgi?id=33731
+        Remove UntypedPtrAndBitfield from UStringImpl (akin to PtrAndFlags).
+
+        This break the OS X Leaks tool.  Instead, free up some more bits from the refCount.
+
+        * runtime/UStringImpl.cpp:
+        (JSC::UStringImpl::sharedBuffer):
+        (JSC::UStringImpl::~UStringImpl):
+        * runtime/UStringImpl.h:
+        (JSC::UStringImpl::cost):
+        (JSC::UStringImpl::checkConsistency):
+        (JSC::UStringImpl::UStringImpl):
+        (JSC::UStringImpl::bufferOwnerString):
+        (JSC::UStringImpl::):
+        * wtf/StringHashFunctions.h:
+        (WTF::stringHash):
+
+2010-01-15  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=33731
         Remove uses of PtrAndFlags from JIT data stuctures.
 
         These break the OS X Leaks tool.  Free up a bit in CallLinkInfo, and invalid
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index e75a05c..0c4dc05 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -348,8 +348,6 @@ 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;
@@ -391,8 +389,6 @@ 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 4b0d1c9..813d45b 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)
+    if (m_length < s_minLengthToShare || isStatic())
         return 0;
-    ASSERT(!isStatic());
 
-    UStringImpl* owner = bufferOwnerString();
-    if (owner->bufferOwnership() == BufferInternal)
+    switch (bufferOwnership()) {
+    case 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;
+    }
 
-    return owner->baseSharedBuffer();
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
 UStringImpl::~UStringImpl()
 {
     ASSERT(!isStatic());
-    checkConsistency();
 
     if (isIdentifier())
         Identifier::remove(this);
 
-    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();
-        }
+    switch (bufferOwnership()) {
+    case BufferInternal:
+        return;
+    case BufferOwned:
+        fastFree(m_data);
+        return;
+    case BufferSubstring:
+        m_bufferSubstring->deref();
+        return;
+    case BufferShared:
+        m_bufferSubstring->deref();
     }
 }
 
-}
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h
index abed637..acdd1b8 100644
--- a/JavaScriptCore/runtime/UStringImpl.h
+++ b/JavaScriptCore/runtime/UStringImpl.h
@@ -40,48 +40,6 @@ 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>
@@ -105,8 +63,9 @@ public:
     static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, int offset, int length)
     {
         ASSERT(rep);
-        rep->checkConsistency();
-        return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString()));
+        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));
     }
 
     static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar> sharedBuffer, UChar* buffer, int length)
@@ -151,21 +110,28 @@ public:
     {
         // For substrings, return the cost of the base string.
         if (bufferOwnership() == BufferSubstring)
-            return m_dataBuffer.asPtr<UStringImpl*>()->cost();
-
-        if (m_dataBuffer & s_reportedCostBit)
+            return m_bufferSubstring->cost();
+        if (m_refCountAndFlags & s_refCountFlagHasReportedCost)
             return 0;
-        m_dataBuffer |= s_reportedCostBit;
+        ASSERT(!isStatic());
+        m_refCountAndFlags |= s_refCountFlagHasReportedCost;
         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_isIdentifier; }
-    void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; }
+    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;
+    }
 
-    UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; }
-    ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; }
+    UStringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; }
+    ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) delete this; }
 
     static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
     {
@@ -183,14 +149,6 @@ 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,
@@ -205,14 +163,12 @@ 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_refCount(s_refCountIncrement)
+        , m_refCountAndFlags(s_refCountIncrement | ownership)
         , 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.
@@ -221,42 +177,37 @@ private:
     enum StaticStringConstructType { ConstructStaticString };
     UStringImpl(UChar* data, int length, StaticStringConstructType)
         : m_data(data)
+        , m_buffer(0)
         , m_length(length)
-        , m_refCount(s_staticRefCountInitialValue)
+        , m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagHasReportedCost | BufferOwned)
         , 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_refCount(s_refCountIncrement)
+        , m_refCountAndFlags(s_refCountIncrement | BufferSubstring)
         , 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_dataBuffer.asPtr<UStringImpl*>()->size());
-        ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->isStatic());
-        checkConsistency();
+        ASSERT(m_bufferSubstring->size());
+        ASSERT(!m_bufferSubstring->isStatic());
+        ASSERT(m_bufferSubstring->bufferOwnership() != BufferSubstring);
     }
 
     // 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_refCount(s_refCountIncrement)
+        , m_refCountAndFlags(s_refCountIncrement | BufferShared)
         , m_hash(0)
-        , m_isIdentifier(false)
-        , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared)
     {
-        checkConsistency();
     }
 
     using Noncopyable::operator new;
@@ -265,28 +216,30 @@ private:
     ~UStringImpl();
 
     // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
-    static const int s_minLengthToShare = 10;
+    static const unsigned s_minLengthToShare = 10;
     static const unsigned s_copyCharsInlineCutOff = 20;
-    static const uintptr_t s_bufferOwnershipMask = 3;
-    static const uintptr_t s_reportedCostBit = 4;
+
+    bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
+    BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
+
     // 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 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; }
+    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;
 
-    // unshared data
     UChar* m_data;
-    int m_length;
-    unsigned m_refCount;
-    mutable unsigned m_hash : 31;
-    mutable unsigned m_isIdentifier : 1;
-    UntypedPtrAndBitfield m_dataBuffer;
+    union {
+        void* m_buffer;
+        UStringImpl* m_bufferSubstring;
+        SharedUChar* m_bufferShared;
+    };
+    unsigned m_length;
+    unsigned m_refCountAndFlags;
+    mutable unsigned m_hash;
 
     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 07f117f..703182c 100644
--- a/JavaScriptCore/wtf/StringHashFunctions.h
+++ b/JavaScriptCore/wtf/StringHashFunctions.h
@@ -60,13 +60,11 @@ 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 = 0x40000000;
+        hash = 0x80000000;
 
     return hash;
 }
@@ -100,13 +98,11 @@ 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 = 0x40000000;
+        hash = 0x80000000;
 
     return hash;
 }
@@ -141,13 +137,11 @@ 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 = 0x40000000;
+        hash = 0x80000000;
 
     return hash;
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list