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