[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