[svn:parrot] r46393 - in trunk: include/parrot src

bacek at svn.parrot.org bacek at svn.parrot.org
Fri May 7 16:15:26 UTC 2010


Author: bacek
Date: Fri May  7 16:15:25 2010
New Revision: 46393
URL: https://trac.parrot.org/parrot/changeset/46393

Log:
Cache strings lookup in PackFile_ConstTable_rlookup. It's bring compilation time of perl6.pbc from 5.30 minutes to 40 seconds

Modified:
   trunk/include/parrot/packfile.h
   trunk/src/packout.c

Modified: trunk/include/parrot/packfile.h
==============================================================================
--- trunk/include/parrot/packfile.h	Fri May  7 15:36:21 2010	(r46392)
+++ trunk/include/parrot/packfile.h	Fri May  7 16:15:25 2010	(r46393)
@@ -251,6 +251,8 @@
     opcode_t                   const_count;
     PackFile_Constant        **constants;
     PackFile_ByteCode         *code;  /* where this segment belongs to */
+
+    PMC                       *string_hash; /* Hash for lookup strings and numbers */
 } PackFile_ConstTable;
 
 struct PackFile_ByteCode {

Modified: trunk/src/packout.c
==============================================================================
--- trunk/src/packout.c	Fri May  7 15:36:21 2010	(r46392)
+++ trunk/src/packout.c	Fri May  7 16:15:25 2010	(r46393)
@@ -250,15 +250,56 @@
     ARGIN(const PackFile_ConstTable *ct), ARGIN(PMC *key), int type)
 {
     ASSERT_ARGS(PackFile_ConstTable_rlookup)
-    int      i;
+    int      i, strings;
     FLOATVAL key_num;
     STRING  *key_str;
+    PMC     *string_list;
 
     PARROT_ASSERT(type == PFC_STRING || type == PFC_NUMBER);
 
     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);
+        }
+
+        /* 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);
+        }
+    }
+
     for (i = 0; i < ct->const_count; ++i) {
         PackFile_Constant *constant = ct->constants[i];
 
@@ -270,8 +311,17 @@
                 &&  Parrot_charset_number_of_str(interp, key_str)
                 ==  Parrot_charset_number_of_str(interp, sc)
                 &&  Parrot_encoding_number_of_str(interp, key_str)
-                ==  Parrot_encoding_number_of_str(interp, sc))
+                ==  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;
+                }
             }
             break;
 


More information about the parrot-commits mailing list