[svn:parrot] r48418 - in trunk: . include/parrot src src/dynpmc src/pmc

chromatic at svn.parrot.org chromatic at svn.parrot.org
Wed Aug 11 20:20:52 UTC 2010


Author: chromatic
Date: Wed Aug 11 20:20:52 2010
New Revision: 48418
URL: https://trac.parrot.org/parrot/changeset/48418

Log:
[hash] Moved hash constant checks to Hash PMCs.

This also allows the removal of the container element of the hash struct, a 9%
size savings.  Patch courtesy Luben Karavelov.

Modified:
   trunk/CREDITS
   trunk/include/parrot/hash.h
   trunk/src/dynpmc/dynlexpad.pmc
   trunk/src/hash.c
   trunk/src/pmc/hash.pmc

Modified: trunk/CREDITS
==============================================================================
--- trunk/CREDITS	Wed Aug 11 13:24:10 2010	(r48417)
+++ trunk/CREDITS	Wed Aug 11 20:20:52 2010	(r48418)
@@ -642,6 +642,10 @@
 E: lt at toetsch.at
 S: Herrnbaumgarten, Austria
 
+N: Luben Karavelov
+U: luben
+E: luben at unixsol.org
+
 N: Luca Barbato
 D: fix to make installable
 E: lu_zero at gentoo.org

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h	Wed Aug 11 13:24:10 2010	(r48417)
+++ trunk/include/parrot/hash.h	Wed Aug 11 20:20:52 2010	(r48418)
@@ -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;
 

Modified: trunk/src/dynpmc/dynlexpad.pmc
==============================================================================
--- trunk/src/dynpmc/dynlexpad.pmc	Wed Aug 11 13:24:10 2010	(r48417)
+++ trunk/src/dynpmc/dynlexpad.pmc	Wed Aug 11 20:20:52 2010	(r48418)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2005-2008, Parrot Foundation.
+Copyright (C) 2005-2010, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -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);
 

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Wed Aug 11 13:24:10 2010	(r48417)
+++ trunk/src/hash.c	Wed Aug 11 20:20:52 2010	(r48418)
@@ -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 */

Modified: trunk/src/pmc/hash.pmc
==============================================================================
--- trunk/src/pmc/hash.pmc	Wed Aug 11 13:24:10 2010	(r48417)
+++ trunk/src/pmc/hash.pmc	Wed Aug 11 20:20:52 2010	(r48418)
@@ -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);
@@ -456,6 +451,12 @@
         PMC    *box;
         HashBucket *b;
 
+        if (PObj_constant_TEST(SELF)
+        && !PObj_constant_TEST((PObj *)key))
+            Parrot_ex_throw_from_c_args(INTERP, NULL,
+                EXCEPTION_INVALID_OPERATION,
+                "Used non-constant PMC key in constant hash.");
+
         if (!nextkey) {
             parrot_hash_put(INTERP, hash, keystr,
                     hash_value_from_int(INTERP, hash, value));
@@ -491,6 +492,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 +644,17 @@
         PMC    *box;
         HashBucket *b;
 
+        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 PMC 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.");
+        }
+
         if (!nextkey) {
             parrot_hash_put(INTERP, hash, keystr,
                     hash_value_from_string(INTERP, hash, value));
@@ -665,6 +684,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 +703,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,6 +800,11 @@
         PMC    *box            = PMCNULL;
         HashBucket *b;
 
+        if (PObj_constant_TEST(SELF)
+        && !PObj_constant_TEST((PObj *)key))
+            Parrot_ex_throw_from_c_args(INTERP, NULL,
+                EXCEPTION_INVALID_OPERATION,
+                "Used non-constant PMC key in constant hash.");
 
         if (!nextkey) {
             PMC * const val = get_number_pmc(INTERP, value);
@@ -793,6 +836,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 +860,18 @@
         PMC    *box;
         HashBucket *b;
 
+        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 PMC 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 (!nextkey) {
             parrot_hash_put(INTERP, hash, keystr, value);
             return;
@@ -842,6 +903,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 +1237,6 @@
             PARROT_ASSERT((INTVAL)hash->key_type == k_type);
             PARROT_ASSERT(hash->entry_type       == v_type);
 
-            hash->container = SELF;
             hash->entries   = elems;
         }
     }


More information about the parrot-commits mailing list