[svn:parrot] r46404 - in trunk: compilers/imcc include/parrot src

plobsing at svn.parrot.org plobsing at svn.parrot.org
Sat May 8 09:29:06 UTC 2010


Author: plobsing
Date: Sat May  8 09:29:05 2010
New Revision: 46404
URL: https://trac.parrot.org/parrot/changeset/46404

Log:
cache pbc strings upon insertion
cuts single-threaded rakudo build time in half for me

Modified:
   trunk/compilers/imcc/pbc.c
   trunk/include/parrot/hash.h
   trunk/src/hash.c
   trunk/src/packout.c

Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c	Sat May  8 08:17:29 2010	(r46403)
+++ trunk/compilers/imcc/pbc.c	Sat May  8 09:29:05 2010	(r46404)
@@ -356,13 +356,21 @@
     PackFile_Constant *new_constant = PackFile_Constant_new(interp);
 
     /* Update the constant count and reallocate */
-    if (interp->code->const_table->constants)
+    if (interp->code->const_table->constants) {
         interp->code->const_table->constants =
             mem_gc_realloc_n_typed_zeroed(interp, interp->code->const_table->constants,
                 newcount, oldcount, PackFile_Constant *);
-    else
+    }
+    else {
+        /* initialize rlookup cache */
+        interp->code->const_table->string_hash =
+            Parrot_pmc_new_init_int(interp, enum_class_Hash, enum_type_INTVAL);
+        ((Hash *)VTABLE_get_pointer(interp, interp->code->const_table->string_hash))->compare =
+            (hash_comp_fn)STRING_compare_distinct_cs_enc;
+
         interp->code->const_table->constants =
             mem_gc_allocate_n_zeroed_typed(interp, newcount, PackFile_Constant *);
+    }
 
     interp->code->const_table->constants[oldcount] = new_constant;
     interp->code->const_table->const_count         = newcount;
@@ -998,6 +1006,8 @@
         constant->type              = PFC_STRING;
         constant->u.string          = s;
 
+        VTABLE_set_integer_keyed_str(interp, table->string_hash, s, k);
+
         return k;
     }
 }

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h	Sat May  8 08:17:29 2010	(r46403)
+++ trunk/include/parrot/hash.h	Sat May  8 09:29:05 2010	(r46404)
@@ -380,6 +380,14 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
+int STRING_compare_distinct_cs_enc(PARROT_INTERP,
+    ARGIN(const void *search_key),
+    ARGIN(const void *bucket_key))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
 #define ASSERT_ARGS_parrot_dump_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_parrot_hash_clone __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
@@ -505,6 +513,11 @@
 #define ASSERT_ARGS_STRING_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(search_key))
+#define ASSERT_ARGS_STRING_compare_distinct_cs_enc \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(search_key) \
+    , PARROT_ASSERT_ARG(bucket_key))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/hash.c */
 

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Sat May  8 08:17:29 2010	(r46403)
+++ trunk/src/hash.c	Sat May  8 09:29:05 2010	(r46404)
@@ -193,6 +193,35 @@
 
 /*
 
+=item C<int STRING_compare_distinct_cs_enc(PARROT_INTERP, const void
+*search_key, const void *bucket_key)>
+
+Compare two strings. Returns 0 if they are identical. Considers differing
+charset or encoding to be distinct.
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+int
+STRING_compare_distinct_cs_enc(PARROT_INTERP, ARGIN(const void *search_key),
+                                                ARGIN(const void *bucket_key))
+{
+    ASSERT_ARGS(STRING_compare_distinct_cs_enc)
+    STRING const *s1 = (STRING const *)search_key;
+    STRING const *s2 = (STRING const *)bucket_key;
+
+    if (s1 && s2 && (
+            s1->charset != s2->charset ||
+            s1->encoding != s2->encoding)) {
+        return 1;
+    }
+
+    return STRING_compare(interp, search_key, bucket_key);
+}
+
+
+/*
+
 =item C<static int pointer_compare(PARROT_INTERP, const void *a, const void *b)>
 
 Compares the two pointers, returning 0 if they are identical

Modified: trunk/src/packout.c
==============================================================================
--- trunk/src/packout.c	Sat May  8 08:17:29 2010	(r46403)
+++ trunk/src/packout.c	Sat May  8 09:29:05 2010	(r46404)
@@ -260,43 +260,12 @@
     GETATTR_Key_str_key(interp, key, key_str);
     GETATTR_Key_num_key(interp, key, key_num);
 
-    /*
-     * string_hash contains array of all possible charset/encoding
-     * combinations for given string.
-     *
-     * Because we don't have templateble PMC like tuple<charset, encoding, i>
-     * we store FIA [charset ^ encoding, i].
-     *
-     * So cache looks like this:
-     *   "foo" => [
-     *      [charset1 ^ encoding1, index1],
-     *      ...
-     *      [charsetN ^ encodingN, indexN]
-     *   ]
-     */
-
-    if (type == PFC_STRING) {
-        /* Auto-vivify cache */
-        if (PMC_IS_NULL(ct->string_hash)) {
-            DECL_CONST_CAST;
-            PackFile_ConstTable * c = PARROT_const_cast(PackFile_ConstTable*, ct);
-            c->string_hash = Parrot_pmc_new(interp, enum_class_Hash);
+    if (type == PFC_STRING && !PMC_IS_NULL(ct->string_hash)) {
+        if (VTABLE_exists_keyed_str(interp, ct->string_hash, key_str)) {
+            return VTABLE_get_integer_keyed_str(interp, ct->string_hash, key_str);
         }
-
-        /* Auto-vivify cache item */
-        string_list = VTABLE_get_pmc_keyed_str(interp, ct->string_hash, key_str);
-        if (PMC_IS_NULL(string_list)) {
-            string_list = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
-            VTABLE_set_pmc_keyed_str(interp, ct->string_hash, key_str, string_list);
-        }
-
-        /* Iterate of cache and try to find exactly this string */
-        strings = VTABLE_elements(interp, string_list);
-        for (i = 0; i < strings; ++i) {
-            PMC    *item = VTABLE_get_pmc_keyed_int(interp, string_list, i);
-            INTVAL xored = VTABLE_get_integer_keyed_int(interp, item, 0);
-            if (((size_t)key_str->encoding ^ (size_t)key_str->charset) == (size_t)xored)
-                return VTABLE_get_integer_keyed_int(interp, item, 1);
+        else {
+            return -1;
         }
     }
 
@@ -312,14 +281,6 @@
                 ==  Parrot_charset_number_of_str(interp, sc)
                 &&  Parrot_encoding_number_of_str(interp, key_str)
                 ==  Parrot_encoding_number_of_str(interp, sc)) {
-                    /* Cache found string */
-                    PMC *item = Parrot_pmc_new_init_int(interp,
-                                    enum_class_FixedIntegerArray, 2);
-                    VTABLE_set_integer_keyed_int(interp, item, 0,
-                            (size_t)sc->encoding ^ (size_t)sc->charset);
-                    VTABLE_set_integer_keyed_int(interp, item, 1,
-                            i);
-                    VTABLE_push_pmc(interp, string_list, item);
                     return i;
                 }
             }


More information about the parrot-commits mailing list