Following a chat on IRC today:

09:28 < nwc10> I see accesses to all structure members except constraints in 
               the rest of the code
09:29 < jnthn> Yeah. It could be moved into Rakudo_md_candidate_graph_node if 
               it's only used in the sort.
09:30 < nwc10> aha. good plan. I'd not thought of doing it like that.

http://irclog.perlgeek.de/perl6/2012-11-15#i_6155821


Is this attached patch the way to go?

Nicholas Clark
>From 46fec0836c0ccfc116cbd1c1ac769c9c87484ebb Mon Sep 17 00:00:00 2001
From: Nicholas Clark <n...@ccl4.org>
Date: Thu, 15 Nov 2012 16:52:33 +0100
Subject: [PATCH] Move constraints from Rakudo_md_candidate_info to
 Rakudo_md_candidate_graph_node as it's only needed while
 generating the sorted candidate list.

---
 src/binder/multidispatch.c | 27 ++++++++++++++++-----------
 src/binder/multidispatch.h |  3 ++-
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/binder/multidispatch.c b/src/binder/multidispatch.c
index 31bba2f..1fbc880 100644
--- a/src/binder/multidispatch.c
+++ b/src/binder/multidispatch.c
@@ -40,7 +40,7 @@ This implements Perl 6 multiple dispatch.
 
 =over 4
 
-=item C<static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_candidate_info *b)>
+=item C<static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, PMC **a_constraints, Rakudo_md_candidate_info *b, PMC **b_constraints)>
 
 Takes two candidates and determines if the first one is narrower than the
 second. Returns a true value if they are.
@@ -48,7 +48,9 @@ second. Returns a true value if they are.
 =cut
 
 */
-static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_candidate_info *b) {
+static INTVAL is_narrower(PARROT_INTERP,
+                          Rakudo_md_candidate_info *a, PMC **a_constraints,
+                          Rakudo_md_candidate_info *b, PMC **b_constraints) {
     INTVAL narrower = 0;
     INTVAL tied = 0;
     INTVAL i, types_to_check;
@@ -71,11 +73,11 @@ static INTVAL is_narrower(PARROT_INTERP, Rakudo_md_candidate_info *a, Rakudo_md_
         if (type_obj_a == type_obj_b) {
             /* Same type; narrower if first has constraints and other doesn't;
              * tied if neither has constraints or both have constraints. */
-            if (!PMC_IS_NULL(a->constraints[i]) && PMC_IS_NULL(b->constraints[i]))
+            if (!PMC_IS_NULL(a_constraints[i]) && PMC_IS_NULL(b_constraints[i]))
                 narrower++;
-            else if ((PMC_IS_NULL(a->constraints[i]) && PMC_IS_NULL(b->constraints[i]))
+            else if ((PMC_IS_NULL(a_constraints[i]) && PMC_IS_NULL(b_constraints[i]))
                  ||
-                    (!PMC_IS_NULL(a->constraints[i]) && !PMC_IS_NULL(b->constraints[i])))
+                    (!PMC_IS_NULL(a_constraints[i]) && !PMC_IS_NULL(b_constraints[i])))
                 tied++;
         }
         else if ((a->type_flags[i] & TYPE_NATIVE_MASK) && !(b->type_flags[i] & TYPE_NATIVE_MASK))
@@ -158,6 +160,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates
         INTVAL                    num_params;
         INTVAL                    j;
         INTVAL                    significant_param;
+        PMC                     **constraints;
 
         /* Get information about this candidate. */
         PMC * const candidate = VTABLE_get_pmc_keyed_int(interp, candidates, i);
@@ -174,7 +177,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates
         /* Type information. */
         info->types         = mem_allocate_n_zeroed_typed(num_params + 1, PMC*);
         info->type_flags    = mem_allocate_n_zeroed_typed(num_params + 1, INTVAL);
-        info->constraints   = mem_allocate_n_zeroed_typed(num_params + 1, PMC*);
+        constraints         = mem_allocate_n_zeroed_typed(num_params + 1, PMC*);
         significant_param = 0;
 
         for (j = 0; j < num_params; j++) {
@@ -220,8 +223,8 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates
             else {
                 info->types[significant_param] = param->nominal_type;
             }
-            info->constraints[significant_param] = param->post_constraints;
-            if (!PMC_IS_NULL(info->constraints[significant_param]))
+            constraints[significant_param] = param->post_constraints;
+            if (!PMC_IS_NULL(constraints[significant_param]))
                 info->bind_check = 1;
             if (param->flags & SIG_ELEM_MULTI_INVOCANT)
                 info->num_types++;
@@ -241,6 +244,7 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates
         /* Add it to graph node, and initialize list of edges. */
         graph[insert_pos]        = mem_allocate_zeroed_typed(Rakudo_md_candidate_graph_node);
         graph[insert_pos]->info  = info;
+        graph[insert_pos]->constraints  = constraints;
         graph[insert_pos]->edges = mem_allocate_n_zeroed_typed(
             num_candidates, Rakudo_md_candidate_graph_node*);
 
@@ -262,7 +266,8 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates
             for (j = 0; j < num_candidates; j++) {
                 if (i == j)
                     continue;
-                if (is_narrower(interp, graph[i]->info, graph[j]->info)) {
+                if (is_narrower(interp, graph[i]->info, graph[i]->constraints,
+                                graph[j]->info, graph[j]->constraints)) {
                     graph[i]->edges[graph[i]->edges_out] = graph[j];
                     graph[i]->edges_out++;
                     graph[j]->edges_in++;
@@ -318,10 +323,10 @@ static Rakudo_md_candidate_info** sort_candidates(PARROT_INTERP, PMC *candidates
                 mem_sys_free(info->types);
             if (info->type_flags)
                 mem_sys_free(info->type_flags);
-            if (info->constraints)
-                mem_sys_free(info->constraints);
             mem_sys_free(info);
         }
+        if (graph[i]->constraints)
+            mem_sys_free(graph[i]->constraints);
         mem_sys_free(graph[i]->edges);
         mem_sys_free(graph[i]);
     }
diff --git a/src/binder/multidispatch.h b/src/binder/multidispatch.h
index 3338f53..e9f6552 100644
--- a/src/binder/multidispatch.h
+++ b/src/binder/multidispatch.h
@@ -37,7 +37,6 @@ typedef struct {
     PMC    *signature;     /* The signature of the sub. */
     PMC   **types;         /* Class or role type constraints for each parameter. */
     INTVAL *type_flags;    /* Definedness and native flags for each of the types. */
-    PMC   **constraints;   /* Refinement type constraints for each parameter. */
     INTVAL  num_types;     /* Number of entries in the above two arrays. */
     INTVAL  min_arity;     /* Number of required positional arguments. */
     INTVAL  max_arity;     /* Number of required and optional positional arguments. */
@@ -86,6 +85,8 @@ typedef struct {
  * in the graph that we have arrows to. */
 typedef struct candidate_graph_node {
     Rakudo_md_candidate_info     *info;
+    /* Refinement type constraints for each parameter, only used in the sort. */
+    PMC                         **constraints;
     struct candidate_graph_node **edges;
     INTVAL                        edges_in;
     INTVAL                        edges_out;
-- 
1.8.0

Reply via email to