[svn:parrot] r47871 - in branches/hash_allocator: include/parrot src src/call
whiteknight at svn.parrot.org
whiteknight at svn.parrot.org
Sat Jun 26 15:58:04 UTC 2010
Author: whiteknight
Date: Sat Jun 26 15:58:04 2010
New Revision: 47871
URL: https://trac.parrot.org/parrot/changeset/47871
Log:
[hash] fix several errors. Almost builds now except for some problems in unmanagedstruct
Modified:
branches/hash_allocator/include/parrot/hash.h
branches/hash_allocator/src/call/args.c
branches/hash_allocator/src/hash.c
Modified: branches/hash_allocator/include/parrot/hash.h
==============================================================================
--- branches/hash_allocator/include/parrot/hash.h Sat Jun 26 15:20:49 2010 (r47870)
+++ branches/hash_allocator/include/parrot/hash.h Sat Jun 26 15:58:04 2010 (r47871)
@@ -23,7 +23,7 @@
typedef UINTVAL BucketIndex;
#define INITBucketIndex ((BucketIndex)-2)
-#define N_BUCKETS(n) ((n) - (n)/4))
+#define N_BUCKETS(n) ((n) - (n)/4)
#define HASH_ALLOC_SIZE(n) ((n) * sizeof (HashBucket *))
typedef int (*hash_comp_fn)(PARROT_INTERP, ARGIN(const void *), ARGIN(const void *));
@@ -46,8 +46,8 @@
} HashBucket;
typedef struct _hashiteratorstate {
- INTVAL idx;
- HashBucket current;
+ UINTVAL idx;
+ HashBucket * current;
} HashIteratorState;
struct _hash {
@@ -147,17 +147,6 @@
__attribute__nonnull__(2);
PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-void * parrot_hash_get_idx(PARROT_INTERP,
- ARGIN(const Hash *hash),
- ARGMOD(PMC *key))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3)
- FUNC_MODIFIES(*key);
-
-PARROT_EXPORT
PARROT_IGNORABLE_RESULT
PARROT_CANNOT_RETURN_NULL
HashBucket* parrot_hash_put(PARROT_INTERP,
@@ -380,6 +369,15 @@
__attribute__nonnull__(3)
FUNC_MODIFIES(*dest);
+PARROT_CAN_RETURN_NULL
+void * Parrot_hash_get_next_key(PARROT_INTERP,
+ ARGIN(const Hash * hash),
+ ARGMOD(HashIteratorState *state))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(*state);
+
PARROT_WARN_UNUSED_RESULT
PARROT_PURE_FUNCTION
int PMC_compare(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
@@ -425,10 +423,6 @@
#define ASSERT_ARGS_parrot_hash_get_bucket __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(hash))
-#define ASSERT_ARGS_parrot_hash_get_idx __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(hash) \
- , PARROT_ASSERT_ARG(key))
#define ASSERT_ARGS_parrot_hash_put __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(hash))
@@ -524,6 +518,10 @@
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(hash) \
, PARROT_ASSERT_ARG(dest))
+#define ASSERT_ARGS_Parrot_hash_get_next_key __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(hash) \
+ , PARROT_ASSERT_ARG(state))
#define ASSERT_ARGS_PMC_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(a) \
Modified: branches/hash_allocator/src/call/args.c
==============================================================================
--- branches/hash_allocator/src/call/args.c Sat Jun 26 15:20:49 2010 (r47870)
+++ branches/hash_allocator/src/call/args.c Sat Jun 26 15:58:04 2010 (r47871)
@@ -497,13 +497,11 @@
/* Low-level hash iteration. */
for (index = 0; index < elements; ++index) {
- if (!PMC_IS_NULL(key)) {
- STRING * const name = (STRING *)Parrot_hash_get_next_key(interp,
- hash, &state);
- PARROT_ASSERT(name);
- VTABLE_set_pmc_keyed_str(interp, call_object, name,
- VTABLE_get_pmc_keyed_str(interp, aggregate, name));
- }
+ STRING * const name = (STRING *)Parrot_hash_get_next_key(interp,
+ hash, &state);
+ PARROT_ASSERT(name);
+ VTABLE_set_pmc_keyed_str(interp, call_object, name,
+ VTABLE_get_pmc_keyed_str(interp, aggregate, name));
}
}
else {
Modified: branches/hash_allocator/src/hash.c
==============================================================================
--- branches/hash_allocator/src/hash.c Sat Jun 26 15:20:49 2010 (r47870)
+++ branches/hash_allocator/src/hash.c Sat Jun 26 15:58:04 2010 (r47871)
@@ -13,9 +13,6 @@
creation, the types of key and value as well as appropriate compare and
hashing functions can be set.
-This hash implementation uses just one piece of malloced memory. The
-C<< hash->buckets >> bucket store points to this region.
-
=head2 Functions
=over 4
@@ -62,6 +59,16 @@
__attribute__nonnull__(3)
FUNC_MODIFIES(*info);
+static void hash_freeze_bucket(PARROT_INTERP,
+ ARGIN(const Hash *hash),
+ ARGMOD(PMC *info),
+ ARGIN(HashBucket * b))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ __attribute__nonnull__(4)
+ FUNC_MODIFIES(*info);
+
static void hash_thaw(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(PMC *info))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
@@ -111,6 +118,11 @@
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(hash) \
, PARROT_ASSERT_ARG(info))
+#define ASSERT_ARGS_hash_freeze_bucket __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(hash) \
+ , PARROT_ASSERT_ARG(info) \
+ , PARROT_ASSERT_ARG(b))
#define ASSERT_ARGS_hash_thaw __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(hash) \
@@ -678,7 +690,7 @@
size_t i;
for (i = 0; i < hash->entries; ++i) {
- HashBucket * b = hash->entries[i];
+ HashBucket * b = hash->bucket_indices[i];
while (b) {
hash_freeze_bucket(interp, hash, info, b);
b = b->next;
@@ -688,8 +700,8 @@
/*
-=item C<static void hash_freeze_bucket(PARROT_INTERP, ARGIN(const Hash *hash),
-ARGMOD(PMC *info), ARGIN(HashBucket * b))>
+=item C<static void hash_freeze_bucket(PARROT_INTERP, const Hash *hash, PMC
+*info, HashBucket * b)>
Freeze the contents of one bucket.
@@ -805,9 +817,10 @@
const UINTVAL old_size = hash->mask + 1;
const UINTVAL new_size = old_size << 1; /* Double. Left-shift is 2x */
const UINTVAL new_mask = new_size - 1;
+ UINTVAL i;
HashBucket ** const old_bi = hash->bucket_indices;
- HashBucket ** const new_bi = Parrot_gc_reallocate_fixed_size_storage(interp,
- new_size * sizeof (HashBucket *));
+ HashBucket ** const new_bi = Parrot_gc_reallocate_memory_chunk(interp,
+ hash->bucket_indices, new_size * sizeof (HashBucket *));
/* clear freshly allocated bucket index */
memset(new_bi + old_size, 0, sizeof (HashBucket *) * old_size);
@@ -993,8 +1006,9 @@
parrot_hash_destroy(PARROT_INTERP, ARGFREE_NOTNULL(Hash *hash))
{
ASSERT_ARGS(parrot_hash_destroy)
+ const UINTVAL size = (hash->mask + 1) * sizeof (HashBucket *);
Parrot_gc_free_memory_chunk(interp, hash->bucket_indices);
- Parrot_gc_free_fixed_size_storage(interp, hash);
+ Parrot_gc_free_fixed_size_storage(interp, size, hash);
}
@@ -1085,8 +1099,8 @@
/*
-=item C<void * Parrot_hash_get_next_key(PARROT_INTERP, ARGIN(const Hash * hash),
- ARGMOD(HashIteratorState *state)>
+=item C<void * Parrot_hash_get_next_key(PARROT_INTERP, const Hash * hash,
+HashIteratorState *state)>
Iterate through the hash using a state object to keep track of the current
position in the hash as we go. Results are undefined if you modify the hash
@@ -1096,9 +1110,10 @@
*/
+PARROT_CAN_RETURN_NULL
void *
Parrot_hash_get_next_key(PARROT_INTERP, ARGIN(const Hash * hash),
- ARGMOD(HashIteratorState *state)
+ ARGMOD(HashIteratorState *state))
{
INTVAL i = state->idx == INITBucketIndex ?
0 : state->idx;
@@ -1114,7 +1129,7 @@
}
bp = bp->next;
}
- if (result != null)
+ if (result != NULL)
break;
i++;
bp = hash->bucket_indices[i];
@@ -1124,73 +1139,6 @@
return result;
}
-
-/*
-
-=item C<void * parrot_hash_get_idx(PARROT_INTERP, const Hash *hash, PMC *key)>
-
-Finds the next index into the hash's internal storage for the given Key. Used
-by iterators. Ugly, and DEPRECATED.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-void *
-parrot_hash_get_idx(PARROT_INTERP, ARGIN(const Hash *hash), ARGMOD(PMC *key))
-{
- ASSERT_ARGS(parrot_hash_get_idx)
- HashBucket *b;
- void *res;
- INTVAL i = VTABLE_get_integer(interp, key);
- PMC *fake_bi;
- BucketIndex bi;
-
- /* idx directly in the bucket store, which is at negative
- * address from the data pointer */
- /* locate initial */
- const INTVAL size = (INTVAL)N_BUCKETS(hash->mask + 1);
-
- GETATTR_Key_next_key(interp, key, fake_bi);
- bi = (BucketIndex)fake_bi;
-
- if (bi == INITBucketIndex) {
- i = 0;
- SETATTR_Key_next_key(interp, key, NULL);
- }
- else if (i >= size || i < 0) {
- /* NOTE: These instances of SETATTR_Key_int_key can't be VTABLE
- * functions because of the "special" way hash iterators work. */
- SETATTR_Key_int_key(interp, key, -1);
- return NULL;
- }
-
- res = NULL;
-
- for (b = hash->buckets + i; i < size ; ++i, ++b) {
- /* XXX int keys may be zero - use different iterator */
- if (b->key) {
- if (!res)
- res = b->key;
-
- /* found next key - FIXME hash iter does auto next */
- else
- break;
- }
- }
-
- if (i >= size)
- i = -1;
-
- SETATTR_Key_int_key(interp, key, i);
-
- return res;
-}
-
-
/*
=item C<HashBucket * parrot_hash_get_bucket(PARROT_INTERP, const Hash *hash,
@@ -1332,7 +1280,7 @@
/* Add the value to the new bucket, increasing the count of elements */
++hash->entries;
- if ((double)(hash->entries / (hash->mash + 1)) > HASH_INDICES)
+ if ((double)(hash->entries / (hash->mask + 1)) > HASH_INDICES_RATIO)
expand_hash(interp, hash);
bucket->key = key;
@@ -1373,7 +1321,7 @@
hash->bucket_indices[hashval] = bucket->next;
--hash->entries;
- Parrot_gc_free_fixed_size_storage(interp, bucket);
+ Parrot_gc_free_fixed_size_storage(interp, sizeof (HashBucket), bucket);
return;
}
@@ -1422,40 +1370,44 @@
UINTVAL entries = hash->entries;
UINTVAL i;
- for (i = 0; i < entries; ++i) {
- void *valtmp;
- HashBucket *b = hash->buckets + i;
- void * const key = b->key;
-
- switch (hash->entry_type) {
- case enum_type_undef:
- case enum_type_ptr:
- case enum_type_INTVAL:
- valtmp = (void *)b->value;
- break;
+ for (i = 0; i <= hash->mask; ++i) {
+ HashBucket *b = hash->bucket_indices[i];
+ while (b) {
+ void * const key = b->key;
+ void *valtmp;
- case enum_type_STRING:
- valtmp = b->value;
- break;
+ switch (hash->entry_type) {
+ case enum_type_undef:
+ case enum_type_ptr:
+ case enum_type_INTVAL:
+ valtmp = (void *)b->value;
+ break;
- case enum_type_PMC:
- if (PMC_IS_NULL((PMC *)b->value))
- valtmp = (void *)PMCNULL;
- else
- if (deep)
- valtmp = (void *)VTABLE_clone(interp, (PMC*)b->value);
+ case enum_type_STRING:
+ valtmp = b->value;
+ break;
+
+ case enum_type_PMC:
+ if (PMC_IS_NULL((PMC *)b->value))
+ valtmp = (void *)PMCNULL;
else
- valtmp = b->value;
- break;
+ if (deep)
+ valtmp = (void *)VTABLE_clone(interp, (PMC*)b->value);
+ else
+ valtmp = b->value;
+ break;
- default:
- valtmp = NULL; /* avoid warning */
- Parrot_ex_throw_from_c_args(interp, NULL, -1,
- "hash corruption: type = %d\n", hash->entry_type);
- };
+ default:
+ valtmp = NULL; /* avoid warning */
+ Parrot_ex_throw_from_c_args(interp, NULL, -1,
+ "hash corruption: type = %d\n", hash->entry_type);
+ };
- if (key)
- parrot_hash_put(interp, dest, key, valtmp);
+ if (key)
+ parrot_hash_put(interp, dest, key, valtmp);
+
+ b = b->next;
+ }
}
}
More information about the parrot-commits
mailing list