Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Make the cache a bit smarter about nameds.

  • Loading branch information...
commit b94f7393992dce91aa36d02cb0f1e7c38c8080ea 1 parent cfd60cb
@jnthn jnthn authored
Showing with 33 additions and 11 deletions.
  1. +26 −11 src/guts/multi_dispatch.c
  2. +7 −0 src/guts/multi_dispatch.h
View
37 src/guts/multi_dispatch.c
@@ -23,9 +23,17 @@ PMC * find_in_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num
INTVAL arg_tup[MD_CACHE_MAX_ARITY];
INTVAL i, j, entries, t_pos;
struct Pcc_cell * pc_positionals;
+ Hash *nameds;
+ char has_nameds;
+
+ /* See if there are any nameds */
+ if (capture->vtable->base_type != enum_class_CallContext)
+ return NULL;
+ GETATTR_CallContext_hash(interp, capture, nameds);
+ has_nameds = nameds && Parrot_hash_size(interp, nameds) ? 1 : 0;
/* If it's zero-arity, return result right off. */
- if (num_args == 0)
+ if (num_args == 0 && !has_nameds)
return cache->zero_arity;
/* If there's more args than the maximum, won't be in the cache. */
@@ -33,10 +41,7 @@ PMC * find_in_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num
return NULL;
/* Create arg tuple. */
- if (capture->vtable->base_type == enum_class_CallContext)
- GETATTR_CallContext_positionals(interp, capture, pc_positionals);
- else
- return NULL;
+ GETATTR_CallContext_positionals(interp, capture, pc_positionals);
for (i = 0; i < num_args; i++) {
if (pc_positionals[i].type == BIND_VAL_OBJ) {
PMC *arg = decontainerize(interp, pc_positionals[i].u.p);
@@ -60,8 +65,11 @@ PMC * find_in_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num
break;
}
}
- if (match)
- return cache->arity_caches[num_args - 1].results[i];
+ if (match) {
+ char match_nameds = cache->arity_caches[num_args - 1].named_ok[i];
+ if (has_nameds == match_nameds)
+ return cache->arity_caches[num_args - 1].results[i];
+ }
t_pos += num_args;
}
@@ -82,6 +90,14 @@ void add_to_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num_a
INTVAL arg_tup[MD_CACHE_MAX_ARITY];
INTVAL i, entries, ins_type;
struct Pcc_cell * pc_positionals;
+ Hash *nameds;
+ char has_nameds;
+
+ /* See if there are any nameds */
+ if (capture->vtable->base_type != enum_class_CallContext)
+ return NULL;
+ GETATTR_CallContext_hash(interp, capture, nameds);
+ has_nameds = nameds && Parrot_hash_size(interp, nameds) ? 1 : 0;
/* Make sure 6model type ID is set. */
if (!smo_id)
@@ -104,10 +120,7 @@ void add_to_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num_a
return;
/* Create arg tuple. */
- if (capture->vtable->base_type == enum_class_CallContext)
- GETATTR_CallContext_positionals(interp, capture, pc_positionals);
- else
- return;
+ GETATTR_CallContext_positionals(interp, capture, pc_positionals);
for (i = 0; i < num_args; i++) {
if (pc_positionals[i].type == BIND_VAL_OBJ) {
PMC *arg = decontainerize(interp, pc_positionals[i].u.p);
@@ -123,6 +136,7 @@ void add_to_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num_a
/* If there's no entries yet, need to do some allocation. */
if (entries == 0) {
cache->arity_caches[num_args - 1].type_ids = mem_sys_allocate(num_args * sizeof(INTVAL) * MD_CACHE_MAX_ENTRIES);
+ cache->arity_caches[num_args - 1].named_ok = mem_sys_allocate(sizeof(char) * MD_CACHE_MAX_ENTRIES);
cache->arity_caches[num_args - 1].results = mem_sys_allocate(sizeof(PMC *) * MD_CACHE_MAX_ENTRIES);
}
@@ -131,5 +145,6 @@ void add_to_cache(PARROT_INTERP, NQP_md_cache *cache, PMC *capture, INTVAL num_a
for (i = 0; i < num_args; i++)
cache->arity_caches[num_args - 1].type_ids[ins_type + i] = arg_tup[i];
cache->arity_caches[num_args - 1].results[entries] = result;
+ cache->arity_caches[num_args - 1].named_ok[entries] = has_nameds;
cache->arity_caches[num_args - 1].num_entries = entries + 1;
}
View
7 src/guts/multi_dispatch.h
@@ -14,6 +14,13 @@ typedef struct {
/* This is a bunch of type IDs. We allocate it arity * MAX_ENTRIES
* big and go through it in arity sized chunks. */
INTVAL *type_ids;
+
+ /* Whether the entry is allowed to have named arguments. Doesn't say
+ * anything about which ones, though. Something that is ambivalent
+ * about named arguments to the degree it doesn't care about them
+ * even tie-breaking (like NQP) can just throw such entries into the
+ * cache. Things that do care should not make such cache entries. */
+ char *named_ok;
/* The results we return from the cache. */
PMC **results;

0 comments on commit b94f739

Please sign in to comment.
Something went wrong with that request. Please try again.