Commit cb1f9131 authored by slewis@apple.com's avatar slewis@apple.com

2009-04-16 Stephanie Lewis <slewis@apple.com>

        Reviewed by Oliver Hunt.

        <rdar://problem/6744652> 32-bit to 64-bit: Javascript hash tables double in size

        Remove perfect hash optimization which removes 1 MB of overhead on 32-bit and almost 2 MB on 64-bit.  Removing the optimization was not a regression on SunSpider and the acid 3 test still passes.

        * create_hash_table:
        * runtime/Lookup.cpp:
        (JSC::HashTable::createTable):
        (JSC::HashTable::deleteTable):
        * runtime/Lookup.h:
        (JSC::HashEntry::initialize):
        (JSC::HashEntry::next):
        (JSC::HashTable::entry):
        * runtime/Structure.cpp:
        (JSC::Structure::getEnumerableNamesFromClassInfoTable):



git-svn-id: svn://svn.chromium.org/blink/trunk@42606 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e92d57f5
2009-04-16 Stephanie Lewis <slewis@apple.com>
Reviewed by Oliver Hunt.
<rdar://problem/6744652> 32-bit to 64-bit: Javascript hash tables double in size
Remove perfect hash optimization which removes 1 MB of overhead on 32-bit and almost 2 MB on 64-bit. Removing the optimization was not a regression on SunSpider and the acid 3 test still passes.
* create_hash_table:
* runtime/Lookup.cpp:
(JSC::HashTable::createTable):
(JSC::HashTable::deleteTable):
* runtime/Lookup.h:
(JSC::HashEntry::initialize):
(JSC::HashEntry::next):
(JSC::HashTable::entry):
* runtime/Structure.cpp:
(JSC::Structure::getEnumerableNamesFromClassInfoTable):
2009-04-16 Oliver Hunt <oliver@apple.com> 2009-04-16 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough. Reviewed by Gavin Barraclough.
...@@ -269,10 +269,6 @@ sub output() { ...@@ -269,10 +269,6 @@ sub output() {
print " { 0, 0, 0, 0 }\n"; print " { 0, 0, 0, 0 }\n";
print "};\n\n"; print "};\n\n";
print "extern const struct HashTable $name =\n"; print "extern const struct HashTable $name =\n";
print "#if ENABLE(PERFECT_HASH_SIZE)\n";
print " \{ ", $pefectHashSize - 1, ", $nameEntries, 0 \};\n";
print "#else\n";
print " \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n"; print " \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n";
print "#endif\n\n";
print "} // namespace\n"; print "} // namespace\n";
} }
...@@ -26,19 +26,6 @@ namespace JSC { ...@@ -26,19 +26,6 @@ namespace JSC {
void HashTable::createTable(JSGlobalData* globalData) const void HashTable::createTable(JSGlobalData* globalData) const
{ {
#if ENABLE(PERFECT_HASH_SIZE)
ASSERT(!table);
HashEntry* entries = new HashEntry[hashSizeMask + 1];
for (int i = 0; i <= hashSizeMask; ++i)
entries[i].setKey(0);
for (int i = 0; values[i].key; ++i) {
UString::Rep* identifier = Identifier::add(globalData, values[i].key).releaseRef();
int hashIndex = identifier->computedHash() & hashSizeMask;
ASSERT(!entries[hashIndex].key());
entries[hashIndex].initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
}
table = entries;
#else
ASSERT(!table); ASSERT(!table);
int linkIndex = compactHashSizeMask + 1; int linkIndex = compactHashSizeMask + 1;
HashEntry* entries = new HashEntry[compactSize]; HashEntry* entries = new HashEntry[compactSize];
...@@ -61,17 +48,12 @@ void HashTable::createTable(JSGlobalData* globalData) const ...@@ -61,17 +48,12 @@ void HashTable::createTable(JSGlobalData* globalData) const
entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2); entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
} }
table = entries; table = entries;
#endif
} }
void HashTable::deleteTable() const void HashTable::deleteTable() const
{ {
if (table) { if (table) {
#if ENABLE(PERFECT_HASH_SIZE)
int max = hashSizeMask + 1;
#else
int max = compactSize; int max = compactSize;
#endif
for (int i = 0; i != max; ++i) { for (int i = 0; i != max; ++i) {
if (UString::Rep* key = table[i].key()) if (UString::Rep* key = table[i].key())
key->deref(); key->deref();
......
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
#include <stdio.h> #include <stdio.h>
#include <wtf/Assertions.h> #include <wtf/Assertions.h>
// Set ENABLE_PERFECT_HASH_SIZE to 0 to save memory at the
// cost of speed. Test your platform as results may vary.
#define ENABLE_PERFECT_HASH_SIZE 1
namespace JSC { namespace JSC {
// Hash table generated by the create_hash_table script. // Hash table generated by the create_hash_table script.
...@@ -57,9 +53,7 @@ namespace JSC { ...@@ -57,9 +53,7 @@ namespace JSC {
m_attributes = attributes; m_attributes = attributes;
m_u.store.value1 = v1; m_u.store.value1 = v1;
m_u.store.value2 = v2; m_u.store.value2 = v2;
#if !ENABLE(PERFECT_HASH_SIZE)
m_next = 0; m_next = 0;
#endif
} }
void setKey(UString::Rep* key) { m_key = key; } void setKey(UString::Rep* key) { m_key = key; }
...@@ -75,10 +69,8 @@ namespace JSC { ...@@ -75,10 +69,8 @@ namespace JSC {
intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; } intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
#if !ENABLE(PERFECT_HASH_SIZE)
void setNext(HashEntry *next) { m_next = next; } void setNext(HashEntry *next) { m_next = next; }
HashEntry* next() const { return m_next; } HashEntry* next() const { return m_next; }
#endif
private: private:
UString::Rep* m_key; UString::Rep* m_key;
...@@ -103,18 +95,14 @@ namespace JSC { ...@@ -103,18 +95,14 @@ namespace JSC {
} lexer; } lexer;
} m_u; } m_u;
#if !ENABLE(PERFECT_HASH_SIZE)
HashEntry* m_next; HashEntry* m_next;
#endif
}; };
struct HashTable { struct HashTable {
#if ENABLE(PERFECT_HASH_SIZE)
int hashSizeMask; // Precomputed size for the hash table (minus 1).
#else
int compactSize; int compactSize;
int compactHashSizeMask; int compactHashSizeMask;
#endif
const HashTableValue* values; // Fixed values generated by script. const HashTableValue* values; // Fixed values generated by script.
mutable const HashEntry* table; // Table allocated at runtime. mutable const HashEntry* table; // Table allocated at runtime.
...@@ -148,13 +136,6 @@ namespace JSC { ...@@ -148,13 +136,6 @@ namespace JSC {
private: private:
ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
{ {
#if ENABLE(PERFECT_HASH_SIZE)
ASSERT(table);
const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];
if (entry->key() != identifier.ustring().rep())
return 0;
return entry;
#else
ASSERT(table); ASSERT(table);
const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask]; const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];
...@@ -169,7 +150,6 @@ namespace JSC { ...@@ -169,7 +150,6 @@ namespace JSC {
} while (entry); } while (entry);
return 0; return 0;
#endif
} }
// Convert the hash table keys to identifiers. // Convert the hash table keys to identifiers.
......
...@@ -948,11 +948,8 @@ void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const Clas ...@@ -948,11 +948,8 @@ void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const Clas
continue; continue;
table->initializeIfNeeded(exec); table->initializeIfNeeded(exec);
ASSERT(table->table); ASSERT(table->table);
#if ENABLE(PERFECT_HASH_SIZE)
int hashSizeMask = table->hashSizeMask;
#else
int hashSizeMask = table->compactSize - 1; int hashSizeMask = table->compactSize - 1;
#endif
const HashEntry* entry = table->table; const HashEntry* entry = table->table;
for (int i = 0; i <= hashSizeMask; ++i, ++entry) { for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
if (entry->key() && !(entry->attributes() & DontEnum)) if (entry->key() && !(entry->attributes() & DontEnum))
......
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