[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