[svn:parrot] r47863 - in trunk: . compilers/data_json compilers/imcc compilers/pct compilers/pge compilers/tge config/auto/sizes config/auto/zlib docs/book/draft docs/book/pct docs/dev docs/pdds examples/embed examples/languages/abc examples/languages/squaak examples/pge ext/nqp-rx include/parrot lib/Parrot lib/Parrot/Configure/Step ports/cygwin ports/debian ports/fedora/2.3.0 ports/suse/2.2.0 runtime/parrot/languages runtime/parrot/library runtime/parrot/library/Math src src/call src/gc src/interp src/pmc src/runcore t/compilers/tge t/oo t/pmc t/src t/steps/init/hints tools/build tools/dev tools/util

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Sat Jun 26 12:50:09 UTC 2010


Author: whiteknight
Date: Sat Jun 26 12:50:08 2010
New Revision: 47863
URL: https://trac.parrot.org/parrot/changeset/47863

Log:
[hash] merge the short-lived hash_faster branch. Despite the name this branch brings no speed-ups, only some cleanups, documentation improvements, and a new 
benchmark file to help with testing future performance improvements in this system

Modified:
   trunk/   (props changed)
   trunk/compilers/data_json/Rules.mak   (props changed)
   trunk/compilers/imcc/Rules.in   (props changed)
   trunk/compilers/pct/Rules.mak   (props changed)
   trunk/compilers/pge/Rules.mak   (props changed)
   trunk/compilers/tge/Rules.mak   (props changed)
   trunk/config/auto/sizes/intval_maxmin_c.in   (props changed)
   trunk/config/auto/zlib/   (props changed)
   trunk/docs/book/draft/README   (props changed)
   trunk/docs/book/draft/appa_glossary.pod   (props changed)
   trunk/docs/book/draft/appb_patch_submission.pod   (props changed)
   trunk/docs/book/draft/appc_command_line_options.pod   (props changed)
   trunk/docs/book/draft/appd_build_options.pod   (props changed)
   trunk/docs/book/draft/appe_source_code.pod   (props changed)
   trunk/docs/book/draft/ch01_introduction.pod   (props changed)
   trunk/docs/book/draft/ch02_getting_started.pod   (props changed)
   trunk/docs/book/draft/ch07_dynpmcs.pod   (props changed)
   trunk/docs/book/draft/ch08_dynops.pod   (props changed)
   trunk/docs/book/draft/ch10_opcode_reference.pod   (props changed)
   trunk/docs/book/draft/ch11_directive_reference.pod   (props changed)
   trunk/docs/book/draft/ch12_operator_reference.pod   (props changed)
   trunk/docs/book/draft/chXX_hlls.pod   (props changed)
   trunk/docs/book/draft/chXX_library.pod   (props changed)
   trunk/docs/book/draft/chXX_testing_and_debugging.pod   (props changed)
   trunk/docs/book/pct/ch01_introduction.pod   (props changed)
   trunk/docs/book/pct/ch02_getting_started.pod   (props changed)
   trunk/docs/book/pct/ch03_compiler_tools.pod   (props changed)
   trunk/docs/book/pct/ch04_pge.pod   (props changed)
   trunk/docs/book/pct/ch05_nqp.pod   (props changed)
   trunk/docs/dev/c_functions.pod   (props changed)
   trunk/docs/pdds/pdd30_install.pod   (props changed)
   trunk/examples/embed/cotorra.c   (props changed)
   trunk/examples/languages/abc/   (props changed)
   trunk/examples/languages/squaak/   (props changed)
   trunk/examples/pge/demo.pir   (props changed)
   trunk/ext/nqp-rx/Rules.mak   (props changed)
   trunk/include/parrot/call.h   (props changed)
   trunk/include/parrot/gc_api.h   (props changed)
   trunk/include/parrot/hash.h
   trunk/include/parrot/runcore_api.h   (props changed)
   trunk/include/parrot/runcore_profiling.h   (props changed)
   trunk/include/parrot/runcore_trace.h   (props changed)
   trunk/lib/Parrot/Configure/Step/Test.pm   (props changed)
   trunk/lib/Parrot/H2inc.pm   (props changed)
   trunk/ports/cygwin/parrot-1.0.0-1.cygport   (props changed)
   trunk/ports/debian/libparrot-dev.install.in   (props changed)
   trunk/ports/debian/libparrot.install.in   (props changed)
   trunk/ports/debian/parrot-doc.install.in   (props changed)
   trunk/ports/debian/parrot.install.in   (props changed)
   trunk/ports/fedora/2.3.0/   (props changed)
   trunk/ports/suse/2.2.0/   (props changed)
   trunk/runtime/parrot/languages/   (props changed)
   trunk/runtime/parrot/library/Math/Rand.pir   (props changed)
   trunk/runtime/parrot/library/Rules.mak   (props changed)
   trunk/src/call/ops.c   (props changed)
   trunk/src/call/pcc.c   (props changed)
   trunk/src/gc/alloc_memory.c   (props changed)
   trunk/src/gc/alloc_resources.c   (props changed)
   trunk/src/gc/api.c   (props changed)
   trunk/src/gc/malloc.c   (props changed)
   trunk/src/gc/malloc_trace.c   (props changed)
   trunk/src/gc/mark_sweep.c   (props changed)
   trunk/src/gc/system.c   (props changed)
   trunk/src/hash.c
   trunk/src/interp/inter_cb.c   (props changed)
   trunk/src/interp/inter_create.c   (props changed)
   trunk/src/interp/inter_misc.c   (props changed)
   trunk/src/packfile.c
   trunk/src/pmc/callcontext.pmc
   trunk/src/pmc/hashiterator.pmc
   trunk/src/pmc/lexinfo.pmc
   trunk/src/pmc/unmanagedstruct.pmc
   trunk/src/runcore/cores.c   (props changed)
   trunk/src/runcore/main.c   (props changed)
   trunk/src/runcore/profiling.c   (props changed)
   trunk/src/runcore/trace.c   (props changed)
   trunk/t/compilers/tge/NoneGrammar.tg   (props changed)
   trunk/t/oo/objects.t   (props changed)
   trunk/t/oo/root_new.t   (props changed)
   trunk/t/pmc/namespace-old.t   (props changed)
   trunk/t/src/embed.t   (props changed)
   trunk/t/steps/init/hints/linux-01.t   (props changed)
   trunk/tools/build/h2inc.pl   (props changed)
   trunk/tools/dev/fetch_languages.pl   (props changed)
   trunk/tools/dev/mk_gitignore.pl   (props changed)
   trunk/tools/util/perlcritic-cage.conf   (props changed)

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/include/parrot/hash.h	Sat Jun 26 12:50:08 2010	(r47863)
@@ -9,10 +9,6 @@
 #ifndef PARROT_HASH_H_GUARD
 #define PARROT_HASH_H_GUARD
 
-/* Prototypes */
-
-/* Hash is really a hashtable, but 'hash' is standard perl nomenclature. */
-
 typedef enum {
     enum_hash_undef,
     enum_hash_int = enum_type_INTVAL,
@@ -22,14 +18,6 @@
     enum_hash_ptr = enum_type_ptr
 } HashEntryType;
 
-/*
- * hash_entry is currently unused in the hash structure
-
-typedef struct _hash_entry {
-    HashEntryType type;
-    UnionVal val;
-} HashEntry;
-*/
 
 /* A BucketIndex is an index into the pool of available buckets. */
 typedef UINTVAL BucketIndex;
@@ -59,18 +47,38 @@
 } HashBucket;
 
 struct _hash {
-    HashBucket *bs;             /* store of buckets */
-    HashBucket **bi;            /* list of Bucket pointers */
-    HashBucket *free_list;      /* empty buckets */
-    UINTVAL entries;            /* Number of values stored in hashtable */
-    UINTVAL mask;               /* alloced - 1 */
-    PMC *container;             /* e.g. the PerlHash PMC */
-    Hash_key_type key_type;     /* cstring, ascii-string, utf8-string */
-    PARROT_DATA_TYPE entry_type;/* type of value */
-    size_t seed;                /* randomizes the hash_key generation
-                                   updated for each new hash */
-    hash_comp_fn   compare;     /* compare two keys, 0 = equal */
-    hash_hash_key_fn hash_val;  /* generate a hash value for key */
+    /* Large slab store of buckets */
+    HashBucket *buckets;
+
+    /* List of Bucket pointers */
+    HashBucket **bucket_indices;
+
+    /* Store for empty buckets */
+    HashBucket *free_list;
+
+    /* Number of values stored in hashtable */
+    UINTVAL entries;
+
+    /* alloced - 1 */
+    UINTVAL mask;
+
+    /* The owner PMC */
+    PMC *container;
+
+    /* The type of key object this hash uses */
+    Hash_key_type key_type;
+
+    /* Type of value */
+    PARROT_DATA_TYPE entry_type;
+
+    /* 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;
 };
 
 typedef void (*value_free)(ARGFREE(void *));

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/src/hash.c	Sat Jun 26 12:50:08 2010	(r47863)
@@ -14,10 +14,7 @@
 hashing functions can be set.
 
 This hash implementation uses just one piece of malloced memory. The
-C<< hash->bs >> bucket store points to this region.
-
-This hash doesn't move during GC, therefore a lot of the old caveats
-don't apply.
+C<< hash->buckets >> bucket store points to this region.
 
 =head2 Functions
 
@@ -357,7 +354,7 @@
     if (a == b)
         return 0;
 
-    /* PMCs of different types are differ */
+    /* PMCs of different types are different */
     if (a->vtable->base_type != b->vtable->base_type)
         return 1;
 
@@ -427,8 +424,8 @@
 
 =item C<void parrot_mark_hash(PARROT_INTERP, Hash *hash)>
 
-Marks the hash and its contents as live.  Assumes that key and value are non
-null in all buckets.
+Marks the hash and its contents as live.  Assumes that key and value are
+non-null in all buckets.
 
 =cut
 
@@ -482,7 +479,7 @@
     INTVAL  i;
 
     for (i = hash->mask; i >= 0; --i) {
-        HashBucket *bucket = hash->bi[i];
+        HashBucket *bucket = hash->bucket_indices[i];
 
         while (bucket) {
             if (++found > entries)
@@ -518,7 +515,7 @@
     INTVAL  i;
 
     for (i = hash->mask; i >= 0; --i) {
-        HashBucket *bucket = hash->bi[i];
+        HashBucket *bucket = hash->bucket_indices[i];
 
         while (bucket) {
             if (++found > entries)
@@ -534,7 +531,6 @@
     }
 }
 
-
 /*
 
 =item C<static void parrot_mark_hash_both(PARROT_INTERP, Hash *hash)>
@@ -554,7 +550,7 @@
     INTVAL  i;
 
     for (i = hash->mask; i >= 0; --i) {
-        HashBucket *bucket = hash->bi[i];
+        HashBucket *bucket = hash->bucket_indices[i];
 
         while (bucket) {
             if (++found > entries)
@@ -678,7 +674,7 @@
     size_t           i;
 
     for (i = 0; i < hash->entries; ++i) {
-        HashBucket * const b = hash->bs+i;
+        HashBucket * const b = hash->buckets + i;
 
         switch (hash->key_type) {
           case Hash_key_type_int:
@@ -787,9 +783,9 @@
     HashBucket   *bs, *b, *new_mem;
     HashBucket * const old_offset = (HashBucket *)((char *)hash + sizeof (Hash));
 
-    void * const  old_mem    = hash->bs;
+    void * const  old_mem    = hash->buckets;
     const UINTVAL old_size   = hash->mask + 1;
-    const UINTVAL new_size   = old_size << 1;
+    const UINTVAL new_size   = old_size << 1; /* Double. Right-shift is 2x */
     const UINTVAL old_nb     = N_BUCKETS(old_size);
     size_t        offset, i;
 
@@ -798,10 +794,10 @@
        e.g. 3 buckets, 4 pointers:
 
          +---+---+---+-+-+-+-+
-         | --> bs    | -> bi |
+         | --> buckets |     |
          +---+---+---+-+-+-+-+
-         ^           ^
-         | old_mem   | hash->bi
+         ^             ^
+         | old_mem     | hash->bucket_indices
     */
 
     /* resize mem */
@@ -819,11 +815,12 @@
 
     /*
          +---+---+---+---+---+---+-+-+-+-+-+-+-+-+
-         |  bs       | old_bi    |  new_bi       |
+         |  buckets  | old_bi    |  new_bi       |
          +---+---+---+---+---+---+-+-+-+-+-+-+-+-+
-           ^                       ^
-         | new_mem                 | hash->bi
+         ^                       ^
+         | new_mem               | hash->bucket_indices
     */
+
     bs     = new_mem;
     old_bi = (HashBucket **)(bs + old_nb);
     new_bi = (HashBucket **)(bs + N_BUCKETS(new_size));
@@ -835,8 +832,8 @@
     mem_sys_memmove(new_bi, old_bi, old_size * sizeof (HashBucket *));
 
     /* update hash data */
-    hash->bi   = new_bi;
-    hash->bs   = bs;
+    hash->bucket_indices = new_bi;
+    hash->buckets        = bs;
     hash->mask = new_size - 1;
 
     /* clear freshly allocated bucket index */
@@ -1027,12 +1024,6 @@
     hash->entries    = 0;
     hash->container  = PMCNULL;
 
-    /*
-     * TODO if we have a significant amount of small hashes:
-     * - allocate a bigger hash structure e.g. 128 byte
-     * - use the bucket store and bi inside this structure
-     * - when reallocate copy this part
-     */
     bp = (HashBucket *)((char *)alloc + sizeof (Hash));
     hash->free_list = NULL;
 
@@ -1040,9 +1031,9 @@
      * buckets[i] directly in an OrderedHash, *if* nothing
      * was deleted */
 
-    hash->bs  = bp;
-    bp       += N_BUCKETS(INITIAL_BUCKETS);
-    hash->bi  = (HashBucket **)bp;
+    hash->buckets = bp;
+    bp += N_BUCKETS(INITIAL_BUCKETS);
+    hash->bucket_indices = (HashBucket **)bp;
 
     for (i = 0, --bp; i < N_BUCKETS(INITIAL_BUCKETS); ++i, --bp) {
         bp->next        = hash->free_list;
@@ -1052,7 +1043,6 @@
     return hash;
 }
 
-
 /*
 
 =item C<void parrot_hash_destroy(PARROT_INTERP, Hash *hash)>
@@ -1072,8 +1062,8 @@
 {
     ASSERT_ARGS(parrot_hash_destroy)
     HashBucket * const bp = (HashBucket*)((char*)hash + sizeof (Hash));
-    if (bp != hash->bs)
-        mem_gc_free(interp, hash->bs);
+    if (bp != hash->buckets)
+        mem_gc_free(interp, hash->buckets);
     mem_gc_free(interp, hash);
 }
 
@@ -1096,7 +1086,7 @@
     UINTVAL i;
 
     for (i = 0; i <= hash->mask; ++i) {
-        HashBucket *bucket = hash->bi[i];
+        HashBucket *bucket = hash->bucket_indices[i];
         while (bucket) {
             mem_gc_free(interp, bucket->key);
             mem_gc_free(interp, bucket->value);
@@ -1130,7 +1120,7 @@
     UINTVAL i;
 
     for (i = 0; i <= hash->mask; ++i) {
-        HashBucket *bucket = hash->bi[i];
+        HashBucket *bucket = hash->bucket_indices[i];
         while (bucket) {
             mem_gc_free(interp, bucket->key);
             func(bucket->value);
@@ -1209,7 +1199,7 @@
 
     res = NULL;
 
-    for (b = hash->bs + i; i < size ; ++i, ++b) {
+    for (b = hash->buckets + i; i < size ; ++i, ++b) {
         /* XXX int keys may be zero - use different iterator */
         if (b->key) {
             if (!res)
@@ -1258,7 +1248,7 @@
         UINTVAL        i;
 
         for (i = 0; i < entries; ++i) {
-            HashBucket * const bucket = hash->bs + i;
+            HashBucket * const bucket = hash->buckets + i;
 
             /* the hash->compare cost is too high for this fast path */
             if (bucket->key == key)
@@ -1269,7 +1259,7 @@
     /* if the fast search didn't work, try the normal hashing search */
     {
         const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed);
-        HashBucket   *bucket  = hash->bi[hashval & hash->mask];
+        HashBucket   *bucket  = hash->bucket_indices[hashval & hash->mask];
 
         while (bucket) {
             /* key equality is always a match, so it's worth checking */
@@ -1350,7 +1340,7 @@
 {
     ASSERT_ARGS(parrot_hash_put)
     const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed);
-    HashBucket   *bucket  = hash->bi[hashval & hash->mask];
+    HashBucket   *bucket  = hash->bucket_indices[hashval & hash->mask];
 
     /* When the hash is constant, check that the key and value are also
      * constant. */
@@ -1367,6 +1357,7 @@
                 "Used non-constant value in constant hash.");
     }
 
+    /* See if we have an existing value for this key */
     while (bucket) {
         /* store hash_val or not */
         if ((hash->compare)(interp, key, bucket->key) == 0)
@@ -1374,22 +1365,26 @@
         bucket = bucket->next;
     }
 
+    /* If we have a bucket already, put the value in it. Otherwise, we need
+       to get a new bucket */
     if (bucket)
         bucket->value = value;
     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) {
             expand_hash(interp, hash);
             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->bi[hashval & hash->mask];
-        hash->bi[hashval & hash->mask] = bucket;
+        bucket->next = hash->bucket_indices[hashval & hash->mask];
+        hash->bucket_indices[hashval & hash->mask] = bucket;
     }
 
     return bucket;
@@ -1415,13 +1410,13 @@
     HashBucket   *prev    = NULL;
     const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed) & hash->mask;
 
-    for (bucket = hash->bi[hashval]; bucket; bucket = bucket->next) {
+    for (bucket = hash->bucket_indices[hashval]; bucket; bucket = bucket->next) {
         if ((hash->compare)(interp, key, bucket->key) == 0) {
 
             if (prev)
                 prev->next = bucket->next;
             else
-                hash->bi[hashval] = bucket->next;
+                hash->bucket_indices[hashval] = bucket->next;
 
             --hash->entries;
             bucket->next    = hash->free_list;
@@ -1477,7 +1472,7 @@
 
     for (i = 0; i < entries; ++i) {
         void         *valtmp;
-        HashBucket   *b   = hash->bs+i;
+        HashBucket   *b   = hash->buckets + i;
         void * const  key = b->key;
 
         switch (hash->entry_type) {

Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/src/packfile.c	Sat Jun 26 12:50:08 2010	(r47863)
@@ -3223,7 +3223,7 @@
         return;
 
     for (i = 0; i <= hash->mask; ++i) {
-        HashBucket *bucket = hash->bi[i];
+        HashBucket *bucket = hash->bucket_indices[i];
 
         while (bucket) {
             PackFile_ConstTable * const table      =

Modified: trunk/src/pmc/callcontext.pmc
==============================================================================
--- trunk/src/pmc/callcontext.pmc	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/src/pmc/callcontext.pmc	Sat Jun 26 12:50:08 2010	(r47863)
@@ -377,7 +377,7 @@
     INTVAL  i;
 
     for (i = h->mask; i >= 0; --i) {
-        HashBucket *b = h->bi[i];
+        HashBucket *b = h->bucket_indices[i];
 
         while (b) {
             Parrot_gc_mark_STRING_alive(interp, (STRING *)b->key);
@@ -403,7 +403,7 @@
         result = Parrot_pmc_new_init_int(interp, enum_class_FixedStringArray, hash->entries);
 
         for (i = 0; i <= hash->mask; ++i) {
-            HashBucket *b = hash->bi[i];
+            HashBucket *b = hash->bucket_indices[i];
 
             while (b) {
                 VTABLE_set_string_keyed_int(interp, result,
@@ -600,7 +600,7 @@
             UINTVAL i;
 
             for (i = 0; i <= hash->mask; ++i) {
-                HashBucket *b = hash->bi[i];
+                HashBucket *b = hash->bucket_indices[i];
 
                 while (b) {
                     FREE_CELL(INTERP, (Pcc_cell *)b->value);
@@ -638,7 +638,7 @@
             UINTVAL i;
 
             for (i = 0; i <= hash->mask; ++i) {
-                HashBucket *b = hash->bi[i];
+                HashBucket *b = hash->bucket_indices[i];
 
                 while (b) {
                     FREE_CELL(INTERP, (Pcc_cell *)b->value);

Modified: trunk/src/pmc/hashiterator.pmc
==============================================================================
--- trunk/src/pmc/hashiterator.pmc	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/src/pmc/hashiterator.pmc	Sat Jun 26 12:50:08 2010	(r47863)
@@ -87,7 +87,7 @@
         if (attrs->pos == attrs->total_buckets)
             break;
 
-        bucket = attrs->parrot_hash->bi[attrs->pos++];
+        bucket = attrs->parrot_hash->bucket_indices[attrs->pos++];
     }
     attrs->bucket = bucket;
     --attrs->elements;

Modified: trunk/src/pmc/lexinfo.pmc
==============================================================================
--- trunk/src/pmc/lexinfo.pmc	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/src/pmc/lexinfo.pmc	Sat Jun 26 12:50:08 2010	(r47863)
@@ -105,7 +105,7 @@
             INTVAL  i;
 
             for (i = hash->mask; i >= 0; --i) {
-                HashBucket *bucket = hash->bi[i];
+                HashBucket *bucket = hash->bucket_indices[i];
                 while (bucket) {
                     if (++found > entries)
                         Parrot_ex_throw_from_c_args(INTERP, NULL, 1,

Modified: trunk/src/pmc/unmanagedstruct.pmc
==============================================================================
--- trunk/src/pmc/unmanagedstruct.pmc	Sat Jun 26 12:30:53 2010	(r47862)
+++ trunk/src/pmc/unmanagedstruct.pmc	Sat Jun 26 12:50:08 2010	(r47863)
@@ -241,7 +241,7 @@
                 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_KEY_NOT_FOUND,
                     "key doesn't exist");
 
-            ix = b - hash->bs;
+            ix = b - hash->buckets;
         }
         else
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,


More information about the parrot-commits mailing list