[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:24:29 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 746ed3362ed76c202eec08754b535f859289e7c4
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 28 21:19:39 2004 +0000

    	Make AtomicString a new class that owns DOMStrings, instead of using KJS::Identifier.  One day when we
    	convert DOMString and UString to have the same underlying rep, then these classes could possibly re-merge.
    	For now this provides an easy migration path for all the code that is using DOMStringImpl*.
    
    	Also fixed a bug with float clearing in the style cascade.
    
            Reviewed by darin
    
            * khtml/css/cssparser.h:
            (DOM::atomicString):
            * khtml/css/cssstyleselector.cpp:
            (khtml::CSSStyleSelector::checkOneSelector):
            (khtml::CSSStyleSelector::applyRule):
            * khtml/dom/dom_string.cpp:
            (DOMString::DOMString):
            * khtml/xml/dom_nameimpl.cpp:
            (DOM::AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger):
            (DOM::AtomicString::equal):
            (DOM::AtomicString::add):
            (DOM::AtomicString::insert):
            (DOM::AtomicString::remove):
            (DOM::AtomicString::expand):
            (DOM::AtomicString::shrink):
            (DOM::AtomicString::rehash):
            (DOM::AtomicString::null):
            (DOM::AtomicString::init):
            (DOM::operator==):
            (DOM::equalsIgnoreCase):
            * khtml/xml/dom_nameimpl.h:
            (DOM::AtomicString::AtomicString):
            (DOM::AtomicString:::m_string):
            (DOM::AtomicString::string):
            (DOM::AtomicString::qstring):
            (DOM::AtomicString::implementation):
            (DOM::AtomicString::unicode):
            (DOM::AtomicString::length):
            (DOM::AtomicString::ascii):
            (DOM::AtomicString::find):
            (DOM::AtomicString::isNull):
            (DOM::AtomicString::isEmpty):
            (DOM::AtomicString::equal):
            (DOM::operator==):
            (DOM::operator!=):
            * khtml/xml/dom_stringimpl.cpp:
            (DOM::DOMStringImpl::empty):
            (DOM::DOMStringImpl::DOMStringImpl):
            (DOM::DOMStringImpl::~DOMStringImpl):
            (DOM::DOMStringImpl::append):
            (DOM::DOMStringImpl::insert):
            (DOM::DOMStringImpl::truncate):
            (DOM::DOMStringImpl::remove):
            (DOM::DOMStringImpl::split):
            (DOM::DOMStringImpl::substring):
            (DOM::DOMStringImpl::replace):
            (DOM::DOMStringImpl::computeHash):
            * khtml/xml/dom_stringimpl.h:
            (DOM::DOMStringImpl::DOMStringImpl):
            (DOM::DOMStringImpl::hash):
            * khtml/xml/dom_textimpl.cpp:
            (CharacterDataImpl::CharacterDataImpl):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5999 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index dba1cf3..b8ab7bf 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,66 @@
+2004-01-28  David Hyatt  <hyatt at apple.com>
+
+	Make AtomicString a new class that owns DOMStrings, instead of using KJS::Identifier.  One day when we
+	convert DOMString and UString to have the same underlying rep, then these classes could possibly re-merge.
+	For now this provides an easy migration path for all the code that is using DOMStringImpl*.
+
+	Also fixed a bug with float clearing in the style cascade.
+	
+        Reviewed by darin
+
+        * khtml/css/cssparser.h:
+        (DOM::atomicString):
+        * khtml/css/cssstyleselector.cpp:
+        (khtml::CSSStyleSelector::checkOneSelector):
+        (khtml::CSSStyleSelector::applyRule):
+        * khtml/dom/dom_string.cpp:
+        (DOMString::DOMString):
+        * khtml/xml/dom_nameimpl.cpp:
+        (DOM::AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger):
+        (DOM::AtomicString::equal):
+        (DOM::AtomicString::add):
+        (DOM::AtomicString::insert):
+        (DOM::AtomicString::remove):
+        (DOM::AtomicString::expand):
+        (DOM::AtomicString::shrink):
+        (DOM::AtomicString::rehash):
+        (DOM::AtomicString::null):
+        (DOM::AtomicString::init):
+        (DOM::operator==):
+        (DOM::equalsIgnoreCase):
+        * khtml/xml/dom_nameimpl.h:
+        (DOM::AtomicString::AtomicString):
+        (DOM::AtomicString:::m_string):
+        (DOM::AtomicString::string):
+        (DOM::AtomicString::qstring):
+        (DOM::AtomicString::implementation):
+        (DOM::AtomicString::unicode):
+        (DOM::AtomicString::length):
+        (DOM::AtomicString::ascii):
+        (DOM::AtomicString::find):
+        (DOM::AtomicString::isNull):
+        (DOM::AtomicString::isEmpty):
+        (DOM::AtomicString::equal):
+        (DOM::operator==):
+        (DOM::operator!=):
+        * khtml/xml/dom_stringimpl.cpp:
+        (DOM::DOMStringImpl::empty):
+        (DOM::DOMStringImpl::DOMStringImpl):
+        (DOM::DOMStringImpl::~DOMStringImpl):
+        (DOM::DOMStringImpl::append):
+        (DOM::DOMStringImpl::insert):
+        (DOM::DOMStringImpl::truncate):
+        (DOM::DOMStringImpl::remove):
+        (DOM::DOMStringImpl::split):
+        (DOM::DOMStringImpl::substring):
+        (DOM::DOMStringImpl::replace):
+        (DOM::DOMStringImpl::computeHash):
+        * khtml/xml/dom_stringimpl.h:
+        (DOM::DOMStringImpl::DOMStringImpl):
+        (DOM::DOMStringImpl::hash):
+        * khtml/xml/dom_textimpl.cpp:
+        (CharacterDataImpl::CharacterDataImpl):
+
 2004-01-27  Chris Blumenberg  <cblu at apple.com>
 
 	Fixed:
diff --git a/WebCore/khtml/css/cssparser.h b/WebCore/khtml/css/cssparser.h
index 0774a27..c516500 100644
--- a/WebCore/khtml/css/cssparser.h
+++ b/WebCore/khtml/css/cssparser.h
@@ -76,7 +76,7 @@ namespace DOM {
 	return DOMString( (QChar *)ps.string, ps.length );
     }
     static inline AtomicString atomicString( const ParseString &ps ) {
-	return AtomicString( (AtomicChar*)ps.string, ps.length );
+	return AtomicString( ps.string, ps.length );
     }
     
     class ValueList {
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index e4f8ca5..d94598b 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -901,7 +901,7 @@ bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl
             }
 
             // The selector's value can't contain a space, or it's totally bogus.
-            spacePos = sel->value.ustring().find(' ');
+            spacePos = sel->value.find(' ');
             if (spacePos != -1)
                 return false;
 
@@ -1716,9 +1716,11 @@ void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value )
     {
         HANDLE_INHERIT_AND_INITIAL(clear, Clear)
         if(!primitiveValue) break;
-        EClear c = CNONE;
+        EClear c;
         switch(primitiveValue->getIdent())
         {
+        case CSS_VAL_NONE:
+            c = CNONE; break;
         case CSS_VAL_LEFT:
             c = CLEFT; break;
         case CSS_VAL_RIGHT:
diff --git a/WebCore/khtml/dom/dom_string.cpp b/WebCore/khtml/dom/dom_string.cpp
index cf3c07b..5f6f822 100644
--- a/WebCore/khtml/dom/dom_string.cpp
+++ b/WebCore/khtml/dom/dom_string.cpp
@@ -29,7 +29,15 @@ using namespace DOM;
 
 DOMString::DOMString(const QChar *str, uint len)
 {
-    impl = new DOMStringImpl( str, len );
+    if (!str) {
+        impl = 0;
+        return;
+    }
+    
+    if (len == 0)
+        impl = DOMStringImpl::empty();
+    else
+        impl = new DOMStringImpl(str, len);
     impl->ref();
 }
 
@@ -39,8 +47,11 @@ DOMString::DOMString(const QString &str)
 	impl = 0;
 	return;
     }
-
-    impl = new DOMStringImpl( str.unicode(), str.length() );
+    
+    if (str.isEmpty())
+        impl = DOMStringImpl::empty();
+    else 
+        impl = new DOMStringImpl(str.unicode(), str.length());
     impl->ref();
 }
 
@@ -51,7 +62,11 @@ DOMString::DOMString(const char *str)
 	return;
     }
 
-    impl = new DOMStringImpl( str );
+    int l = strlen(str);
+    if (l == 0)
+        impl = DOMStringImpl::empty();
+    else
+        impl = new DOMStringImpl(str, l);
     impl->ref();
 }
 
diff --git a/WebCore/khtml/xml/dom_nameimpl.cpp b/WebCore/khtml/xml/dom_nameimpl.cpp
index e19ac63..6f86a7b 100644
--- a/WebCore/khtml/xml/dom_nameimpl.cpp
+++ b/WebCore/khtml/xml/dom_nameimpl.cpp
@@ -21,10 +21,323 @@
  */
 
 #include "dom/dom_string.h"
+#include "xml/dom_stringimpl.h"
 #include "dom_nameimpl.h"
 
 namespace DOM {
 
+// For KHTML we need to avoid having static constructors.
+// Our strategy is to declare the global objects with a different type (initialized to 0)
+// and then use placement new to initialize the global objects later. This is not completely
+// portable, and it would be good to figure out a 100% clean way that still avoids code that
+// runs at init time.
+    
+#if APPLE_CHANGES
+#define AVOID_STATIC_CONSTRUCTORS 1
+#endif
+    
+#if AVOID_STATIC_CONSTRUCTORS
+#define KHTML_ATOMICSTRING_HIDE_GLOBALS 1
+#endif
+    
+#include "dom_nameimpl.h"
+    
+#define DUMP_STATISTICS 0
+
+#if DUMP_STATISTICS
+    
+static int numProbes;
+static int numCollisions;
+
+struct AtomicStringStatisticsExitLogger { ~AtomicStringStatisticsExitLogger(); };
+
+static AtomicStringStatisticsExitLogger logger;
+
+AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger()
+{
+    printf("\nDOM::AtomicString statistics\n\n");
+    printf("%d probes\n", numProbes);
+    printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes);
+}
+
+#endif
+
+const int _minTableSize = 64;
+
+DOMStringImpl **AtomicString::_table;
+int AtomicString::_tableSize;
+int AtomicString::_tableSizeMask;
+int AtomicString::_keyCount;
+
+bool AtomicString::equal(DOMStringImpl *r, const char *s)
+{
+    if (!r && !s) return true;
+    if (!r || !s) return false;
+
+    int length = r->l;
+    const QChar *d = r->s;
+    for (int i = 0; i != length; ++i)
+        if (d[i] != s[i])
+            return false;
+    return s[length] == 0;
+}
+
+bool AtomicString::equal(DOMStringImpl *r, const QChar *s, uint length)
+{
+    if (!r && !s) return true;
+    if (!r || !s) return false;
+    
+    if (r->l != length)
+        return false;
+    const QChar *d = r->s;
+    for (uint i = 0; i != length; ++i)
+        if (d[i] != s[i])
+            return false;
+    return true;
+}
+
+bool AtomicString::equal(DOMStringImpl *r, DOMStringImpl *b)
+{
+    if (r == b) return true;
+    if (!r || !b) return false;
+    uint length = r->l;
+    if (length != b->l)
+        return false;
+    const QChar *d = r->s;
+    const QChar *s = b->s;
+    for (uint i = 0; i != length; ++i)
+        if (d[i] != s[i])
+            return false;
+    return true;
+}
+
+DOMStringImpl *AtomicString::add(const char *c)
+{
+    if (!c)
+        return 0;
+    int length = strlen(c);
+    if (length == 0)
+        return DOMStringImpl::empty();
+    
+    if (!_table)
+        expand();
+    
+    unsigned hash = DOMStringImpl::computeHash(c);
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i] && !equal(_table[i], c);
+#endif
+    while (DOMStringImpl *key = _table[i]) {
+        if (equal(key, c))
+            return key;
+        i = (i + 1) & _tableSizeMask;
+    }
+    
+    QChar *d = new QChar[length];
+    for (int j = 0; j != length; j++)
+        d[j] = c[j];
+    
+    DOMStringImpl *r = new DOMStringImpl(d, length);
+    r->_hash = hash;
+    
+    _table[i] = r;
+    ++_keyCount;
+    
+    if (_keyCount * 2 >= _tableSize)
+        expand();
+    
+    return r;
+}
+
+DOMStringImpl *AtomicString::add(const QChar *s, int length)
+{
+    if (!s)
+        return 0;
+
+    if (length == 0)
+        return DOMStringImpl::empty();
+    
+    if (!_table)
+        expand();
+    
+    unsigned hash = DOMStringImpl::computeHash(s, length);
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i] && !equal(_table[i], s, length);
+#endif
+    while (DOMStringImpl *key = _table[i]) {
+        if (equal(key, s, length))
+            return key;
+        i = (i + 1) & _tableSizeMask;
+    }
+    
+    QChar *d = new QChar[length];
+    for (int j = 0; j != length; j++)
+        d[j] = s[j];
+    
+    DOMStringImpl *r = new DOMStringImpl(d, length);
+    r->_hash = hash;
+    
+    _table[i] = r;
+    ++_keyCount;
+    
+    if (_keyCount * 2 >= _tableSize)
+        expand();
+    
+    return r;
+}
+
+DOMStringImpl *AtomicString::add(DOMStringImpl *r)
+{
+    if (!r)
+        return 0;
+
+    if (r->l == 0)
+        return DOMStringImpl::empty();
+    
+    if (!_table)
+        expand();
+    
+    unsigned hash = r->hash();
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i] && !equal(_table[i], r);
+#endif
+    while (DOMStringImpl *key = _table[i]) {
+        if (equal(key, r))
+            return key;
+        i = (i + 1) & _tableSizeMask;
+    }
+
+    _table[i] = r;
+    ++_keyCount;
+    
+    if (_keyCount * 2 >= _tableSize)
+        expand();
+    
+    return r;
+}
+
+inline void AtomicString::insert(DOMStringImpl *key)
+{
+    unsigned hash = key->hash();
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i] != 0;
+#endif
+    while (_table[i])
+        i = (i + 1) & _tableSizeMask;
+    
+    _table[i] = key;
+}
+
+void AtomicString::remove(DOMStringImpl *r)
+{
+    unsigned hash = r->hash();
+    
+    DOMStringImpl *key;
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i] && equal(_table[i], r);
+#endif
+    while ((key = _table[i])) {
+        if (equal(key, r))
+            break;
+        i = (i + 1) & _tableSizeMask;
+    }
+    if (!key)
+        return;
+ 
+    _table[i] = 0;
+    --_keyCount;
+    
+    if (_keyCount * 6 < _tableSize && _tableSize > _minTableSize) {
+        shrink();
+        return;
+    }
+    
+    // Reinsert all the items to the right in the same cluster.
+    while (1) {
+        i = (i + 1) & _tableSizeMask;
+        key = _table[i];
+        if (!key)
+            break;
+        _table[i] = 0;
+        insert(key);
+    }
+}
+
+void AtomicString::expand()
+{
+    rehash(_tableSize == 0 ? _minTableSize : _tableSize * 2);
+}
+
+void AtomicString::shrink()
+{
+    rehash(_tableSize / 2);
+}
+
+void AtomicString::rehash(int newTableSize)
+{
+    int oldTableSize = _tableSize;
+    DOMStringImpl **oldTable = _table;
+    
+    _tableSize = newTableSize;
+    _tableSizeMask = newTableSize - 1;
+    _table = (DOMStringImpl **)calloc(newTableSize, sizeof(DOMStringImpl *));
+    
+    for (int i = 0; i != oldTableSize; ++i)
+        if (DOMStringImpl *key = oldTable[i])
+            insert(key);
+    
+    free(oldTable);
+}
+
+const AtomicString &AtomicString::null()
+{
+    static AtomicString null;
+    return null;
+}
+
+// Global constants for property name strings.
+
+#if !AVOID_STATIC_CONSTRUCTORS
+    // Define an AtomicString in the normal way.
+    #define DEFINE_GLOBAL(name, string) extern const AtomicString name ## PropertyName(string);
+#else
+    // Define an AtomicString-sized array of pointers to avoid static initialization.
+    // Use an array of pointers instead of an array of char in case there is some alignment issue.
+    #define DEFINE_GLOBAL(name, string) \
+        void * name ## PropertyName[(sizeof(AtomicString) + sizeof(void *) - 1) / sizeof(void *)];
+#endif
+
+#define CALL_DEFINE_GLOBAL(name) DEFINE_GLOBAL(name, #name)
+KHTML_ATOMICSTRING_EACH_GLOBAL(CALL_DEFINE_GLOBAL)
+
+void AtomicString::init()
+{
+#if AVOID_STATIC_CONSTRUCTORS
+    static bool initialized;
+    if (!initialized) {
+        // Use placement new to initialize the globals.
+        #define PLACEMENT_NEW_GLOBAL(name, string) new (&name ## PropertyName) AtomicString(string);
+        #define CALL_PLACEMENT_NEW_GLOBAL(name) PLACEMENT_NEW_GLOBAL(name, #name)
+        KHTML_ATOMICSTRING_EACH_GLOBAL(CALL_PLACEMENT_NEW_GLOBAL)
+        initialized = true;
+    }
+#endif
+}
+
 AtomicStringList* AtomicStringList::clone()
 {
     return new AtomicStringList(m_string, m_next ? m_next->clone() : 0);
@@ -32,47 +345,21 @@ AtomicStringList* AtomicStringList::clone()
 
 bool operator==(const AtomicString &a, const DOMString &b)
 {
-    unsigned l = a.size();
-    if (l != b.length()) return false;
-    
-    if (!memcmp(a.ustring().data(), b.unicode(), l*sizeof(unsigned short)))
-	return true;
-    return false;
-    
+    return a.string() == b;    
 }
    
 bool equalsIgnoreCase(const AtomicString &as, const DOMString &bs)
 {
     // returns true when equal, false otherwise (ignoring case)
-    unsigned l = as.size();
-    if (l != bs.length()) return false;
-    
-    const QChar *a = reinterpret_cast<const QChar*>(as.ustring().data());
-    const QChar *b = bs.unicode();
-    if (a == b)  return true;
-    if (!(a && b))  return false;
-    while (l--) {
-        if (*a != *b && a->lower() != b->lower()) return false;
-	a++,b++;
-    }
-    return true;
+    return !strcasecmp(as.string(), bs);
 }
 
 bool equalsIgnoreCase(const AtomicString &as, const AtomicString &bs)
 {
     // returns true when equal, false otherwise (ignoring case)
-    int l = as.size();
-    if (l != bs.size()) return false;
-    
-    const QChar *a = reinterpret_cast<const QChar*>(as.ustring().data());
-    const QChar *b = reinterpret_cast<const QChar*>(bs.ustring().data());
-    if ( a == b )  return true;
-    if ( !( a && b ) )  return false;
-    while ( l-- ) {
-        if ( *a != *b && a->lower() != b->lower() ) return false;
-	a++,b++;
-    }
-    return true;    
+    if (as == bs)
+        return true;
+    return !strcasecmp(as.string(), bs.string());
 }
 
 }
diff --git a/WebCore/khtml/xml/dom_nameimpl.h b/WebCore/khtml/xml/dom_nameimpl.h
index 3b6f47d..e11e5bd 100644
--- a/WebCore/khtml/xml/dom_nameimpl.h
+++ b/WebCore/khtml/xml/dom_nameimpl.h
@@ -22,13 +22,94 @@
 #ifndef _DOM_NameImpl_h_
 #define _DOM_NameImpl_h_
 
-#include <kjs/identifier.h>
+#include "dom/dom_string.h"
 
 namespace DOM {
 
-typedef KJS::Identifier AtomicString;
-typedef KJS::UChar AtomicChar;
+class AtomicString {
+public:
+    static void init();
+    
+    AtomicString() { }
+    AtomicString(const char *s) : m_string(add(s)) { }
+    AtomicString(const QChar *s, int length) : m_string(add(s, length)) { }
+    AtomicString(const unsigned short* s, int length) : m_string(add((QChar*)s, length)) { }
+    AtomicString(DOMStringImpl* imp) :m_string(add(imp)) { }
+    explicit AtomicString(const DOMString &s) : m_string(add(s.implementation())) { }
+    
+    const DOMString& string() const { return m_string; };
+    QString qstring() const { return m_string.string(); };
+    
+    const DOMStringImpl* implementation() { return m_string.implementation(); }
+    
+    const QChar *unicode() const { return m_string.unicode(); }
+    int length() const { return m_string.length(); }
+    
+    const char *ascii() const { return m_string.string().ascii(); }
+
+    int find(const QChar c, int start = 0) const { return m_string.find(c, start); }
+    
+    bool isNull() const { return m_string.isNull(); }
+    bool isEmpty() const { return m_string.isEmpty(); }
+
+    static const AtomicString &null();
+    
+    friend bool operator==(const AtomicString &, const AtomicString &);
+    friend bool operator!=(const AtomicString &, const AtomicString &);
+    
+    friend bool operator==(const AtomicString &, const char *);
+    
+    static void remove(DOMStringImpl *);
+    
+private:
+    DOMString m_string;
+    
+    static bool equal(DOMStringImpl *, const char *);
+    static bool equal(DOMStringImpl *, const QChar *, uint length);
+    static bool equal(DOMStringImpl *, DOMStringImpl *);
+    
+    static bool equal(const AtomicString &a, const AtomicString &b)
+    { return a.m_string.implementation() == b.m_string.implementation(); }
+    static bool equal(const AtomicString &a, const char *b)
+    { return equal(a.m_string.implementation(), b); }
+    
+    static DOMStringImpl *add(const char *);
+    static DOMStringImpl *add(const QChar *, int length);
+    static DOMStringImpl *add(DOMStringImpl *);
+    
+    static void insert(DOMStringImpl *);
+    
+    static void rehash(int newTableSize);
+    static void expand();
+    static void shrink();
+    
+    static DOMStringImpl **_table;
+    static int _tableSize;
+    static int _tableSizeMask;
+    static int _keyCount;
+};
+
+inline bool operator==(const AtomicString &a, const AtomicString &b)
+{ return AtomicString::equal(a, b); }
+
+inline bool operator!=(const AtomicString &a, const AtomicString &b)
+{ return !AtomicString::equal(a, b); }
 
+inline bool operator==(const AtomicString &a, const char *b)
+{ return AtomicString::equal(a, b); }
+
+// List of property names, passed to a macro so we can do set them up various
+// ways without repeating the list.
+#define KHTML_ATOMICSTRING_EACH_GLOBAL(macro)
+
+    // Define external global variables for all property names above (and one more).
+#if !KHTML_ATOMICSTRING_HIDE_GLOBALS
+#define KHTML_ATOMICSTRING_DECLARE_GLOBAL(name) extern const AtomicString name ## PropertyName;
+    KHTML_ATOMICSTRING_EACH_GLOBAL(KHTML_ATOMICSTRING_DECLARE_GLOBAL)
+    KHTML_ATOMICSTRING_DECLARE_GLOBAL(specialPrototype)
+#undef KHTML_ATOMICSTRING_DECLARE_GLOBAL
+#endif
+        
 class AtomicStringList {
 public:
     AtomicStringList() :m_next(0) {}
diff --git a/WebCore/khtml/xml/dom_stringimpl.cpp b/WebCore/khtml/xml/dom_stringimpl.cpp
index f47d553..9e6edad 100644
--- a/WebCore/khtml/xml/dom_stringimpl.cpp
+++ b/WebCore/khtml/xml/dom_stringimpl.cpp
@@ -28,16 +28,37 @@
 #include <kdebug.h>
 
 #include <string.h>
+#include "dom_nameimpl.h"
 
-using namespace DOM;
 using namespace khtml;
 
 namespace DOM {
 
 using khtml::Fixed;
 
+DOMStringImpl* DOMStringImpl::empty()
+{
+    static DOMStringImpl e = WithOneRef();
+    return &e;
+}
+
+DOMStringImpl::DOMStringImpl(const QChar *str, unsigned int len) {
+    _hash = 0;
+    bool havestr = str && len;
+    s = QT_ALLOC_QCHAR_VEC( havestr ? len : 1 );
+    if(str && len) {
+        memcpy( s, str, len * sizeof(QChar) );
+        l = len;
+    } else {
+        // crash protection
+        s[0] = 0x0;
+        l = 0;
+    }
+}
+
 DOMStringImpl::DOMStringImpl(const char *str)
 {
+    _hash = 0;
     if(str && *str)
     {
         l = strlen(str);
@@ -55,8 +76,36 @@ DOMStringImpl::DOMStringImpl(const char *str)
     }
 }
 
+DOMStringImpl::DOMStringImpl(const char *str, unsigned int len)
+{
+    _hash = 0;
+    l = len;
+    if (!l || !str)
+        return;
+    
+    s = QT_ALLOC_QCHAR_VEC(l);
+    int i = l;
+    QChar* ptr = s;
+    while( i-- )
+        *ptr++ = *str++;
+}
+
+DOMStringImpl::DOMStringImpl(const QChar &ch) {
+    _hash = 0;
+    s = QT_ALLOC_QCHAR_VEC( 1 );
+    s[0] = ch;
+    l = 1;
+}
+
+DOMStringImpl::~DOMStringImpl()
+{
+    if (_hash) AtomicString::remove(this);
+    if(s) QT_DELETE_QCHAR_VEC(s);
+}
+
 void DOMStringImpl::append(DOMStringImpl *str)
 {
+    assert(_hash == 0);
     if(str && str->l != 0)
     {
         int newlen = l+str->l;
@@ -71,6 +120,7 @@ void DOMStringImpl::append(DOMStringImpl *str)
 
 void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
 {
+    assert(_hash == 0);
     if(pos > l)
     {
         append(str);
@@ -91,6 +141,7 @@ void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
 
 void DOMStringImpl::truncate(int len)
 {
+    assert(_hash == 0);
     if(len > (int)l) return;
 
     int nl = len < 1 ? 1 : len;
@@ -103,31 +154,33 @@ void DOMStringImpl::truncate(int len)
 
 void DOMStringImpl::remove(uint pos, int len)
 {
-  if(len <= 0) return;
-  if(pos >= l ) return;
-  if((unsigned)len > l - pos)
+    assert(_hash == 0);
+    if(len <= 0) return;
+    if(pos >= l ) return;
+    if((unsigned)len > l - pos)
     len = l - pos;
 
-  uint newLen = l-len;
-  QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
-  memcpy(c, s, pos*sizeof(QChar));
-  memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(QChar));
-  if(s) QT_DELETE_QCHAR_VEC(s);
-  s = c;
-  l = newLen;
+    uint newLen = l-len;
+    QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
+    memcpy(c, s, pos*sizeof(QChar));
+    memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(QChar));
+    if(s) QT_DELETE_QCHAR_VEC(s);
+    s = c;
+    l = newLen;
 }
 
 DOMStringImpl *DOMStringImpl::split(uint pos)
 {
-  if( pos >=l ) return new DOMStringImpl();
+    assert(_hash == 0);
+    if( pos >=l ) return new DOMStringImpl();
 
-  uint newLen = l-pos;
-  QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
-  memcpy(c, s+pos, newLen*sizeof(QChar));
+    uint newLen = l-pos;
+    QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
+    memcpy(c, s+pos, newLen*sizeof(QChar));
 
-  DOMStringImpl *str = new DOMStringImpl(s + pos, newLen);
-  truncate(pos);
-  return str;
+    DOMStringImpl *str = new DOMStringImpl(s + pos, newLen);
+    truncate(pos);
+    return str;
 }
 
 bool DOMStringImpl::containsOnlyWhitespace() const
@@ -149,11 +202,10 @@ bool DOMStringImpl::containsOnlyWhitespace() const
     
 DOMStringImpl *DOMStringImpl::substring(uint pos, uint len)
 {
-  if( pos >=l ) return new DOMStringImpl();
-  if(len > l - pos)
+    if (pos >=l) return new DOMStringImpl();
+    if (len > l - pos)
     len = l - pos;
-
-  return new DOMStringImpl(s + pos, len);
+    return new DOMStringImpl(s + pos, len);
 }
 
 static Length parseLength(QChar *s, unsigned int l)
@@ -350,4 +402,77 @@ DOMStringImpl *DOMStringImpl::replace(QChar oldC, QChar newC)
     return c;
 }
 
+// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+// or anything like that.
+const unsigned PHI = 0x9e3779b9U;
+
+// This hash algorithm comes from:
+// http://burtleburtle.net/bob/hash/hashfaq.html
+// http://burtleburtle.net/bob/hash/doobs.html
+unsigned DOMStringImpl::computeHash(const QChar *s, int length)
+{
+    int prefixLength = length < 8 ? length : 8;
+    int suffixPosition = length < 16 ? 8 : length - 8;
+    
+    unsigned h = PHI;
+    h += length;
+    h += (h << 10); 
+    h ^= (h << 6); 
+    
+    for (int i = 0; i < prefixLength; i++) {
+        h += s[i].unicode(); 
+	h += (h << 10); 
+	h ^= (h << 6); 
+    }
+    for (int i = suffixPosition; i < length; i++){
+        h += s[i].unicode(); 
+	h += (h << 10); 
+	h ^= (h << 6); 
+    }
+    
+    h += (h << 3);
+    h ^= (h >> 11);
+    h += (h << 15);
+    
+    if (h == 0)
+        h = 0x80000000;
+    
+    return h;
+}
+
+// This hash algorithm comes from:
+// http://burtleburtle.net/bob/hash/hashfaq.html
+// http://burtleburtle.net/bob/hash/doobs.html
+unsigned DOMStringImpl::computeHash(const char *s)
+{
+    int length = strlen(s);
+    int prefixLength = length < 8 ? length : 8;
+    int suffixPosition = length < 16 ? 8 : length - 8;
+    
+    unsigned h = PHI;
+    h += length;
+    h += (h << 10); 
+    h ^= (h << 6); 
+    
+    for (int i = 0; i < prefixLength; i++) {
+        h += (unsigned char)s[i];
+	h += (h << 10); 
+	h ^= (h << 6); 
+    }
+    for (int i = suffixPosition; i < length; i++) {
+        h += (unsigned char)s[i];
+	h += (h << 10); 
+	h ^= (h << 6); 
+    }
+    
+    h += (h << 3);
+    h ^= (h >> 11);
+    h += (h << 15);
+    
+    if (h == 0)
+        h = 0x80000000;
+    
+    return h;
+}
+
 } // namespace DOM
diff --git a/WebCore/khtml/xml/dom_stringimpl.h b/WebCore/khtml/xml/dom_stringimpl.h
index d5c073e..d590c1a 100644
--- a/WebCore/khtml/xml/dom_stringimpl.h
+++ b/WebCore/khtml/xml/dom_stringimpl.h
@@ -35,32 +35,23 @@ namespace DOM {
 
 class DOMStringImpl : public khtml::Shared<DOMStringImpl>
 {
+private:
+    struct WithOneRef { };
+    DOMStringImpl(WithOneRef) { s = 0; l = 0; _hash = 0; ref(); }
+
 protected:
-    DOMStringImpl() { s = 0, l = 0; }
+    DOMStringImpl() { s = 0, l = 0; _hash = 0; }
 public:
-    DOMStringImpl(const QChar *str, unsigned int len) {
-	bool havestr = str && len;
-	s = QT_ALLOC_QCHAR_VEC( havestr ? len : 1 );
-	if(str && len) {
-	    memcpy( s, str, len * sizeof(QChar) );
-	    l = len;
-	} else {
-	    // crash protection
-	    s[0] = 0x0;
-	    l = 0;
-	}
-    }
-
+    DOMStringImpl(const QChar *str, unsigned int len);
     DOMStringImpl(const char *str);
-    DOMStringImpl(const QChar &ch) {
-	s = QT_ALLOC_QCHAR_VEC( 1 );
-	s[0] = ch;
-	l = 1;
-    }
-    ~DOMStringImpl() {
-	if(s) QT_DELETE_QCHAR_VEC(s);
-    }
-
+    DOMStringImpl(const char *str, unsigned int len);
+    DOMStringImpl(const QChar &ch);
+    ~DOMStringImpl();
+    
+    unsigned hash() const { if (_hash == 0) _hash = computeHash(s, l); return _hash; }
+    static unsigned computeHash(const QChar *, int length);
+    static unsigned computeHash(const char *);
+    
     void append(DOMStringImpl *str);
     void insert(DOMStringImpl *str, unsigned int pos);
     void truncate(int len);
@@ -91,8 +82,11 @@ public:
     // This modifies the string in place if there is only one ref, makes a new string otherwise.
     DOMStringImpl *replace(QChar, QChar);
 
+    static DOMStringImpl* empty();
+
     unsigned int l;
     QChar *s;
+    mutable unsigned _hash;
 };
 
 };
diff --git a/WebCore/khtml/xml/dom_textimpl.cpp b/WebCore/khtml/xml/dom_textimpl.cpp
index aa9ff47..4f7a9ab 100644
--- a/WebCore/khtml/xml/dom_textimpl.cpp
+++ b/WebCore/khtml/xml/dom_textimpl.cpp
@@ -45,7 +45,7 @@ CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc)
 CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc, const DOMString &_text)
     : NodeImpl(doc)
 {
-    str = _text.impl ? _text.impl : new DOMStringImpl(0, 0);
+    str = _text.impl ? _text.impl : new DOMStringImpl((QChar*)0, 0);
     str->ref();
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list