JavaScriptCore:

        Reviewed by Eric.

	- added a new HashCountedSet class for the common pattern of mapping items to counts that can change

        * kxmlcore/HashCountedSet.h: Added.
        (KXMLCore::HashCountedSet::*): Implemented, on top of HashMap.
        * kxmlcore/HashMap.h:
        (KXMLCore::HashMap::add): New method - does not replace existing value if key already present
	but otherwise like set().
        (KXMLCore::HashMap::set): Improved comments.
        * kxmlcore/HashMapPtrSpec.h:
        (KXMLCore::HashMap::add): Added to specializations too.
        * JavaScriptCore.xcodeproj/project.pbxproj: Add new  file.
        * kxmlcore/HashFunctions.h: Added include of stdint.h

	- replaced the custom hashtable for values protected from GC with HashCountedSet

        * kjs/collector.cpp:
        (KJS::Collector::protect): Moved code here from ProtectedValues::increaseProtectCount
	since the code is so simple now.
        (KJS::Collector::unprotect): Ditto for ProtectedValues::decreaseProtectCount.
        (KJS::Collector::markProtectedObjects): Updated for new way of doing things, now
	simpler and safer.
        (KJS::Collector::numReferencedObjects): ditto
        (KJS::Collector::rootObjectClasses): ditto
        * kjs/collector.h: Added protect and unprotect static methods
        * kjs/protect.h:
        (KJS::gcProtect): Updated for removal of ProtectedValues class
        (KJS::gcUnprotect): likewise
        * kjs/protected_values.cpp: Removed.
        * kjs/protected_values.h: Removed.

WebCore:

        Reviewed by Eric.

        - updated for new HashCountedSet class

        * ForwardingHeaders/kxmlcore/HashCountedSet.h: Added forwarding header.
        * khtml/ecma/kjs_binding.cpp: Moved #define to disable pointer specialization higher
	in the file.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@11561 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
index aacca99..791a777 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -24,6 +24,7 @@
 
 #include <kxmlcore/FastMalloc.h>
 #include <kxmlcore/FastMallocInternal.h>
+#include <kxmlcore/HashCountedSet.h>
 #include "internal.h"
 #include "list.h"
 #include "value.h"
@@ -378,16 +379,44 @@
 #endif
 }
 
+typedef HashCountedSet<JSCell *, PointerHash<JSCell *> > ProtectCounts;
+
+static ProtectCounts& protectedValues()
+{
+    static ProtectCounts pv;
+    return pv;
+}
+
+void Collector::protect(JSValue *k)
+{
+    assert(k);
+    assert(JSLock::lockCount() > 0);
+
+    if (SimpleNumber::is(k))
+      return;
+
+    protectedValues().insert(k->downcast());
+}
+
+void Collector::unprotect(JSValue *k)
+{
+    assert(k);
+    assert(JSLock::lockCount() > 0);
+
+    if (SimpleNumber::is(k))
+      return;
+
+    protectedValues().remove(k->downcast());
+}
+
 void Collector::markProtectedObjects()
 {
-  typedef ProtectedValues::KeyValue Entry;
-  Entry *table = ProtectedValues::_table;
-  Entry *end = table + ProtectedValues::_tableSize;
-  for (Entry *entry = table; entry != end; ++entry) {
-    JSCell *val = entry->key;
-    if (val && !val->marked()) {
+  ProtectCounts& pv = protectedValues();
+  ProtectCounts::iterator end = pv.end();
+  for (ProtectCounts::iterator it = pv.begin(); it != end; ++it) {
+    JSCell *val = it->first;
+    if (!val->marked())
       val->mark();
-    }
   }
 }
 
@@ -558,18 +587,7 @@
 
 size_t Collector::numReferencedObjects()
 {
-  size_t count = 0;
-
-  size_t size = ProtectedValues::_tableSize;
-  ProtectedValues::KeyValue *table = ProtectedValues::_table;
-  for (size_t i = 0; i < size; i++) {
-    JSCell *val = table[i].key;
-    if (val) {
-      ++count;
-    }
-  }
-
-  return count;
+  return protectedValues().size();
 }
 
 #if APPLE_CHANGES
@@ -606,19 +624,18 @@
 
 const void *Collector::rootObjectClasses()
 {
+  // FIXME: this should be a HashSet (or maybe even CountedHashSet)
   CFMutableSetRef classes = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 
-  int size = ProtectedValues::_tableSize;
-  ProtectedValues::KeyValue *table = ProtectedValues::_table;
-  for (int i = 0; i < size; i++) {
-    JSCell *val = table[i].key;
-    if (val) {
-      CFStringRef name = CFStringCreateWithCString(NULL, className(val), kCFStringEncodingASCII);
-      CFSetAddValue(classes, name);
-      CFRelease(name);
-    }
+  ProtectCounts& pv = protectedValues();
+  ProtectCounts::iterator end = pv.end();
+  for (ProtectCounts::iterator it = pv.begin(); it != end; ++it) {
+    JSCell *val = it->first;
+    CFStringRef name = CFStringCreateWithCString(NULL, className(val), kCFStringEncodingASCII);
+    CFSetAddValue(classes, name);
+    CFRelease(name);
   }
-  
+
   return classes;
 }