[svn:parrot] r42598 - trunk/src/pmc

chromatic at svn.parrot.org chromatic at svn.parrot.org
Fri Nov 20 08:41:40 UTC 2009


Author: chromatic
Date: Fri Nov 20 08:41:39 2009
New Revision: 42598
URL: https://trac.parrot.org/parrot/changeset/42598

Log:
[oo] Added a naive method cache to Class PMC and used it from Object's
find_method().  This improves NQP-rx's Actions.pm benchmark performance by some
7%.

Modified:
   trunk/src/pmc/class.pmc
   trunk/src/pmc/object.pmc

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc	Fri Nov 20 08:41:35 2009	(r42597)
+++ trunk/src/pmc/class.pmc	Fri Nov 20 08:41:39 2009	(r42598)
@@ -476,6 +476,7 @@
     ATTR PMC *resolve_method;   /* List of method names the class provides to resolve
                                  * conflicts with methods from roles. */
     ATTR PMC *parent_overrides;
+    ATTR PMC *meth_cache;
 
 /*
 
@@ -510,6 +511,7 @@
         _class->attrib_metadata = pmc_new(interp, enum_class_Hash);
         _class->attrib_index    = PMCNULL;
         _class->attrib_cache    = PMCNULL;
+        _class->meth_cache      = PMCNULL;
         _class->resolve_method  = pmc_new(interp, enum_class_ResizablePMCArray);
 
         _class->vtable_overrides = pmc_new(interp, enum_class_Hash);
@@ -610,6 +612,7 @@
         Parrot_gc_mark_PMC_alive(interp, _class->attrib_index);
         Parrot_gc_mark_PMC_alive(interp, _class->attrib_cache);
         Parrot_gc_mark_PMC_alive(interp, _class->resolve_method);
+        Parrot_gc_mark_PMC_alive(interp, _class->meth_cache);
     }
 
 

Modified: trunk/src/pmc/object.pmc
==============================================================================
--- trunk/src/pmc/object.pmc	Fri Nov 20 08:41:35 2009	(r42597)
+++ trunk/src/pmc/object.pmc	Fri Nov 20 08:41:39 2009	(r42598)
@@ -107,6 +107,32 @@
     return -1;
 }
 
+static PMC *
+find_cached(PARROT_INTERP, PMC *_class, STRING *name)
+{
+    PMC *cache;
+    GETATTR_Class_meth_cache(interp, _class, cache);
+
+    if (PMC_IS_NULL(cache))
+        return PMCNULL;
+
+    return VTABLE_get_pmc_keyed_str(interp, cache, name);
+}
+
+static void
+cache_method(PARROT_INTERP, PMC *_class, STRING *name, PMC *method)
+{
+    PMC *cache;
+    GETATTR_Class_meth_cache(interp, _class, cache);
+
+    if (PMC_IS_NULL(cache)) {
+        cache = pmc_new(interp, enum_class_Hash);
+        SETATTR_Class_meth_cache(interp, _class, cache);
+    }
+
+    VTABLE_set_pmc_keyed_str(interp, cache, name, method);
+}
+
 pmclass Object auto_attrs {
     ATTR PMC *_class;       /* The class this is an instance of. */
     ATTR PMC *attrib_store; /* The attributes store - a resizable PMC array. */
@@ -328,51 +354,66 @@
 
 */
     VTABLE PMC *find_method(STRING *name) {
-        Parrot_Object_attributes * const obj         = PARROT_OBJECT(SELF);
-        Parrot_Class_attributes  * const _class      = PARROT_CLASS(obj->_class);
-        STRING                   * const find_method = CONST_STRING(interp, "find_method");
-        PMC           *method        = PMCNULL;
+        Parrot_Object_attributes * const obj    = PARROT_OBJECT(SELF);
+        Parrot_Class_attributes  * const _class = PARROT_CLASS(obj->_class);
+        PMC                             *method = find_cached(interp, obj->_class, name);
 
-        /* Walk and search. One day, we'll use the cache first. */
-        const int num_classes        = VTABLE_elements(interp,
+        if (!PMC_IS_NULL(method))
+            return method;
+        else {
+            STRING * const find_method = CONST_STRING(interp, "find_method");
+            const int      num_classes = VTABLE_elements(interp,
                                                       _class->all_parents);
-        const int all_in_universe    = !CLASS_has_alien_parents_TEST(obj->_class);
-        int i;
-
-        for (i = 0; i < num_classes; i++) {
-            /* Get the class. */
-            PMC * const cur_class =
-                VTABLE_get_pmc_keyed_int(interp, _class->all_parents, i);
 
-            const Parrot_Class_attributes * const class_info = PARROT_CLASS(cur_class);
+            const int all_in_universe  =
+                            !CLASS_has_alien_parents_TEST(obj->_class);
+            int i;
+
+            for (i = 0; i < num_classes; i++) {
+                /* Get the class. */
+                PMC * const cur_class =
+                    VTABLE_get_pmc_keyed_int(interp, _class->all_parents, i);
+
+                const Parrot_Class_attributes * const class_info =
+                        PARROT_CLASS(cur_class);
+
+                /* If there's a vtable override for 'find_method' in the
+                 * current class, run that first. */
+
+                method = Parrot_oo_find_vtable_override_for_class(interp,
+                            cur_class, find_method);
+
+                if (!PMC_IS_NULL(method)) {
+                    PMC *result = PMCNULL;
+                    Parrot_pcc_invoke_sub_from_c_args(interp, method,
+                            "PiS->P", SELF, name, &result);
 
-            /* If there's a vtable override for 'find_method' in the current
-             * class, run that first. */
-            method = Parrot_oo_find_vtable_override_for_class(interp, cur_class,
-                    find_method);
+                    /* break out to the CACHE IF FOUND code */
+                    method = result;
+                    break;
+                }
 
-            if (!PMC_IS_NULL(method)) {
-                PMC *result = PMCNULL;
-                Parrot_pcc_invoke_sub_from_c_args(interp, method,
-                        "PiS->P", SELF, name, &result);
-                return result;
+                /* If it's from this universe or the class doesn't inherit from
+                 * anything outside of it... */
+                if (all_in_universe || VTABLE_isa(interp, cur_class, CONST_STRING(interp, "Class"))) {
+                    method = VTABLE_get_pmc_keyed_str(interp,
+                                    class_info->methods, name);
+
+                    /* Found it! */
+                    if (!PMC_IS_NULL(method))
+                        break;
+                }
+                else
+                    Parrot_ex_throw_from_c_args(INTERP, NULL, -1,
+                        "Class %Ss inherits from alien parents.",
+                        class_info->name);
             }
 
-            /* If it's from this universe or the class doesn't inherit from
-             * anything outside of it... */
-            if (all_in_universe || VTABLE_isa(interp, cur_class, CONST_STRING(interp, "Class"))) {
-                method = VTABLE_get_pmc_keyed_str(interp, class_info->methods, name);
-                /* Found it! */
-                if (!PMC_IS_NULL(method))
-                    break;
-            }
-            else {
-                Parrot_ex_throw_from_c_args(INTERP, NULL, -1,
-                        "Class %Ss inherits from alien parents.", class_info->name);
-            }
-        }
+            if (!PMC_IS_NULL(method))
+                cache_method(interp, obj->_class, name, method);
 
-        return method;
+            return method;
+        }
     }
 
 /*


More information about the parrot-commits mailing list