cvsuser     01/12/18 12:06:17

  Modified:    .        interpreter.c
  Log:
  Performance improvements to the predereferencing code path
  suggested to me over lunch yesterday by my friend John Kennedy.
  The goal is to remove the additional test in the inner loop
  that was checking for NULL to decide whether or not to call
  the prederef() function. Also moved pc & pc_prederef syncing
  outside the innner loop.
  
    * Changed the prototype of the prederef() function in
      interpreter.c to match that of an opfunc.
  
    * Instead of initializing the prederef void * array with NULL,
      we initialize it with pointers to prederef().
  
    * prederef() now returns the prederef_pc passed in, so that
      after predereferencing, the same location is executed, but now
      with the real code being called.
  
  Thanks to: John Kennedy
  
  Revision  Changes    Path
  1.38      +23 -13    parrot/interpreter.c
  
  Index: interpreter.c
  ===================================================================
  RCS file: /home/perlcvs/parrot/interpreter.c,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -w -r1.37 -r1.38
  --- interpreter.c     13 Dec 2001 21:57:45 -0000      1.37
  +++ interpreter.c     18 Dec 2001 20:06:16 -0000      1.38
  @@ -1,7 +1,7 @@
   /* interpreter.c
    *  Copyright: (When this is determined...it will go here)
    *  CVS Info
  - *     $Id: interpreter.c,v 1.37 2001/12/13 21:57:45 dan Exp $
  + *     $Id: interpreter.c,v 1.38 2001/12/18 20:06:16 gregor Exp $
    *  Overview:
    *     The interpreter api handles running the operations
    *  Data Structure and Algorithms:
  @@ -78,9 +78,11 @@
   /*=for api interpreter prederef
    */
   
  -prederef_op_func_t
  -prederef(opcode_t * pc, void ** pc_prederef, struct Parrot_Interp * interpreter)
  +void **
  +prederef(void ** pc_prederef, struct Parrot_Interp * interpreter)
   {
  +  size_t      offset = pc_prederef - interpreter->prederef_code;
  +  opcode_t *  pc     = ((opcode_t *)interpreter->code->byte_code) + offset;
     op_info_t * opinfo = &core_opinfo_prederef[*pc];
     int         i;
   
  @@ -135,7 +137,7 @@
     }
   
   
  -  return (prederef_op_func_t)pc_prederef[0];
  +  return pc_prederef;
   }
   
   
  @@ -157,7 +159,8 @@
       code_start_prederef = pc_prederef;
   
       while (pc_prederef) {
  -      DO_OP_PREDEREF(pc, pc_prederef, interpreter);
  +      pc_prederef = ((prederef_op_func_t)*pc_prederef)(pc_prederef, interpreter);
  +    }
   
         if (pc_prederef == 0) {
           pc = 0;
  @@ -165,7 +168,6 @@
         else {
           pc = code_start + (pc_prederef - code_start_prederef);
         }
  -    }
   
       if (pc && (pc < code_start || pc >= code_end)) {
           fprintf(stderr, "Error: Control left bounds of byte-code block (now at 
location %d)!\n", (int) (pc - code_start));
  @@ -214,7 +216,15 @@
             size_t offset = pc - (opcode_t *)interpreter->code->byte_code;
   
             if (!interpreter->prederef_code) {
  -            interpreter->prederef_code = (void 
**)calloc(interpreter->code->byte_code_size, sizeof(void *));
  +            size_t N = interpreter->code->byte_code_size;
  +            size_t i;
  +            void ** temp = (void **)malloc(N * sizeof(void *));
  +
  +            for (i = 0; i < N; i++) {
  +              temp[i] = (void *)prederef;
  +            }
  +
  +            interpreter->prederef_code = temp;
             }
   
             runops_prederef(interpreter, pc, interpreter->prederef_code + offset);
  
  
  


Reply via email to