[svn:parrot] r44550 - branches/find_method_object/src/pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Sun Feb 28 14:51:48 UTC 2010


Author: whiteknight
Date: Sun Feb 28 14:51:48 2010
New Revision: 44550
URL: https://trac.parrot.org/parrot/changeset/44550

Log:
first step of the refactor. Move most of the logic from Object.find_method into Class.get_pmc_keyed_str. Include a mechanism for the Class to cache the results.

Modified:
   branches/find_method_object/src/pmc/class.pmc
   branches/find_method_object/src/pmc/object.pmc

Modified: branches/find_method_object/src/pmc/class.pmc
==============================================================================
--- branches/find_method_object/src/pmc/class.pmc	Sun Feb 28 14:13:41 2010	(r44549)
+++ branches/find_method_object/src/pmc/class.pmc	Sun Feb 28 14:51:48 2010	(r44550)
@@ -446,6 +446,18 @@
         interp->vtables[VTABLE_type(interp, SELF)]->mro = _class->all_parents;
 }
 
+static void
+add_method_to_cache(PARROT_INTERP, PMC * self, STRING *name, PMC *meth)
+{
+    Parrot_Class_attributes * const attrs = PARROT_CLASS(self);
+    PMC * cache = attrs->meth_cache;
+    if (PMC_IS_NULL(cache)) {
+        cache = Parrot_pmc_new(interp, enum_class_Hash);
+        attrs->meth_cache = cache;
+    }
+    VTABLE_set_pmc_keyed_str(interp, cache, name, meth);
+}
+
 /*
 
 =back
@@ -476,7 +488,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;
+    ATTR PMC *meth_cache;       /* cache of methods */
 
 /*
 
@@ -1760,27 +1772,61 @@
 
 */
 
-    METHOD find_method(STRING *name) {
+    VTABLE PMC *get_pmc_keyed_str(STRING *name) {
         Parrot_Class_attributes * const  _class    = PARROT_CLASS(SELF);
         int i;
+        PMC * const cache = _class->meth_cache;
 
-        /* Walk and search. One day, we'll use the cache first. */
-        const int num_classes = VTABLE_elements(interp, _class->all_parents);
+        if (!PMC_IS_NULL(cache) && VTABLE_exists_keyed_str(INTERP, cache, name)) {
+            PMC * const method = VTABLE_get_pmc_keyed_str(INTERP, cache, name);
+            if (!PMC_IS_NULL(method))
+                return method;
+        }
+        else {
+            const int all_in_universe = !CLASS_has_alien_parents_TEST(SELF);
+            const int num_classes = VTABLE_elements(interp, _class->all_parents);
+            STRING * const find_method = CONST_STRING(INTERP, "find_method");
+            PMC * method = PMCNULL;
+
+            /* We loop over all classes in the MRO to find the method. First
+               we see if a vtable override has been defined for the class. If
+               so, we call the vtable override. If an override has not been
+               defined, we look the method up in the hash of methods that the
+               Class PMC keeps. */
+            for (i = 0; i < num_classes; i++) {
+                /* Get the class and see if it has the method. */
+                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);
+
+                /* See if there is a vtable override for find_method defined.
+                   if so, call that to see if we have a winner */
+                PMC * const vtable = Parrot_oo_find_vtable_override_for_class(interp,
+                    cur_class, find_method);
+                if (!PMC_IS_NULL(vtable)) {
+                    PMC * result = PMCNULL;
+                    Parrot_pcc_invoke_sub_from_c_args(interp, vtable, "PiS->P", SELF, name, &result);
+                    if (!PMC_IS_NULL(result)) {
+                        method = result;
+                        break;
+                    }
+                }
 
-        for (i = 0; i < num_classes; i++) {
-            /* Get the class and see if it has the method. */
-            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);
-
-            /* Found it! */
-            if (VTABLE_exists_keyed_str(interp, class_info->methods, name)) {
-                PMC * const ret = VTABLE_get_pmc_keyed_str(interp, class_info->methods, name);
-                RETURN(PMC *ret);
+                /* no vtable override in this class, so just look it up in the
+                   hash of method names that the class object contains. */
+                if (VTABLE_exists_keyed_str(interp, class_info->methods, name)) {
+                    method = VTABLE_get_pmc_keyed_str(interp, class_info->methods, name);
+                    break;
+                }
             }
+            if (!PMC_IS_NULL(method))
+                add_method_to_cache(INTERP, SELF, name, method);
+            return method;
         }
+    }
 
-        RETURN(PMC *PMCNULL);
+    METHOD find_method(STRING *name) {
+        PMC * const method = VTABLE_get_pmc_keyed_str(INTERP, SELF, name);
+        RETURN (PMC *method);
     }
 
 /*

Modified: branches/find_method_object/src/pmc/object.pmc
==============================================================================
--- branches/find_method_object/src/pmc/object.pmc	Sun Feb 28 14:13:41 2010	(r44549)
+++ branches/find_method_object/src/pmc/object.pmc	Sun Feb 28 14:51:48 2010	(r44550)
@@ -354,66 +354,9 @@
 
 */
     VTABLE PMC *find_method(STRING *name) {
-        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);
-
-        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);
-
-                /* 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);
-
-                    /* break out to the CACHE IF FOUND code */
-                    method = result;
-                    break;
-                }
-
-                /* 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;
-        }
+        Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
+        PMC * const class = obj->_class;
+        return VTABLE_get_pmc_keyed_str(INTERP, class, name);
     }
 
 /*


More information about the parrot-commits mailing list