[svn:parrot] r38504 - in trunk: include/parrot lib/Parrot/Pmc2c src
chromatic at svn.parrot.org
chromatic at svn.parrot.org
Wed May 6 07:38:23 UTC 2009
Author: chromatic
Date: Wed May 6 07:38:22 2009
New Revision: 38504
URL: https://trac.parrot.org/parrot/changeset/38504
Log:
[mmd] Changed the MMD variant initialization code in PMCs to use STRINGs
instead of C STRINGs. There's more work to do here, but already this speeds up
Parrot startup by 7% and Rakudo startup by 6.32%.
Modified:
trunk/include/parrot/multidispatch.h
trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
trunk/src/multidispatch.c
Modified: trunk/include/parrot/multidispatch.h
==============================================================================
--- trunk/include/parrot/multidispatch.h Wed May 6 06:21:15 2009 (r38503)
+++ trunk/include/parrot/multidispatch.h Wed May 6 07:38:22 2009 (r38504)
@@ -45,9 +45,9 @@
} MMD_table;
typedef struct _multi_func_list {
- const char *multi_name;
- const char *short_sig;
- const char *full_sig;
+ const STRING *multi_name;
+ const STRING *short_sig;
+ const STRING *full_sig;
funcptr_t func_ptr;
} multi_func_list;
Modified: trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
==============================================================================
--- trunk/lib/Parrot/Pmc2c/PMCEmitter.pm Wed May 6 06:21:15 2009 (r38503)
+++ trunk/lib/Parrot/Pmc2c/PMCEmitter.pm Wed May 6 07:38:22 2009 (r38504)
@@ -472,6 +472,15 @@
return $cout;
}
+sub gen_multi_name
+{
+ my ($name, $cache) = @_;
+
+ return $cache->{$name} if exists $cache->{$name};
+ my $count = keys %$cache;
+ return $cache->{$name} = "mfl_$count";
+}
+
=item C<init_func()>
Returns the C code for the PMC's initialization method, or an empty
@@ -481,19 +490,40 @@
sub init_func {
my ($self) = @_;
- return "" if $self->no_init;
-
- my $cout = "";
- my $classname = $self->name;
+ return '' if $self->no_init;
+ my $cout = '';
+ my $classname = $self->name;
my $enum_name = $self->is_dynamic ? -1 : "enum_class_$classname";
-
my $multi_funcs = $self->find_multi_functions();
- my $multi_list = join( ",\n ",
- map { '{ "'. $_->[0] . '", ' . "\n " .
- '"'. $_->[1] . '", ' . "\n " .
- '"'. $_->[2] . '", ' . "\n " .
- '(funcptr_t) ' . $_->[3] . ' }' } @$multi_funcs );
+
+ my @multi_list;
+ my %strings_seen;
+ my $multi_strings = '';
+ my $cache = {};
+
+ for my $multi (@$multi_funcs) {
+ my ($name, $ssig, $fsig, $func) = @$multi;
+ my ($name_str, $ssig_str, $fsig_str) =
+ map { gen_multi_name($_, $cache) } ($name, $ssig, $fsig);
+
+ for my $s ([$name, $name_str], [$ssig, $ssig_str], [$fsig,$fsig_str]) {
+ my ($raw_string, $name) = @$s;
+ next if $strings_seen{$name}++;
+ $multi_strings .= " STRING *$name = "
+ . qq|CONST_STRING_GEN(interp, "$raw_string");\n|;
+ }
+
+ push @multi_list, <<END_MULTI_LIST;
+ { $name_str,
+ $ssig_str,
+ $fsig_str,
+ (funcptr_t) $func }
+END_MULTI_LIST
+
+ }
+
+ my $multi_list = join( ",\n", @multi_list);
my @isa = grep { $_ ne 'default' } @{ $self->parents };
@@ -550,7 +580,7 @@
my $const = ( $self->{flags}{dynpmc} ) ? " " : " const ";
if ( @$multi_funcs ) {
- $cout .= <<"EOC";
+ $cout .= $multi_strings . <<"EOC";
$const multi_func_list _temp_multi_func_list[] = {
$multi_list
Modified: trunk/src/multidispatch.c
==============================================================================
--- trunk/src/multidispatch.c Wed May 6 06:21:15 2009 (r38503)
+++ trunk/src/multidispatch.c Wed May 6 07:38:22 2009 (r38504)
@@ -1332,14 +1332,31 @@
ASSERT_ARGS(Parrot_mmd_add_multi_list_from_c_args)
INTVAL i;
for (i = 0; i < elements; ++i) {
+ funcptr_t func_ptr = mmd_info[i].func_ptr;
+
+ STRING *sub_name = mmd_info[i].multi_name;
+ STRING *long_sig = mmd_info[i].full_sig;
+ STRING *short_sig = mmd_info[i].short_sig;
+ PMC *type_list = Parrot_str_split(interp, CONST_STRING(interp, ","), long_sig);
+ STRING *ns_name = VTABLE_get_string_keyed_int(interp, type_list, 0);
+
+ /* Create an NCI sub for the C function */
+ PMC *sub_obj = constant_pmc_new(interp, enum_class_NCI);
+ PMC *multi_sig = mmd_build_type_tuple_from_long_sig(interp,
+ long_sig);
+
#ifdef PARROT_HAS_ALIGNED_FUNCPTR
- PARROT_ASSERT((PTR2UINTVAL(mmd_info[i].func_ptr) & 3) == 0);
+ PARROT_ASSERT((PTR2UINTVAL(func_ptr) & 3) == 0);
#endif
- Parrot_mmd_add_multi_from_c_args(interp,
- mmd_info[i].multi_name,
- mmd_info[i].short_sig,
- mmd_info[i].full_sig,
- mmd_info[i].func_ptr);
+
+ VTABLE_set_pointer_keyed_str(interp, sub_obj, short_sig,
+ F2DPTR(func_ptr));
+
+ /* Attach a type tuple array to the NCI sub for multi dispatch */
+ SETATTR_NCI_multi_sig(interp, sub_obj, multi_sig);
+
+ mmd_add_multi_to_namespace(interp, ns_name, sub_name, sub_obj);
+ mmd_add_multi_global(interp, sub_name, sub_obj);
}
}
More information about the parrot-commits
mailing list