# New Ticket Created by  Jason Gloudon 
# Please include the string:  [perl #18520]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=18520 >



This patch just adds a new control flow flag to op.h and extracts the
additional information from op definitions needed to identify ops that cause
interpreter retarts. I've changed the output to the opcode C file so that it
uses the enum values in OpsFile.pm instead of hard coding their integer values.

The current approach to handling restart in the JIT checks for restart after
calling every external op function that can adjust the flow of control. The
normal flow control ops cannot cause a restart, so those checks are mostly
unnecessary.

With the additional information the unnecessary checks can be removed for ops
that cannot cause restarts.

-- 
Jason


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/41946/33752/bd86c6/restartflow.patch

? mops.pbc
Index: ops2c.pl
===================================================================
RCS file: /cvs/public/parrot/ops2c.pl,v
retrieving revision 1.33
diff -u -r1.33 ops2c.pl
--- ops2c.pl    18 Oct 2002 08:51:32 -0000      1.33
+++ ops2c.pl    19 Nov 2002 20:31:50 -0000
@@ -272,7 +272,7 @@
     "$full_name",
     "$func_name",
     "", /* TODO: Put the body here */
-    $jump, /* 1 = rel 2 = abs 4 = pop 8 = enext 16 = gnext 32 = unpredict */
+    $jump,
     $arg_count,
     $arg_types,
     $arg_dirs
Index: include/parrot/op.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/op.h,v
retrieving revision 1.18
diff -u -r1.18 op.h
--- include/parrot/op.h 19 Aug 2002 23:15:52 -0000      1.18
+++ include/parrot/op.h 19 Nov 2002 20:31:51 -0000
@@ -48,13 +48,15 @@
     PARROT_ARGDIR_INOUT
 } arg_dir_t;
 
+/* See lib/Parrot/OpsFile.pm if the names of these values change */
 typedef enum {
     PARROT_JUMP_RELATIVE = 1,
     PARROT_JUMP_ADDRESS = 2,
     PARROT_JUMP_POP = 4,
     PARROT_JUMP_ENEXT = 8,
     PARROT_JUMP_GNEXT = 16,
-    PARROT_JUMP_UNPREDICTABLE = 32
+    PARROT_JUMP_UNPREDICTABLE = 32,
+    PARROT_JUMP_RESTART = 64
 } op_jump_t;
 
 /* NOTE: Sure wish we could put the types here... */
Index: lib/Parrot/OpsFile.pm
===================================================================
RCS file: /cvs/public/parrot/lib/Parrot/OpsFile.pm,v
retrieving revision 1.27
diff -u -r1.27 OpsFile.pm
--- lib/Parrot/OpsFile.pm       12 Nov 2002 09:54:38 -0000      1.27
+++ lib/Parrot/OpsFile.pm       19 Nov 2002 20:31:53 -0000
@@ -251,6 +251,19 @@
   return;
 }
 
+# Extends a string containing an or expression "0" .. "A" .. "A|B" etc.
+sub or_flag
+{
+    my ($flag, $value) = @_;
+
+    if($$flag eq '0'){
+       $$flag = $value;
+    }
+    else {
+       $$flag .= "|$value";
+    }
+}
+
 
 #
 # make_op()
@@ -265,13 +278,14 @@
   my $branch = 0;
   my $pop = 0;
   my $next = 0;
-  my $jumps = 0;
+  my $restart = 0;
 
   foreach my $variant (expand_args(@$args)) {
       my(@fixedargs)=split(/,/,$variant);
       my $op = Parrot::Op->new($code++, $type, $short_name,
         [ 'op', @fixedargs ], [ '', @$argdirs ]);
       my $op_size = $op->size;
+      my $jumps = "0";
 
       #
       # Macro substitutions:
@@ -325,8 +339,14 @@
 
                     $body =~ s/\bHALT\(\)/{{=0}}/mg;
 
-      $branch   ||= $body =~ s/\brestart\s+OFFSET\((.*?)\)/{{=0,+=$1}}/mg;
-      $next     ||= $body =~ s/\brestart\s+NEXT\(\)/{{=0,+=$op_size}}/mg;
+      if($body =~ s/\brestart\s+OFFSET\((.*?)\)/{{=0,+=$1}}/mg) {
+       $branch = 1;
+       $restart = 1;
+      }
+      elsif($body =~ s/\brestart\s+NEXT\(\)/{{=0,+=$op_size}}/mg) {
+       $restart = 1;
+       $next = 1;
+      }
 
                     $body =~ s/\$(\d+)/{{\@$1}}/mg;
 
@@ -336,12 +356,15 @@
         $op->body(qq{#line $line "$file"\n}.$body);
       }
 
-      $jumps |= 1 if ($branch);
-      $jumps |= 2 if ($absolute);
-      $jumps |= 4 if ($pop);
-      $jumps |= 8 if ($next);
+      # Constants here are defined in include/parrot/op.h
+      or_flag(\$jumps, "PARROT_JUMP_RELATIVE")   if ($branch);
+      or_flag(\$jumps, "PARROT_JUMP_ADDRESS")    if ($absolute);
+      or_flag(\$jumps, "PARROT_JUMP_POP")        if ($pop);
+      or_flag(\$jumps, "PARROT_JUMP_ENEXT")      if ($next);
       # I'm assuming the op branches to the value in the last argument.
-      $jumps |= 16 if (($jumps) && ($fixedargs[@fixedargs - 1]) && 
($fixedargs[@fixedargs - 1] eq 'i'));
+      or_flag(\$jumps, "PARROT_JUMP_GNEXT")      if (($jumps) && 
+($fixedargs[@fixedargs - 1]) && ($fixedargs[@fixedargs - 1] eq 'i'));
+      or_flag(\$jumps, "PARROT_JUMP_RESTART")     if ($restart);
+
       $op->jump($jumps);
 
       $self->push_op($op);

Reply via email to