[svn:parrot] r48944 - in trunk: compilers/imcc include/parrot src src/pmc t/pmc

luben at svn.parrot.org luben at svn.parrot.org
Sat Sep 11 23:44:57 UTC 2010


Author: luben
Date: Sat Sep 11 23:44:56 2010
New Revision: 48944
URL: https://trac.parrot.org/parrot/changeset/48944

Log:
Merge hash_inlined_func branch

Modified:
   trunk/compilers/imcc/pbc.c
   trunk/include/parrot/hash.h
   trunk/src/global_setup.c
   trunk/src/hash.c
   trunk/src/oo.c
   trunk/src/pmc/addrregistry.pmc
   trunk/src/pmc/callcontext.pmc
   trunk/src/pmc/class.pmc
   trunk/src/pmc/hash.pmc
   trunk/src/pmc/stringbuilder.pmc
   trunk/t/pmc/packfile.t

Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/compilers/imcc/pbc.c	Sat Sep 11 23:44:56 2010	(r48944)
@@ -363,9 +363,7 @@
         /* initialize rlookup cache */
         interp->code->const_table->string_hash = parrot_create_hash(interp,
                 enum_type_INTVAL,
-                Hash_key_type_STRING,
-                hash_compare_string_distinct_enc,
-                (hash_hash_key_fn)key_hash_STRING);
+                Hash_key_type_STRING_enc);
         interp->code->const_table->constants =
             mem_gc_allocate_n_zeroed_typed(interp, newcount, PackFile_Constant);
     }

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/include/parrot/hash.h	Sat Sep 11 23:44:56 2010	(r48944)
@@ -26,16 +26,15 @@
 #define HASH_ALLOC_SIZE(n) (N_BUCKETS(n) * sizeof (HashBucket) + \
                                      (n) * sizeof (HashBucket *))
 
-typedef int (*hash_comp_fn)(PARROT_INTERP, ARGIN(const void *), ARGIN(const void *));
-typedef size_t (*hash_hash_key_fn)(PARROT_INTERP, ARGIN(const void *), size_t seed);
-
 /* &gen_from_enum(hash_key_type.pasm) */
 typedef enum {
     Hash_key_type_int,
     Hash_key_type_cstring,
     Hash_key_type_STRING,
     Hash_key_type_PMC,
-    Hash_key_type_ptr
+    Hash_key_type_ptr,
+    Hash_key_type_PMC_ptr,
+    Hash_key_type_STRING_enc,
 } Hash_key_type;
 /* &end_gen */
 
@@ -69,12 +68,6 @@
 
     /* Random seed value for seeding hash algorithms */
     size_t seed;
-
-    /* Comparison function pointer. Returns 0 if elements are equal */
-    hash_comp_fn   compare;
-
-    /* Function pointer to generate a hash value for the object */
-    hash_hash_key_fn hash_val;
 };
 
 /* Utility macros - use them, do not reinvent the wheel */
@@ -86,10 +79,8 @@
     UINTVAL     _found  = 0;                                                \
     while (_found < (_hash)->entries){                                      \
         if (_bucket->key){                                                  \
+            _code                                                           \
             _found++;                                                       \
-            {                                                               \
-                _code                                                       \
-            }                                                               \
         }                                                                   \
        _bucket++;                                                           \
     }                                                                       \
@@ -235,32 +226,28 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
-int hash_compare_cstring(SHIM_INTERP,
-    ARGIN(const char *a),
-    ARGIN(const char *b))
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
 int hash_compare_int(SHIM_INTERP,
     ARGIN_NULLOK(const void *a),
     ARGIN_NULLOK(const void *b));
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
+PARROT_INLINE
 int hash_compare_pmc(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 int hash_compare_pointer(SHIM_INTERP,
     ARGIN_NULLOK(const void *a),
     ARGIN_NULLOK(const void *b));
 
 PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 int hash_compare_string(PARROT_INTERP,
     ARGIN(const void *search_key),
     ARGIN_NULLOK(const void *bucket_key))
@@ -268,7 +255,7 @@
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-int hash_compare_string_distinct_enc(PARROT_INTERP,
+int hash_compare_string_enc(PARROT_INTERP,
     ARGIN(const void *search_key),
     ARGIN(const void *bucket_key))
         __attribute__nonnull__(1)
@@ -373,25 +360,21 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
-size_t key_hash_cstring(SHIM_INTERP, ARGIN(const void *value), size_t seed)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
 size_t key_hash_int(SHIM_INTERP,
     ARGIN_NULLOK(const void *value),
     size_t seed);
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
+PARROT_INLINE
 size_t key_hash_PMC(PARROT_INTERP, ARGIN(PMC *value), NULLOK(size_t seed))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-size_t key_hash_STRING(PARROT_INTERP,
-    ARGMOD(STRING *s),
-    NULLOK(size_t seed))
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+size_t key_hash_STRING(PARROT_INTERP, ARGMOD(STRING *s), size_t seed)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*s);
@@ -414,12 +397,8 @@
 PARROT_MALLOC
 Hash * parrot_create_hash(PARROT_INTERP,
     PARROT_DATA_TYPE val_type,
-    Hash_key_type hkey_type,
-    NOTNULL(hash_comp_fn compare),
-    NOTNULL(hash_hash_key_fn keyhash))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(4)
-        __attribute__nonnull__(5);
+    Hash_key_type hkey_type)
+        __attribute__nonnull__(1);
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
@@ -427,12 +406,8 @@
 Hash * parrot_create_hash_sized(PARROT_INTERP,
     PARROT_DATA_TYPE val_type,
     Hash_key_type hkey_type,
-    NOTNULL(hash_comp_fn compare),
-    NOTNULL(hash_hash_key_fn keyhash),
     UINTVAL size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(4)
-        __attribute__nonnull__(5);
+        __attribute__nonnull__(1);
 
 void parrot_hash_clone_prunable(PARROT_INTERP,
     ARGIN(const Hash *hash),
@@ -510,8 +485,7 @@
 #define ASSERT_ARGS_hash_compare_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(search_key))
-#define ASSERT_ARGS_hash_compare_string_distinct_enc \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_hash_compare_string_enc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(search_key) \
     , PARROT_ASSERT_ARG(bucket_key))
@@ -577,13 +551,9 @@
     , PARROT_ASSERT_ARG(hash) \
     , PARROT_ASSERT_ARG(func))
 #define ASSERT_ARGS_parrot_create_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(compare) \
-    , PARROT_ASSERT_ARG(keyhash))
+       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_parrot_create_hash_sized __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(compare) \
-    , PARROT_ASSERT_ARG(keyhash))
+       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_parrot_hash_clone_prunable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(hash) \

Modified: trunk/src/global_setup.c
==============================================================================
--- trunk/src/global_setup.c	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/global_setup.c	Sat Sep 11 23:44:56 2010	(r48944)
@@ -224,10 +224,8 @@
     }
     else {
         op_lib_t  *core_ops = PARROT_CORE_OPLIB_INIT(interp, 1);
-        interp->op_hash     = parrot_create_hash_sized(interp, enum_type_ptr, Hash_key_type_cstring,
-                                                        (hash_comp_fn)hash_compare_cstring,
-                                                        (hash_hash_key_fn)key_hash_cstring,
-                                                        core_ops->op_count);
+        interp->op_hash     = parrot_create_hash_sized(interp, enum_type_ptr, 
+                                    Hash_key_type_cstring, core_ops->op_count);
         parrot_hash_oplib(interp, core_ops);
     }
 

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/hash.c	Sat Sep 11 23:44:56 2010	(r48944)
@@ -54,7 +54,47 @@
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
+<<<<<<< HEAD
 PARROT_CONST_FUNCTION
+=======
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+static int hash_compare(PARROT_INTERP,
+    ARGIN(const Hash *hash),
+    ARGIN_NULLOK(void *a),
+    ARGIN_NULLOK(void *b))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+static int hash_compare_cstring(SHIM_INTERP,
+    ARGIN(const char *a),
+    ARGIN(const char *b))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+static size_t key_hash(PARROT_INTERP,
+    ARGIN(const Hash *hash),
+    ARGIN_NULLOK(void *key))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+static size_t key_hash_cstring(SHIM_INTERP,
+    ARGIN(const void *value),
+    size_t seed)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 static size_t key_hash_pointer(SHIM_INTERP,
     ARGIN(const void *value),
     size_t seed)
@@ -82,6 +122,17 @@
 #define ASSERT_ARGS_get_string_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(value))
+#define ASSERT_ARGS_hash_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(hash))
+#define ASSERT_ARGS_hash_compare_cstring __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(a) \
+    , PARROT_ASSERT_ARG(b))
+#define ASSERT_ARGS_key_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(hash))
+#define ASSERT_ARGS_key_hash_cstring __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(value))
 #define ASSERT_ARGS_key_hash_pointer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(value))
 #define ASSERT_ARGS_parrot_mark_hash_both __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -96,8 +147,6 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
-
-
 /*
 
 =item C<size_t key_hash_STRING(PARROT_INTERP, STRING *s, size_t seed)>
@@ -110,8 +159,10 @@
 
 
 PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 size_t
-key_hash_STRING(PARROT_INTERP, ARGMOD(STRING *s), SHIM(size_t seed))
+key_hash_STRING(PARROT_INTERP, ARGMOD(STRING *s), size_t seed)
 {
     ASSERT_ARGS(key_hash_STRING)
 
@@ -134,6 +185,8 @@
 */
 
 PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 int
 hash_compare_string(PARROT_INTERP, ARGIN(const void *search_key),
         ARGIN_NULLOK(const void *bucket_key))
@@ -142,17 +195,14 @@
     STRING const *s1 = (STRING const *)search_key;
     STRING const *s2 = (STRING const *)bucket_key;
 
-    if (s1->hashval != s2->hashval)
-        return 1;
-
-    return STRING_compare(interp, s1, s2);
+    return STRING_equal(interp, s1, s2) == 0;
 }
 
 
 /*
 
-=item C<int hash_compare_string_distinct_enc(PARROT_INTERP, const void
-*search_key, const void *bucket_key)>
+=item C<int hash_compare_string_enc(PARROT_INTERP, const void *search_key, const
+void *bucket_key)>
 
 Compare two strings. Returns 0 if they are identical. Considers differing
 charset or encoding to be distinct.
@@ -161,17 +211,19 @@
 
 PARROT_WARN_UNUSED_RESULT
 int
-hash_compare_string_distinct_enc(PARROT_INTERP, ARGIN(const void *search_key),
-                                                ARGIN(const void *bucket_key))
+hash_compare_string_enc(PARROT_INTERP, ARGIN(const void *search_key),
+                                       ARGIN(const void *bucket_key))
 {
-    ASSERT_ARGS(hash_compare_string_distinct_enc)
+    ASSERT_ARGS(hash_compare_string_enc)
     STRING const *s1 = (STRING const *)search_key;
     STRING const *s2 = (STRING const *)bucket_key;
 
+    if (s1->hashval != s2->hashval)
+        return 1;
     if (s1 && s2 && s1->encoding != s2->encoding)
         return 1;
-
-    return hash_compare_string(interp, search_key, bucket_key);
+    else
+        return memcmp(s1->strstart, s2->strstart, s1->bufused);
 }
 
 
@@ -186,7 +238,8 @@
 */
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 int
 hash_compare_pointer(SHIM_INTERP, ARGIN_NULLOK(const void *a), ARGIN_NULLOK(const void *b))
 {
@@ -207,7 +260,8 @@
 */
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 static size_t
 key_hash_pointer(SHIM_INTERP, ARGIN(const void *value), size_t seed)
 {
@@ -233,18 +287,18 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
-size_t
+PARROT_INLINE
+static size_t
 key_hash_cstring(SHIM_INTERP, ARGIN(const void *value), size_t seed)
 {
     ASSERT_ARGS(key_hash_cstring)
-    const unsigned char * p = (const unsigned char *) value;
-    register size_t       h = seed;
-
+    const char    * p = (const char *) value;
+    register size_t h = seed;
+    size_t        len = strlen(p);
     while (*p) {
         h += h << 5;
         h += *p++;
     }
-
     return h;
 }
 
@@ -262,7 +316,8 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
-int
+PARROT_INLINE
+static int
 hash_compare_cstring(SHIM_INTERP, ARGIN(const char *a), ARGIN(const char *b))
 {
     ASSERT_ARGS(hash_compare_cstring)
@@ -282,6 +337,7 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
+PARROT_INLINE
 size_t
 key_hash_PMC(PARROT_INTERP, ARGIN(PMC *value), SHIM(size_t seed))
 {
@@ -302,6 +358,7 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
+PARROT_INLINE
 int
 hash_compare_pmc(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
 {
@@ -329,7 +386,8 @@
 */
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 size_t
 key_hash_int(SHIM_INTERP, ARGIN_NULLOK(const void *value), size_t seed)
 {
@@ -350,7 +408,8 @@
 */
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CONST_FUNCTION
+PARROT_PURE_FUNCTION
+PARROT_INLINE
 int
 hash_compare_int(SHIM_INTERP, ARGIN_NULLOK(const void *a), ARGIN_NULLOK(const void *b))
 {
@@ -360,6 +419,80 @@
 
 /*
 
+=item C<static size_t key_hash(PARROT_INTERP, const Hash *hash, void *key)>
+
+Generic function to get the hashvalue of a given key. It may dispatches to
+key_hash_STRING, key_hash_cstring, etc. depending on hash->key_type.
+
+=cut
+
+*/
+
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+static size_t
+key_hash(PARROT_INTERP, ARGIN(const Hash *hash), ARGIN_NULLOK(void *key))
+{
+    ASSERT_ARGS(key_hash)
+
+    if (hash->key_type == Hash_key_type_STRING
+    ||  hash->key_type == Hash_key_type_STRING_enc)
+        return key_hash_STRING(interp, (STRING *)key, hash->seed);
+
+    if (hash->key_type == Hash_key_type_cstring)
+        return key_hash_cstring(interp, (char *)key, hash->seed);
+
+    if (hash->key_type == Hash_key_type_PMC)
+        return VTABLE_hashvalue(interp, (PMC *)key);
+
+    return ((size_t) key) ^ hash->seed;
+
+}
+
+/*
+
+=item C<static int hash_compare(PARROT_INTERP, const Hash *hash, void *a, void
+*b)>
+
+Generic function to compare values. It may dispatches to
+hash_compare_string, hash_compare_cstring, etc. depending on hash->key_type.
+
+=cut
+
+*/
+
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+PARROT_INLINE
+static int
+hash_compare(PARROT_INTERP, ARGIN(const Hash *hash), ARGIN_NULLOK(void *a),
+    ARGIN_NULLOK(void *b))
+{
+    ASSERT_ARGS(hash_compare)
+
+    if (a == b)
+        return 0;
+
+    if (hash->key_type == Hash_key_type_STRING)
+        return hash_compare_string(interp, (STRING *)a, (STRING *)b);
+
+    if (hash->key_type == Hash_key_type_STRING_enc)
+        return hash_compare_string_enc(interp, (STRING *)a, (STRING *)b);
+
+    if (hash->key_type == Hash_key_type_cstring)
+        return strcmp((char *)a, (char *)b);
+
+    if (hash->key_type == Hash_key_type_PMC)
+        return hash_compare_pmc(interp, (PMC *)a, (PMC *) b);
+
+    return 1;
+}
+
+/*
+
 =item C<void parrot_dump_hash(PARROT_INTERP, const Hash *hash)>
 
 Prints out the hash in human-readable form, at least once someone implements
@@ -401,7 +534,9 @@
         mark_value = 1;
 
     if (hash->key_type == Hash_key_type_STRING
-    ||  hash->key_type == Hash_key_type_PMC)
+    ||  hash->key_type == Hash_key_type_STRING_enc
+    ||  hash->key_type == Hash_key_type_PMC
+    ||  hash->key_type == Hash_key_type_PMC_ptr)
         mark_key = 1;
 
     if (mark_key) {
@@ -432,12 +567,13 @@
 {
     ASSERT_ARGS(parrot_mark_hash_keys)
 
-    if (hash->key_type == Hash_key_type_STRING) {
+    if (hash->key_type == Hash_key_type_STRING
+     || hash->key_type == Hash_key_type_STRING_enc) {
         parrot_hash_iterate(hash,
             PARROT_ASSERT(_bucket->key);
             Parrot_gc_mark_STRING_alive(interp, (STRING *)_bucket->key););
     }
-    else if (hash->key_type == Hash_key_type_PMC) {
+    else {
         parrot_hash_iterate(hash,
             PARROT_ASSERT(_bucket->key);
             Parrot_gc_mark_PMC_alive(interp, (PMC *)_bucket->key););
@@ -488,7 +624,8 @@
 {
     ASSERT_ARGS(parrot_mark_hash_both)
 
-    if (hash->key_type == Hash_key_type_STRING
+    if ((hash->key_type == Hash_key_type_STRING
+    ||   hash->key_type == Hash_key_type_STRING_enc)
     &&  hash->entry_type == (PARROT_DATA_TYPE) enum_hash_pmc) {
         parrot_hash_iterate(hash,
             PARROT_ASSERT(_bucket->key);
@@ -529,34 +666,7 @@
     const Hash_key_type     key_type    = (Hash_key_type)VTABLE_shift_integer(interp, info);
     const PARROT_DATA_TYPE  entry_type  = (PARROT_DATA_TYPE)VTABLE_shift_integer(interp, info);
     size_t                  entry_index;
-    Hash                   *hash;
-
-    {
-        hash_comp_fn     cmp_fn;
-        hash_hash_key_fn key_fn;
-
-        switch (key_type) {
-            case Hash_key_type_int:
-                key_fn = (hash_hash_key_fn)key_hash_int;
-                cmp_fn = (hash_comp_fn)hash_compare_int;
-                break;
-            case Hash_key_type_STRING:
-                key_fn = (hash_hash_key_fn)key_hash_STRING;
-                cmp_fn = (hash_comp_fn)hash_compare_string;
-                break;
-            case Hash_key_type_PMC:
-                key_fn = (hash_hash_key_fn)key_hash_PMC;
-                cmp_fn = (hash_comp_fn)hash_compare_pmc;
-                break;
-            default:
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                        "unimplemented key type");
-                break;
-        }
-
-        hash = parrot_create_hash_sized(interp, entry_type, key_type, cmp_fn, key_fn, num_entries);
-
-    }
+    Hash *hash = parrot_create_hash_sized(interp, entry_type, key_type, num_entries);
 
     /* special case for great speed */
     if (key_type   == Hash_key_type_STRING
@@ -581,12 +691,14 @@
             }
             break;
           case Hash_key_type_STRING:
+          case Hash_key_type_STRING_enc:
             {
                 STRING * const s_key = VTABLE_shift_string(interp, info);
                 key                  = (void *)s_key;
             }
             break;
           case Hash_key_type_PMC:
+          case Hash_key_type_PMC_ptr:
             {
                 PMC * const p_key = VTABLE_shift_pmc(interp, info);
                 key               = (void *)p_key;
@@ -660,9 +772,11 @@
             VTABLE_push_integer(interp, info, (INTVAL)_bucket->key);
             break;
           case Hash_key_type_STRING:
+          case Hash_key_type_STRING_enc:
             VTABLE_push_string(interp, info, (STRING *)_bucket->key);
             break;
           case Hash_key_type_PMC:
+          case Hash_key_type_PMC_ptr:
             VTABLE_push_pmc(interp, info, (PMC *)_bucket->key);
             break;
           default:
@@ -723,20 +837,18 @@
 expand_hash(PARROT_INTERP, ARGMOD(Hash *hash))
 {
     ASSERT_ARGS(expand_hash)
-    HashBucket  **old_bi, **new_bi;
-    HashBucket   *bs, *b, *new_mem;
-    HashBucket * const old_offset = (HashBucket *)((char *)hash + sizeof (Hash));
+    HashBucket  **new_index,  **index;
+    HashBucket   *new_buckets, *bucket;
+
+    HashBucket * const initial_offset = (HashBucket *)((char *)hash + sizeof (Hash));
 
+    void *        new_mem;
     void * const  old_mem    = hash->buckets;
     const UINTVAL old_size   = hash->mask + 1;
-    const UINTVAL new_size   = old_size << 1; /* Double. Right-shift is 2x */
-    const UINTVAL old_nb     = N_BUCKETS(old_size);
-    const UINTVAL new_nb     = N_BUCKETS(new_size);
+    const UINTVAL new_size   = old_size  << 1; /* Double. Right-shift is 2x */
+    const UINTVAL new_mask   = new_size   - 1;
     size_t        offset, i;
 
-    const hash_hash_key_fn hash_val_func = hash->hash_val;
-    const int              is_string_key = (hash_val_func == (hash_hash_key_fn)key_hash_STRING);
-
     /*
        allocate some less buckets
        e.g. 3 buckets, 4 pointers:
@@ -749,86 +861,103 @@
     */
 
     /* resize mem */
-    if (old_offset != old_mem) {
+    if (initial_offset != old_mem) {
         /* This buffer has been reallocated at least once before. */
-        new_mem = (HashBucket *)Parrot_gc_reallocate_memory_chunk_with_interior_pointers(
-                interp, old_mem, HASH_ALLOC_SIZE(new_size), HASH_ALLOC_SIZE(old_size));
+        new_mem   = Parrot_gc_reallocate_memory_chunk_with_interior_pointers(
+                interp, old_mem,
+                HASH_ALLOC_SIZE(new_size),
+                HASH_ALLOC_SIZE(old_size));
+
+        new_buckets = (HashBucket *)  new_mem;
+        new_index   = (HashBucket **)(new_buckets + N_BUCKETS(new_size));
+
+        offset = (char *)new_mem - (char *)old_mem;
+
+        /* old index is here */
+        index  = (HashBucket **)(new_buckets + N_BUCKETS(old_size));
+        /* reallocate index */
+        mem_sys_memcopy(new_index, index, sizeof (HashBucket *) * old_size);
+
+        /* clear second half of the buckets, freed by old the index */
+        memset(new_buckets + N_BUCKETS(old_size), 0,
+                sizeof (HashBucket *) * old_size);
     }
     else {
         /* Allocate a new buffer. */
-        new_mem = (HashBucket *)Parrot_gc_allocate_memory_chunk_with_interior_pointers(
+        new_mem = Parrot_gc_allocate_memory_chunk_with_interior_pointers(
                 interp, HASH_ALLOC_SIZE(new_size));
-        memcpy(new_mem, old_mem, HASH_ALLOC_SIZE(old_size));
+
+        new_buckets = (HashBucket *)  new_mem;
+        new_index   = (HashBucket **)(new_buckets + N_BUCKETS(new_size));
+
+        offset = (char *)new_buckets - (char *)hash->buckets;
+
+        mem_sys_memcopy(new_buckets, hash->buckets ,
+                N_BUCKETS(old_size) * sizeof (HashBucket));
+        mem_sys_memcopy(new_index,   hash->index,
+                sizeof (HashBucket *) * old_size);
     }
 
+
     /*
          +---+---+---+---+---+---+-+-+-+-+-+-+-+-+
-         |  buckets  | old_bi    |  new_bi       |
+         |  buckets  | old_index |  new_index    |
          +---+---+---+---+---+---+-+-+-+-+-+-+-+-+
          ^                       ^
          | new_mem               | hash->index
     */
 
-    bs     = new_mem;
-    old_bi = (HashBucket **)(bs + old_nb);
-    new_bi = (HashBucket **)(bs + new_nb);
-
-    /* things can have moved by this offset */
-    offset = (char *)new_mem - (char *)old_mem;
-
-    /* relocate the bucket index */
-    mem_sys_memmove(new_bi, old_bi, old_size * sizeof (HashBucket *));
-
     /* update hash data */
-    hash->index = new_bi;
-    hash->buckets        = bs;
-    hash->mask = new_size - 1;
-
-    /* clear freshly allocated bucket index */
-    memset(new_bi + old_size, 0, sizeof (HashBucket *) * (new_size - old_size));
+    hash->index     = new_index;
+    hash->buckets   = new_buckets;
+    hash->mask      = new_mask;
 
     /* reloc pointers and recalc bucket indices */
     for (i = 0; i < old_size; ++i) {
-        HashBucket **next_p = new_bi + i;
+        index = new_index + i;
 
-        while (*next_p != NULL) {
+        while (*index != NULL) {
             size_t new_loc;
             size_t hashval;
 
-            b = (HashBucket *)((char *)*next_p + offset);
+            bucket = (HashBucket *)((char *)*index + offset);
 
             /* rehash the bucket */
-            if (is_string_key) {
-                STRING *s = (STRING *)b->key;
+            if (hash->key_type == Hash_key_type_STRING
+            ||  hash->key_type == Hash_key_type_STRING_enc) {
+                STRING *s = (STRING *)bucket->key;
                 hashval   = s->hashval;
             }
             else {
-                hashval = hash_val_func(interp, b->key, hash->seed);
+                hashval = key_hash(interp, hash, bucket->key);
             }
 
-            new_loc = hashval & (new_size - 1);
+            new_loc = hashval & new_mask;
 
             if (i != new_loc) {
-                *next_p         = b->next;
-                b->next         = new_bi[new_loc];
-                new_bi[new_loc] = b;
+                *index              = bucket->next;
+                bucket->next        = new_index[new_loc];
+                new_index[new_loc]  = bucket;
             }
             else {
-                *next_p = b;
-                next_p  = &b->next;
+                *index = bucket;
+                index  = &bucket->next;
             }
         }
     }
 
     /* add new buckets to free_list
      * lowest bucket is top on free list and will be used first */
-    for (b = bs + old_nb; b < bs + new_nb - 1; ++b) {
-        b->next = b + 1;
-        b->key  = b->value = NULL;
+
+    bucket = new_buckets + N_BUCKETS(old_size);
+
+    for (; bucket < new_buckets + N_BUCKETS(new_size) - 1; ++bucket) {
+        bucket->next = bucket + 1;
+        bucket->key  = bucket->value = NULL;
     }
 
-    b->next = hash->free_list;
-    hash->free_list = bs + old_nb;
+    hash->free_list = new_buckets + N_BUCKETS(old_size);
+    bucket->next = NULL;
 }
 
 
@@ -850,9 +979,7 @@
     ASSERT_ARGS(parrot_new_hash)
     return parrot_create_hash(interp,
             enum_type_PMC,
-            Hash_key_type_STRING,
-            hash_compare_string,
-            (hash_hash_key_fn)key_hash_STRING);
+            Hash_key_type_STRING);
 }
 
 
@@ -874,9 +1001,7 @@
     ASSERT_ARGS(parrot_new_cstring_hash)
     return parrot_create_hash(interp,
             enum_type_PMC,
-            Hash_key_type_cstring,
-            (hash_comp_fn)hash_compare_cstring,
-            (hash_hash_key_fn)key_hash_cstring);
+            Hash_key_type_cstring);
 }
 
 
@@ -898,9 +1023,7 @@
     ASSERT_ARGS(parrot_new_pointer_hash)
     return parrot_create_hash(interp,
             enum_type_ptr,
-            Hash_key_type_ptr,
-            hash_compare_pointer,
-            key_hash_pointer);
+            Hash_key_type_ptr);
 }
 
 
@@ -925,15 +1048,13 @@
     ASSERT_ARGS(parrot_new_intval_hash)
     return parrot_create_hash(interp,
             enum_type_INTVAL,
-            Hash_key_type_int,
-            hash_compare_int,
-            key_hash_int);
+            Hash_key_type_int);
 }
 
 /*
 
 =item C<Hash * parrot_create_hash(PARROT_INTERP, PARROT_DATA_TYPE val_type,
-Hash_key_type hkey_type, hash_comp_fn compare, hash_hash_key_fn keyhash)>
+Hash_key_type hkey_type)>
 
 Creates and initializes a hash.  Function pointers determine its behaviors.
 
@@ -947,12 +1068,10 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_MALLOC
 Hash *
-parrot_create_hash(PARROT_INTERP, PARROT_DATA_TYPE val_type, Hash_key_type hkey_type,
-        NOTNULL(hash_comp_fn compare), NOTNULL(hash_hash_key_fn keyhash))
+parrot_create_hash(PARROT_INTERP, PARROT_DATA_TYPE val_type, Hash_key_type hkey_type)
 {
     ASSERT_ARGS(parrot_create_hash)
-    return parrot_create_hash_sized(interp, val_type, hkey_type, compare, keyhash,
-                                    INITIAL_SIZE);
+    return parrot_create_hash_sized(interp, val_type, hkey_type, INITIAL_SIZE);
 }
 
 
@@ -979,8 +1098,7 @@
 /*
 
 =item C<Hash * parrot_create_hash_sized(PARROT_INTERP, PARROT_DATA_TYPE
-val_type, Hash_key_type hkey_type, hash_comp_fn compare, hash_hash_key_fn
-keyhash, UINTVAL size)>
+val_type, Hash_key_type hkey_type, UINTVAL size)>
 
 Creates and initializes a hash, similar to C<parrot_create_hash>.
 
@@ -995,7 +1113,7 @@
 PARROT_MALLOC
 Hash *
 parrot_create_hash_sized(PARROT_INTERP, PARROT_DATA_TYPE val_type, Hash_key_type hkey_type,
-        NOTNULL(hash_comp_fn compare), NOTNULL(hash_hash_key_fn keyhash), UINTVAL size)
+        UINTVAL size)
 {
     ASSERT_ARGS(parrot_create_hash_sized)
     UINTVAL      initial_buckets = size > INITIAL_SIZE ? round_up_pow2(size) : INITIAL_SIZE;
@@ -1007,8 +1125,6 @@
 
     PARROT_ASSERT(initial_buckets % 4 == 0);
 
-    hash->compare    = compare;
-    hash->hash_val   = keyhash;
     hash->entry_type = val_type;
     hash->key_type   = hkey_type;
     hash->seed       = interp->hash_seed;
@@ -1150,57 +1266,53 @@
 parrot_hash_get_bucket(PARROT_INTERP, ARGIN(const Hash *hash), ARGIN_NULLOK(const void *key))
 {
     ASSERT_ARGS(parrot_hash_get_bucket)
-    UINTVAL     hashval;
+    DECL_CONST_CAST;
     HashBucket *bucket;
-    const hash_hash_key_fn hash_val = hash->hash_val;
-    const hash_comp_fn     compare  = hash->compare;
 
     if (hash->entries <= 0)
         return NULL;
 
-    if (hash_val == (hash_hash_key_fn)key_hash_STRING
-    &&  compare == hash_compare_string) {
-        /* fast path for string keys */
-        DECL_CONST_CAST;
-        STRING * const s = (STRING *)PARROT_const_cast(void *, key);
-
-        if (s->hashval)
-            hashval = s->hashval;
-        else
-            hashval = Parrot_str_to_hashval(interp, s);
+    if (hash->key_type == Hash_key_type_STRING) {
+        STRING * const s       = (STRING *)PARROT_const_cast(void *, key);
+        const size_t   hashval = key_hash_STRING(interp, s, hash->seed);
 
-        bucket = hash->index[hashval & hash->mask];
+        bucket                 = hash->index[hashval & hash->mask];
 
         while (bucket) {
             const STRING *s2 = (const STRING *)bucket->key;
 
-            if (s == s2
-            || (hashval == s2->hashval
-            &&  STRING_compare(interp, s, s2) == 0))
-                return bucket;
+            if (s == s2)
+                break;
+            /* manually inline part of string_equal  */
+            if (hashval == s2->hashval) {
+                if (s->encoding == s2->encoding){
+                    if ((STRING_byte_length(s) == STRING_byte_length(s2))
+                    && (memcmp(s->strstart, s2->strstart, STRING_byte_length(s)) == 0))
+                        break;
+                } else if (STRING_equal(interp, s, s2))
+                        break;
+            }
 
             bucket = bucket->next;
         }
     }
     else {
-        hashval = hash_val(interp, key, hash->seed);
-        bucket  = hash->index[hashval & hash->mask];
+        const size_t hashval = key_hash(interp, hash,
+                                    PARROT_const_cast(void *, key));
+        bucket               = hash->index[hashval & hash->mask];
 
         while (bucket) {
-            /* key equality is always a match, so it's worth checking */
-            if (bucket->key == key
-
-            /* ... but the slower comparison is more accurate */
-            || ((compare)(interp, key, bucket->key) == 0))
-                return bucket;
+            if (hash_compare(interp, hash,
+                    PARROT_const_cast(void *, key),
+                    bucket->key) == 0)
+                break;
             bucket = bucket->next;
         }
     }
 
-    return NULL;
+    return bucket;
 }
 
-
 /*
 
 =item C<void * parrot_hash_get(PARROT_INTERP, const Hash *hash, const void
@@ -1264,42 +1376,36 @@
         ARGIN_NULLOK(void *key), ARGIN_NULLOK(void *value))
 {
     ASSERT_ARGS(parrot_hash_put)
-    UINTVAL     hashval;
     HashBucket *bucket;
-    const hash_hash_key_fn hash_val = hash->hash_val;
-    const hash_comp_fn     compare  = hash->compare;
-
-    if (hash_val == (hash_hash_key_fn)key_hash_STRING
-    &&  compare == hash_compare_string) {
-        /* fast path for string keys */
-        STRING *s = (STRING *)key;
-
-        if (s->hashval)
-            hashval = s->hashval;
-        else
-            hashval = Parrot_str_to_hashval(interp, s);
+    size_t      hashval;
 
-        bucket = hash->index[hashval & hash->mask];
+    if (hash->key_type == Hash_key_type_STRING) {
+        const STRING * const s = (STRING *)key;
+        hashval                = key_hash_STRING(interp, s, hash->seed);
+        bucket                 = hash->index[hashval & hash->mask];
 
         while (bucket) {
             const STRING *s2 = (const STRING *)bucket->key;
-
-            if (s == s2
-            || (hashval == s2->hashval
-            &&  STRING_compare(interp, s, s2) == 0))
+            if (s == s2)
                 break;
-
+            /* manually inline part of string_equal  */
+            if (hashval == s2->hashval) {
+                if (s->encoding == s2->encoding) {
+                    if ((STRING_byte_length(s) == STRING_byte_length(s2))
+                    && (memcmp(s->strstart, s2->strstart, STRING_byte_length(s)) == 0))
+                        break;
+                } else if (STRING_equal(interp, s, s2))
+                        break;
+            }
             bucket = bucket->next;
         }
     }
     else {
-        hashval = hash_val(interp, key, hash->seed);
+        hashval = key_hash(interp, hash, key);
         bucket  = hash->index[hashval & hash->mask];
 
-        /* See if we have an existing value for this key */
         while (bucket) {
-            /* store hash_val or not */
-            if (compare(interp, key, bucket->key) == 0)
+            if (hash_compare(interp, hash, key, bucket->key) == 0)
                 break;
             bucket = bucket->next;
         }
@@ -1312,18 +1418,17 @@
     else {
         /* Get a new bucket off the free list. If the free list is empty, we
            expand the hash so we get more items on the free list */
-        bucket = hash->free_list;
-        if (!bucket) {
+        if (!hash->free_list)
             expand_hash(interp, hash);
-            bucket = hash->free_list;
-        }
+
+        bucket = hash->free_list;
 
         /* Add the value to the new bucket, increasing the count of elements */
         ++hash->entries;
-        hash->free_list                = bucket->next;
-        bucket->key                    = key;
-        bucket->value                  = value;
-        bucket->next = hash->index[hashval & hash->mask];
+        hash->free_list                   = bucket->next;
+        bucket->key                       = key;
+        bucket->value                     = value;
+        bucket->next                      = hash->index[hashval & hash->mask];
         hash->index[hashval & hash->mask] = bucket;
     }
 
@@ -1346,13 +1451,12 @@
 parrot_hash_delete(PARROT_INTERP, ARGMOD(Hash *hash), ARGIN(void *key))
 {
     ASSERT_ARGS(parrot_hash_delete)
-    const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed) & hash->mask;
+    const UINTVAL hashval = key_hash(interp, hash, key) & hash->mask;
     HashBucket   **prev   = &hash->index[hashval];
     if (*prev) {
-        const hash_comp_fn compare = hash->compare;
         for (; *prev; prev = &(*prev)->next) {
             HashBucket *current = *prev;
-            if ((compare)(interp, key, current->key) == 0) {
+            if (hash_compare(interp, hash, key, current->key) == 0) {
                 *prev = current->next;
                 --hash->entries;
                 current->next    = hash->free_list;
@@ -1407,12 +1511,6 @@
         void * const  key = _bucket->key;
 
         switch (hash->entry_type) {
-          case enum_type_undef:
-          case enum_type_ptr:
-          case enum_type_INTVAL:
-            valtmp = (void *)_bucket->value;
-            break;
-
           case enum_type_STRING:
             valtmp = _bucket->value;
             break;
@@ -1427,6 +1525,12 @@
                     valtmp = _bucket->value;
             break;
 
+          case enum_type_undef:
+          case enum_type_ptr:
+          case enum_type_INTVAL:
+            valtmp = (void *)_bucket->value;
+            break;
+
           default:
             valtmp = NULL; /* avoid warning */
             Parrot_ex_throw_from_c_args(interp, NULL, -1,
@@ -1534,9 +1638,11 @@
         break;
         /* Currently PMCs are stringified */
       case Hash_key_type_PMC:
+      case Hash_key_type_PMC_ptr:
         ret = (void *)get_integer_pmc(interp, key);
         break;
       case Hash_key_type_STRING:
+      case Hash_key_type_STRING_enc:
         ret = (void *)Parrot_str_from_int(interp, key);
         break;
       default:
@@ -1573,10 +1679,12 @@
       }
 
       case Hash_key_type_PMC:
+      case Hash_key_type_PMC_ptr:
         ret = get_string_pmc(interp, key);
         break;
 
       case Hash_key_type_STRING:
+      case Hash_key_type_STRING_enc:
         ret = key;
         break;
 
@@ -1611,6 +1719,7 @@
             break;
         }
       case Hash_key_type_PMC:
+      case Hash_key_type_PMC_ptr:
         {
             /* Extract real value from Key (and box it if nessary) */
             if (key->vtable->base_type == enum_class_Key)
@@ -1639,6 +1748,7 @@
             break;
         }
       case Hash_key_type_STRING:
+      case Hash_key_type_STRING_enc:
         {
             STRING * const tmp = VTABLE_get_string(interp, key);
             if (STRING_IS_NULL(tmp))
@@ -1674,9 +1784,11 @@
         ret = (INTVAL)key;
         break;
       case Hash_key_type_PMC:
+      case Hash_key_type_PMC_ptr:
         ret = VTABLE_get_integer(interp, (PMC *)key);
         break;
       case Hash_key_type_STRING:
+      case Hash_key_type_STRING_enc:
         ret = Parrot_str_to_int(interp, (STRING *)key);
         break;
       default:
@@ -1708,10 +1820,12 @@
         break;
 
       case Hash_key_type_PMC:
+      case Hash_key_type_PMC_ptr:
         ret = VTABLE_get_string(interp, (PMC *)key);
         break;
 
       case Hash_key_type_STRING:
+      case Hash_key_type_STRING_enc:
         ret = (STRING *)key;
         break;
 
@@ -1743,9 +1857,11 @@
         ret = get_integer_pmc(interp, (INTVAL)key);
         break;
       case Hash_key_type_PMC:
+      case Hash_key_type_PMC_ptr:
         ret = (PMC*)key;
         break;
       case Hash_key_type_STRING:
+      case Hash_key_type_STRING_enc:
         ret = get_string_pmc(interp, (STRING*)key);
         break;
       default:

Modified: trunk/src/oo.c
==============================================================================
--- trunk/src/oo.c	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/oo.c	Sat Sep 11 23:44:56 2010	(r48944)
@@ -260,8 +260,12 @@
          || base_type == enum_class_ResizableStringArray
          || base_type == enum_class_String)
             type = Parrot_pmc_get_type(interp, key);
-        else
+        else if (VTABLE_does(interp, key, CONST_STRING(interp, "string")) ||
+                base_type == enum_class_NameSpace)
             type = Parrot_pmc_get_type_str(interp, VTABLE_get_string(interp, key));
+        else
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                    "can't get class from an instance of class '%Ss'", VTABLE_name(interp, key));
 
         classobj = get_pmc_proxy(interp, type);
     }

Modified: trunk/src/pmc/addrregistry.pmc
==============================================================================
--- trunk/src/pmc/addrregistry.pmc	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/pmc/addrregistry.pmc	Sat Sep 11 23:44:56 2010	(r48944)
@@ -46,9 +46,7 @@
     VTABLE void init() {
         Hash  *registry = parrot_create_hash(INTERP,
                 enum_type_int,
-                Hash_key_type_PMC,
-                hash_compare_int,
-                key_hash_int);
+                Hash_key_type_PMC_ptr);
 
         SET_ATTR_hash(INTERP, SELF, registry);
         PObj_custom_mark_destroy_SETALL(SELF);

Modified: trunk/src/pmc/callcontext.pmc
==============================================================================
--- trunk/src/pmc/callcontext.pmc	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/pmc/callcontext.pmc	Sat Sep 11 23:44:56 2010	(r48944)
@@ -390,9 +390,7 @@
     if (!hash) {
         hash = parrot_create_hash(interp,
             enum_type_ptr,
-            Hash_key_type_STRING,
-            hash_compare_string,
-            (hash_hash_key_fn)key_hash_STRING);
+            Hash_key_type_STRING);
 
         SETATTR_CallContext_hash(interp, SELF, hash);
     }

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/pmc/class.pmc	Sat Sep 11 23:44:56 2010	(r48944)
@@ -141,11 +141,6 @@
         __attribute__nonnull__(3)
         __attribute__nonnull__(4);
 
-static size_t key_hash_pointer(SHIM_INTERP,
-    ARGIN(const void *value),
-    size_t seed)
-        __attribute__nonnull__(2);
-
 PARROT_CANNOT_RETURN_NULL
 static STRING * make_class_name(PARROT_INTERP, ARGIN(PMC *SELF))
         __attribute__nonnull__(1)
@@ -174,8 +169,6 @@
     , PARROT_ASSERT_ARG(object) \
     , PARROT_ASSERT_ARG(all_parents) \
     , PARROT_ASSERT_ARG(init))
-#define ASSERT_ARGS_key_hash_pointer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(value))
 #define ASSERT_ARGS_make_class_name __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(SELF))
@@ -184,22 +177,6 @@
 
 /*
 
-=item C<static size_t key_hash_pointer(PARROT_INTERP, const void *value, size_t
-seed)>
-
-=cut
-
-*/
-
-static size_t
-key_hash_pointer(SHIM_INTERP, ARGIN(const void *value), size_t seed)
-{
-    ASSERT_ARGS(key_hash_pointer)
-    return ((size_t) value ^ seed);
-}
-
-/*
-
 =item C<static int cache_class_attribs(PARROT_INTERP, PMC *cur_class, PMC
 *attrib_index, PMC *cache, int cur_index)>
 
@@ -685,9 +662,10 @@
 
         _class->vtable_overrides = Parrot_pmc_new(INTERP, enum_class_Hash);
         _class->parent_overrides = Parrot_pmc_new(INTERP, enum_class_Hash);
+
         _class->isa_cache        = parrot_create_hash(INTERP,
-            enum_type_INTVAL, Hash_key_type_PMC,
-            (hash_comp_fn)hash_compare_pointer, (hash_hash_key_fn)key_hash_pointer);
+            enum_type_INTVAL, Hash_key_type_PMC_ptr);
+
 
         /* We put ourself on the all parents list. */
         VTABLE_push_pmc(INTERP, _class->all_parents, SELF);

Modified: trunk/src/pmc/hash.pmc
==============================================================================
--- trunk/src/pmc/hash.pmc	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/pmc/hash.pmc	Sat Sep 11 23:44:56 2010	(r48944)
@@ -141,9 +141,7 @@
 
         attr->hash = parrot_create_hash(INTERP,
                 (PARROT_DATA_TYPE)value_type,
-                Hash_key_type_STRING,
-                hash_compare_string,
-                (hash_hash_key_fn)key_hash_STRING);
+                Hash_key_type_STRING);
         PObj_custom_mark_destroy_SETALL(SELF);
     }
 
@@ -233,23 +231,17 @@
         if (type == Hash_key_type_STRING)
             new_hash = parrot_create_hash(INTERP,
                     entry_type,
-                    Hash_key_type_STRING,
-                    hash_compare_string,
-                    (hash_hash_key_fn)key_hash_STRING);
+                    Hash_key_type_STRING);
         else if (type == Hash_key_type_int)
             /* new_int_hash set BOTH keys and values to INTVAL */
             new_hash = parrot_create_hash(INTERP,
                     entry_type,
-                    Hash_key_type_int,
-                    hash_compare_int,
-                    key_hash_int);
+                    Hash_key_type_int);
         else if (type == Hash_key_type_PMC)
             /* new_int_hash set BOTH keys and values to INTVAL */
             new_hash = parrot_create_hash(INTERP,
                     entry_type,
-                    Hash_key_type_PMC,
-                    (hash_comp_fn)hash_compare_pmc,
-                    (hash_hash_key_fn)key_hash_PMC);
+                    Hash_key_type_PMC);
         else
             /* We probably will not implement other types of keys. They are way
              * too dangerous to use from PIR */
@@ -310,9 +302,7 @@
           case enum_type_PMC:
             new_hash = parrot_create_hash(INTERP,
                         (PARROT_DATA_TYPE)type,
-                        old_hash ? old_hash->key_type : Hash_key_type_STRING,
-                        old_hash ? old_hash->compare  : hash_compare_string,
-                        old_hash ? old_hash->hash_val : (hash_hash_key_fn)key_hash_STRING);
+                        old_hash ? old_hash->key_type : Hash_key_type_STRING);
             break;
           default:
             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_UNIMPLEMENTED,

Modified: trunk/src/pmc/stringbuilder.pmc
==============================================================================
--- trunk/src/pmc/stringbuilder.pmc	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/src/pmc/stringbuilder.pmc	Sat Sep 11 23:44:56 2010	(r48944)
@@ -133,7 +133,7 @@
 */
 
     VTABLE STRING *get_string() {
-        STRING *buffer;
+        STRING *buffer, *result;
         GET_ATTR_buffer(INTERP, SELF, buffer);
         /* We need to build a new string because outside of StringBuilder
          * strings are immutable. */

Modified: trunk/t/pmc/packfile.t
==============================================================================
--- trunk/t/pmc/packfile.t	Sat Sep 11 23:04:26 2010	(r48943)
+++ trunk/t/pmc/packfile.t	Sat Sep 11 23:44:56 2010	(r48944)
@@ -271,7 +271,7 @@
     msg = 'set_keyed_str_msg'(skey)
     is(value, check, msg)
     inc i
-    if i < nkeys goto get_next    
+    if i < nkeys goto get_next
 
     i = 0
     push_eh unknown_key


More information about the parrot-commits mailing list