[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