Commit 5721aa9d authored by darin's avatar darin

- another step towards atomic identifiers; storing hash in the string rep. gives about

	a 1.5% speedup in the JavaScript iBench

        * kjs/ustring.h: Add a hash field to UString::Rep.
        * kjs/ustring.cpp:
        (UString::Rep::create): Set hash to uninitialized value.
        (UString::Rep::destroy): Do the deleting in her, and call Identifier if needed.
        (UString::Rep::computeHash): Added.
        (UString::append): Set hash to 0 when modifying the string in place.
        (UString::operator=): Ditto.

        * kjs/property_map.cpp: Use the hash from UString.

        * kjs/identifier.h: Added aboutToDestroyUStringRep.
        * kjs/identifier.cpp: (Identifier::aboutToDestroyUStringRep): Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@2769 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 634e3f1b
2002-11-19 Darin Adler <darin@apple.com>
- another step towards atomic identifiers; storing hash in the string rep. gives about
a 1.5% speedup in the JavaScript iBench
* kjs/ustring.h: Add a hash field to UString::Rep.
* kjs/ustring.cpp:
(UString::Rep::create): Set hash to uninitialized value.
(UString::Rep::destroy): Do the deleting in her, and call Identifier if needed.
(UString::Rep::computeHash): Added.
(UString::append): Set hash to 0 when modifying the string in place.
(UString::operator=): Ditto.
* kjs/property_map.cpp: Use the hash from UString.
* kjs/identifier.h: Added aboutToDestroyUStringRep.
* kjs/identifier.cpp: (Identifier::aboutToDestroyUStringRep): Added.
2002-11-19 Darin Adler <darin@apple.com>
- next step towards atomic identifiers; Identifier is no longer derived from UString
......
2002-11-19 Darin Adler <darin@apple.com>
- another step towards atomic identifiers; storing hash in the string rep. gives about
a 1.5% speedup in the JavaScript iBench
* kjs/ustring.h: Add a hash field to UString::Rep.
* kjs/ustring.cpp:
(UString::Rep::create): Set hash to uninitialized value.
(UString::Rep::destroy): Do the deleting in her, and call Identifier if needed.
(UString::Rep::computeHash): Added.
(UString::append): Set hash to 0 when modifying the string in place.
(UString::operator=): Ditto.
* kjs/property_map.cpp: Use the hash from UString.
* kjs/identifier.h: Added aboutToDestroyUStringRep.
* kjs/identifier.cpp: (Identifier::aboutToDestroyUStringRep): Added.
2002-11-19 Darin Adler <darin@apple.com>
- next step towards atomic identifiers; Identifier is no longer derived from UString
......
2002-11-19 Darin Adler <darin@apple.com>
- another step towards atomic identifiers; storing hash in the string rep. gives about
a 1.5% speedup in the JavaScript iBench
* kjs/ustring.h: Add a hash field to UString::Rep.
* kjs/ustring.cpp:
(UString::Rep::create): Set hash to uninitialized value.
(UString::Rep::destroy): Do the deleting in her, and call Identifier if needed.
(UString::Rep::computeHash): Added.
(UString::append): Set hash to 0 when modifying the string in place.
(UString::operator=): Ditto.
* kjs/property_map.cpp: Use the hash from UString.
* kjs/identifier.h: Added aboutToDestroyUStringRep.
* kjs/identifier.cpp: (Identifier::aboutToDestroyUStringRep): Added.
2002-11-19 Darin Adler <darin@apple.com>
- next step towards atomic identifiers; Identifier is no longer derived from UString
......
......@@ -30,4 +30,8 @@ bool operator==(const Identifier &a, const char *b)
return a._ustring == b;
}
void Identifier::aboutToDestroyUStringRep(UString::Rep *)
{
}
} // namespace KJS
......@@ -57,6 +57,8 @@ namespace KJS {
friend bool operator==(const Identifier &, const char *);
static void aboutToDestroyUStringRep(UString::Rep *);
private:
UString _ustring;
};
......
......@@ -64,17 +64,9 @@ void PropertyMap::clear()
_keyCount = 0;
}
int PropertyMap::hash(const UString::Rep *s) const
inline int PropertyMap::hash(const UString::Rep *s) const
{
int h = 0;
int length = s->len;
int prefixLength = length < 8 ? length : 8;
for (int i = 0; i < prefixLength; i++)
h = (127 * h + s->dat[i].unicode()) & _tableSizeHashMask;
int suffixPosition = length < 16 ? 8 : length - 8;
for (int i = suffixPosition; i < length; i++)
h = (127 * h + s->dat[i].unicode()) & _tableSizeHashMask;
return h;
return s->hash() & _tableSizeHashMask;
}
bool PropertyMap::keysMatch(const UString::Rep *a, const UString::Rep *b)
......
......@@ -36,6 +36,7 @@
#include "ustring.h"
#include "operations.h"
#include "identifier.h"
#include <math.h>
namespace KJS {
......@@ -114,8 +115,8 @@ bool KJS::operator==(const KJS::CString& c1, const KJS::CString& c2)
}
UChar UChar::null((char)0);
UString::Rep UString::Rep::null = { 0, 0, 0, 1 };
UString::Rep UString::Rep::empty = { 0, 0, 0, 1 };
UString::Rep UString::Rep::null = { 0, 0, 0, 1, 1 };
UString::Rep UString::Rep::empty = { 0, 0, 0, 1, 1 };
UString UString::null;
const int normalStatBufferSize = 4096;
static char *statBuffer = 0;
......@@ -162,10 +163,35 @@ UString::Rep *UString::Rep::create(UChar *d, int l)
r->len = l;
r->capacity = l;
r->rc = 1;
r->_hash = 0;
return r;
}
void UString::Rep::destroy()
{
if (capacity == capacityForIdentifier)
Identifier::aboutToDestroyUStringRep(this);
delete [] dat;
delete this;
}
void UString::Rep::computeHash() const
{
int length = len;
int prefixLength = length < 8 ? length : 8;
int suffixPosition = length < 16 ? 8 : length - 8;
unsigned h = length;
for (int i = 0; i < prefixLength; i++)
h = 127 * h + dat[i].unicode();
for (int i = suffixPosition; i < length; i++)
h = 127 * h + dat[i].unicode();
if (h == 0)
h = 0x80000000;
_hash = h;
}
UString::UString()
{
null.rep = &Rep::null;
......@@ -328,6 +354,7 @@ UString &UString::append(const UString &t)
if (rep->rc == 1 && newLen <= rep->capacity) {
memcpy(rep->dat+l, t.data(), tLen * sizeof(UChar));
rep->len = newLen;
rep->_hash = 0;
return *this;
}
......@@ -388,8 +415,9 @@ UString &UString::operator=(const char *c)
{
int l = c ? strlen(c) : 0;
UChar *d;
if (rep->rc == 1 && l < rep->capacity) {
if (rep->rc == 1 && l <= rep->capacity) {
d = rep->dat;
rep->_hash = 0;
} else {
release();
d = new UChar[l];
......
......@@ -199,30 +199,37 @@ namespace KJS {
class UString {
friend bool operator==(const UString&, const UString&);
friend class UCharReference;
friend class Identifier;
friend class PropertyMap;
friend class PropertyMapHashTableEntry;
/**
* @internal
*/
struct Rep {
friend class UString;
friend bool operator==(const UString&, const UString&);
static Rep *create(UChar *d, int l);
inline UChar *data() const { return dat; }
inline int size() const { return len; }
void destroy();
UChar *data() const { return dat; }
int size() const { return len; }
int hash() const { if (_hash == 0) computeHash(); return _hash; }
void computeHash() const;
inline void ref() { rc++; }
inline void deref() {
if (--rc == 0) {
delete [] dat;
delete this;
}
}
void ref() { ++rc; }
void deref() { if (--rc == 0) destroy(); }
UChar *dat;
int len;
int capacity;
int rc;
mutable int _hash;
enum { capacityForIdentifier = 0x10000000 };
static Rep null;
static Rep empty;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment