On 11.08.2010 22:45, luben karavelov wrote:
As a part of the hash-cleanup effort, I have attached a patch that moves
the checks for constant keys/values out of the src/hash.c in
corresponding PMCs. All test pass. The only functional difference is
that if hash table is constant and is indexed by PMC I also check that
key PMC is constant.
It looks that the new behaviour that check PMC keys if they are constant
is putting weight on our calling convention.
So here is a patch that does the same as above, but do not introduce new
checks.
luben
Index: src/hash.c
===================================================================
--- src/hash.c (revision 48417)
+++ src/hash.c (working copy)
@@ -1027,8 +1027,6 @@
Hash_key_type hkey_type, hash_comp_fn compare, hash_hash_key_fn keyhash)>
Creates and initializes a hash. Function pointers determine its behaviors.
-The container passed in is the address of the hash PMC that is using it. The
-hash and the PMC point to each other.
Memory from this function must be freed.
@@ -1059,7 +1057,6 @@
hash->seed = interp->hash_seed;
hash->mask = INITIAL_BUCKETS - 1;
hash->entries = 0;
- hash->container = PMCNULL;
bp = (HashBucket *)((char *)alloc + sizeof (Hash));
hash->free_list = NULL;
@@ -1367,21 +1364,6 @@
HashBucket *bucket = hash->bucket_indices[hashval & hash->mask];
const hash_comp_fn compare = hash->compare;
- /* When the hash is constant, check that the key and value are also
- * constant. */
- if (!PMC_IS_NULL(hash->container)
- && PObj_constant_TEST(hash->container)) {
- if (hash->key_type == Hash_key_type_STRING
- && !PObj_constant_TEST((PObj *)key))
- Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_INVALID_OPERATION,
- "Used non-constant key in constant hash.");
- if (((hash->entry_type == enum_type_PMC)
- || (hash->entry_type == enum_type_STRING))
- && !PObj_constant_TEST((PObj *)value))
- Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_INVALID_OPERATION,
- "Used non-constant value in constant hash.");
- }
-
/* See if we have an existing value for this key */
while (bucket) {
/* store hash_val or not */
Index: src/pmc/hash.pmc
===================================================================
--- src/pmc/hash.pmc (revision 48417)
+++ src/pmc/hash.pmc (working copy)
@@ -78,7 +78,6 @@
(Parrot_Hash_attributes *) PMC_data(SELF);
attr->hash = parrot_new_hash(INTERP);
- attr->hash->container = SELF;
PObj_custom_mark_destroy_SETALL(SELF);
}
@@ -91,7 +90,6 @@
Hash_key_type_STRING,
STRING_compare,
(hash_hash_key_fn)key_hash_STRING);
- attr->hash->container = SELF;
PObj_custom_mark_destroy_SETALL(SELF);
}
@@ -150,7 +148,6 @@
Hash * const new_hash = (Hash *)ptr;
PARROT_HASH(SELF)->hash = new_hash;
- new_hash->container = SELF;
if (old_hash)
parrot_hash_destroy(INTERP, old_hash);
@@ -206,7 +203,6 @@
PARROT_HASH(SELF)->hash = new_hash;
- new_hash->container = SELF;
if (old_hash)
parrot_hash_destroy(INTERP, old_hash);
@@ -269,7 +265,6 @@
}
PARROT_HASH(SELF)->hash = new_hash;
- new_hash->container = SELF;
if (old_hash)
parrot_hash_destroy(INTERP, old_hash);
@@ -491,6 +486,13 @@
VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) {
Hash * const hash = (Hash *)SELF.get_pointer();
+
+ if (PObj_constant_TEST(SELF)
+ && !PObj_constant_TEST((PObj *)key))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant key in constant hash.");
+
parrot_hash_put(INTERP, hash, hash_key_from_string(INTERP, hash, key),
hash_value_from_int(INTERP, hash, value));
}
@@ -636,6 +638,12 @@
PMC *box;
HashBucket *b;
+ if (PObj_constant_TEST(SELF)
+ && !PObj_constant_TEST((PObj *)value))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING value in constant hash.");
+
if (!nextkey) {
parrot_hash_put(INTERP, hash, keystr,
hash_value_from_string(INTERP, hash, value));
@@ -665,6 +673,18 @@
VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
Hash * const hash = (Hash *)SELF.get_pointer();
+
+ if (PObj_constant_TEST(SELF)){
+ if (!PObj_constant_TEST((PObj *)key))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING key in constant hash.");
+ if (!PObj_constant_TEST((PObj *)value))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING value in constant hash.");
+ }
+
parrot_hash_put(INTERP, hash,
hash_key_from_string(INTERP, hash, key),
hash_value_from_string(INTERP, hash, value));
@@ -672,6 +692,13 @@
VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
Hash * const hash = (Hash *)SELF.get_pointer();
+
+ if ((PObj_constant_TEST(SELF))
+ && (!PObj_constant_TEST((PObj *)value)))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING value in constant hash.");
+
parrot_hash_put(INTERP, hash,
hash_key_from_int(INTERP, hash, key),
hash_value_from_string(INTERP, hash, value));
@@ -762,7 +789,6 @@
PMC *box = PMCNULL;
HashBucket *b;
-
if (!nextkey) {
PMC * const val = get_number_pmc(INTERP, value);
parrot_hash_put(INTERP, hash, keystr, hash_value_from_pmc(INTERP,
hash, val));
@@ -793,6 +819,12 @@
VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) {
PMC * const val = get_number_pmc(INTERP, value);
+ if (PObj_constant_TEST(SELF)
+ && !PObj_constant_TEST((PObj *)key))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING key in constant hash.");
+
parrot_hash_put(INTERP, (Hash *)SELF.get_pointer(), key, val);
}
@@ -811,6 +843,12 @@
PMC *box;
HashBucket *b;
+ if (PObj_constant_TEST(SELF)
+ && !PObj_constant_TEST((PObj *)value))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant PMC value in constant hash.");
+
if (!nextkey) {
parrot_hash_put(INTERP, hash, keystr, value);
return;
@@ -842,6 +880,19 @@
VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
Hash * const hash = (Hash *)SELF.get_pointer();
+
+ if (PObj_constant_TEST(SELF)) {
+ if (!PObj_constant_TEST((PObj *)key))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING key in constant hash.");
+
+ if (!PObj_constant_TEST((PObj *)value))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING value in constant hash.");
+ }
+
parrot_hash_put(INTERP, hash, hash_key_from_string(INTERP, hash, key),
hash_value_from_pmc(INTERP, hash, value));
}
@@ -1163,7 +1214,6 @@
PARROT_ASSERT((INTVAL)hash->key_type == k_type);
PARROT_ASSERT(hash->entry_type == v_type);
- hash->container = SELF;
hash->entries = elems;
}
}
Index: src/dynpmc/dynlexpad.pmc
===================================================================
--- src/dynpmc/dynlexpad.pmc (revision 48417)
+++ src/dynpmc/dynlexpad.pmc (working copy)
@@ -52,7 +52,6 @@
hash = parrot_new_hash(INTERP);
attrs->hash = hash;
- hash->container = SELF;
PObj_custom_mark_destroy_SETALL(SELF);
}
@@ -166,6 +165,17 @@
VTABLE void set_pmc_keyed_str(STRING* name, PMC* value) {
PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
+ if (PObj_constant_TEST(SELF)) {
+ if (!PObj_constant_TEST((PObj *)name))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant STRING key in constant hash.");
+ if (!PObj_constant_TEST((PObj *)value))
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Used non-constant PMC value in constant hash.");
+ }
+
if (std_pad && VTABLE_exists_keyed_str(INTERP, std_pad, name))
VTABLE_set_pmc_keyed_str(INTERP, std_pad, name, value);
Index: include/parrot/hash.h
===================================================================
--- include/parrot/hash.h (revision 48417)
+++ include/parrot/hash.h (working copy)
@@ -62,9 +62,6 @@
/* alloced - 1 */
UINTVAL mask;
- /* The owner PMC */
- PMC *container;
-
/* The type of key object this hash uses */
Hash_key_type key_type;
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev