cvsuser     03/10/15 11:00:30

  Modified:    .        core.ops interpreter.c ops2c.pl
               include/parrot interpreter.h oplib.h
               lib/Parrot OpTrans.pm
               lib/Parrot/OpTrans C.pm CGP.pm CGoto.pm CPrederef.pm
                        CSwitch.pm
  Log:
  Rework prederef code
  
  Till now only the original (function based) prederef core did
  predereference on demand (or JIT). Now all prederef cores (switch,
  CGP too) work likes this.
  
  All opcodes are first redirected to the new prederef__ opcode,
  which calls the prederef function (now called do_prederef). As now
  predereferencing is done from inside the run loop, this works for cores
  that don't have any oplib function/address table too.
  
  This avoids one additional run over all bytecode and prepares prederefed
  cores for dynamic oplib loading.
  
  Revision  Changes    Path
  1.331     +13 -0     parrot/core.ops
  
  Index: core.ops
  ===================================================================
  RCS file: /cvs/public/parrot/core.ops,v
  retrieving revision 1.330
  retrieving revision 1.331
  diff -u -w -r1.330 -r1.331
  --- core.ops  15 Oct 2003 08:31:20 -0000      1.330
  +++ core.ops  15 Oct 2003 18:00:16 -0000      1.331
  @@ -6,6 +6,8 @@
   #include "parrot/embed.h"
   #include "parrot/interp_guts.h"
   
  +static op_lib_t op_lib;
  +
   VERSION = PARROT_VERSION;
   
   =head1 NAME
  @@ -81,6 +83,12 @@
   Don't use.
   (Must be op #5).
   
  +=item B<prederef__>()
  +
  +Internal opcode to prederef opcodes on the fly.
  +Don't use.
  +(Must be op #6).
  +
   =item B<load_bytecode>(in STR)
   
   Load Parrot bytecode from file $1, and (TODO) search the library path,
  @@ -117,6 +125,11 @@
       opcode_t *pc = CUR_OPCODE;
       DO_OP(pc, interpreter);
       goto ADDRESS(pc);
  +}
  +
  +inline op prederef__() {
  +    do_prederef((void**)cur_opcode, interpreter, op_lib.core_type);
  +    goto OFFSET(0);
   }
   
   inline op reserved(in INT) {
  
  
  
  1.216     +46 -69    parrot/interpreter.c
  
  Index: interpreter.c
  ===================================================================
  RCS file: /cvs/public/parrot/interpreter.c,v
  retrieving revision 1.215
  retrieving revision 1.216
  diff -u -w -r1.215 -r1.216
  --- interpreter.c     15 Oct 2003 09:10:23 -0000      1.215
  +++ interpreter.c     15 Oct 2003 18:00:16 -0000      1.216
  @@ -1,7 +1,7 @@
   /* interpreter.c
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: interpreter.c,v 1.215 2003/10/15 09:10:23 leo Exp $
  + *     $Id: interpreter.c,v 1.216 2003/10/15 18:00:16 leo Exp $
    *  Overview:
    *     The interpreter api handles running the operations
    *  Data Structure and Algorithms:
  @@ -37,12 +37,14 @@
   
   /*=for api interpreter prederef
    *
  - * Predereference the current opcode. Note that this function has the
  - * same signature as a prederef opfunc. This is important because the
  - * prederef code chunk is pre-initialized with pointers to this
  - * function, so that as ops that have not yet been predereferenced are
  - * encountered, execution is automatically vectored here so the
  - * predereferencing can be performed. Since this function returns the
  + * Predereference the current opcode.
  + *
  + * The prederef code chunk is pre-initialized with opcode function
  + * pointers (or addresses or opnumbers) of the prederef__ opcode.
  + * This opcode call the do_prederef function, which fills in the
  + * real function (address/op number)
  + *
  + * Since the prederef__ opcode returns the
    * same pc_prederef it was passed, the runops loop will re-execute
    * the same location, which will then have the pointer to the real
    * prederef opfunc and prederef args.
  @@ -53,27 +55,19 @@
    * since there is a one-to-one mapping.
    */
   
  -static void **
  -prederef(void **pc_prederef, struct Parrot_Interp *interpreter)
  +static void
  +prederef_args(void **pc_prederef, struct Parrot_Interp *interpreter,
  +        opcode_t *pc)
   {
  -    size_t offset = pc_prederef - interpreter->prederef_code;
  -    opcode_t *pc = ((opcode_t *)interpreter->code->byte_code) + offset;
       op_info_t *opinfo;
  -    op_func_t *prederef_op_func = interpreter->op_lib->op_func_table;
       struct PackFile_ConstTable * const_table = interpreter->code->const_table;
       int i;
   
  -    if (*pc < 0 || *pc >= (opcode_t)interpreter->op_count)
  -        internal_exception(INTERP_ERROR, "Illegal opcode");
       opinfo = &interpreter->op_info_table[*pc];
  -    for (i = 0; i < opinfo->arg_count; i++) {
  +    for (i = 1; i < opinfo->arg_count; i++) {
           opcode_t arg = pc[i];
   
           switch (opinfo->types[i]) {
  -        case PARROT_ARG_OP:
  -            if (prederef_op_func)
  -                pc_prederef[i] = (void *)(ptrcast_t)prederef_op_func[arg];
  -            break;
   
           case PARROT_ARG_KI:
           case PARROT_ARG_I:
  @@ -141,7 +135,6 @@
           }
   
           if (pc_prederef[i] == 0) {
  -            if (prederef_op_func || i) {
                   /* switched core has no func_table, so a NULL op is ok */
                   internal_exception(INTERP_ERROR,
                       "Prederef generated a NULL pointer for arg of type %d!\n",
  @@ -150,52 +143,34 @@
           }
       }
   
  -    return pc_prederef;
  -}
  -
   /*
  - * non plain prederf cores immediately do the dereferencing
  - * the opcode is replaced depending on the run core
  + * this is called from inside the run cores
    */
  -static void
  -fill_prederef(struct Parrot_Interp *interpreter, int which,
  -        size_t N, void **temp)
  +void
  +do_prederef(void **pc_prederef, Parrot_Interp interpreter, int type)
   {
  -    size_t i;
  -    opcode_t *pc = interpreter->code->cur_cs->base.data;
  +    size_t offset = pc_prederef - interpreter->prederef_code;
  +    opcode_t *pc = ((opcode_t *)interpreter->code->byte_code) + offset;
       op_func_t *prederef_op_func = interpreter->op_lib->op_func_table;
  -    size_t n;
  -    int is_ret;
   
  -    for (i = 0; i < N; ) {
  -        is_ret = 0;
  -        switch (which) {
  -            case PARROT_EXEC_CORE:
  -                if (*temp)
  -                    is_ret = 1;
  -                break;
  -        }
  -        prederef(temp, interpreter);
  -        switch (which) {
  +    if (*pc < 0 || *pc >= (opcode_t)interpreter->op_count)
  +        internal_exception(INTERP_ERROR, "Illegal opcode");
  +    switch (type) {
               case PARROT_SWITCH_CORE:
  -                *temp = (void**) *pc;
  +            *pc_prederef = (void**) *pc;
                   break;
  +        case PARROT_PREDEREF_CORE:
               case PARROT_CGP_CORE:
  -                *temp = ((void**)(prederef_op_func)) [*pc];
  +            *pc_prederef = ((void**)(prederef_op_func)) [*pc];
                   break;
  -            case PARROT_EXEC_CORE:
  -                if (is_ret)
  -                    *temp = (void *)(ptrcast_t)prederef_op_func[2];
  -                else
  -                    *temp = (void *)(ptrcast_t)prederef_op_func[*pc];
  +        default:
  +            internal_exception(1, "Tried to prederef wrong core");
                   break;
           }
  -        n = interpreter->op_info_table[*pc].arg_count;
  -        pc += n;
  -        i += n;
  -        temp += n;
  -    }
  +    /* and arguments */
  +    prederef_args(pc_prederef, interpreter, pc);
   }
  +
   /*=for api interpreter get_op_lib_init
    *
    * return an  opcode's library op_lib init func
  @@ -245,8 +220,8 @@
       int (*get_op)(const char * name, int full);
   
       get_op = interpreter->op_lib->op_code;
  -    /* preserve the loop fun */
       interpreter->op_lib = init_func(1);
  +    /* preserve the get_op function */
       interpreter->op_lib->op_code = get_op;
       if (interpreter->op_lib->op_count != interpreter->op_count)
           internal_exception(PREDEREF_LOAD_ERROR,
  @@ -266,6 +241,7 @@
       if (!interpreter->prederef_code) {
           size_t N = interpreter->code->cur_cs->base.size;
           size_t i;
  +        void *pred_func;
   /* Parrot_memalign_if_possible in OpenBSD allocates 256 if you ask for 312 */
   #if 1
           void **temp = (void **)mem_sys_allocate_zeroed(N * sizeof(void *));
  @@ -274,17 +250,18 @@
                   N * sizeof(void *));
   #endif
   
  -        if (which == PARROT_PREDEREF_CORE) {
  +        /* fill with the prederef__ opcode function */
  +        if (which == PARROT_SWITCH_CORE)
  +            pred_func = (void*) 6;
  +        else
  +            pred_func = ((void **) interpreter->op_lib->op_func_table)[6];
               for (i = 0; i < N; i++) {
  -                temp[i] = (void *)(ptrcast_t)prederef;
  -            }
  +            temp[i] = pred_func;
           }
   
           interpreter->prederef_code = temp;
           interpreter->code->cur_cs->prederef_code = temp;
   
  -        if (which != PARROT_PREDEREF_CORE)
  -            fill_prederef(interpreter, which, N, temp);
       }
   }
   
  @@ -322,7 +299,7 @@
   
           interpreter->prederef_code = temp;
           interpreter->code->cur_cs->prederef_code = temp;
  -        fill_prederef(interpreter, PARROT_EXEC_CORE, N, temp);
  +        /* TODO */
       }
   }
   #endif
  
  
  
  1.53      +12 -9     parrot/ops2c.pl
  
  Index: ops2c.pl
  ===================================================================
  RCS file: /cvs/public/parrot/ops2c.pl,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -w -r1.52 -r1.53
  --- ops2c.pl  14 Oct 2003 15:47:07 -0000      1.52
  +++ ops2c.pl  15 Oct 2003 18:00:16 -0000      1.53
  @@ -5,7 +5,7 @@
   # Generate a C header and source file from the operation definitions in
   # an .ops file, using a supplied transform.
   #
  -# $Id: ops2c.pl,v 1.52 2003/10/14 15:47:07 leo Exp $
  +# $Id: ops2c.pl,v 1.53 2003/10/15 18:00:16 leo Exp $
   #
   
   use strict;
  @@ -42,6 +42,7 @@
   my $suffix  = $trans->suffix;
   my $defines = $trans->defines;
   my $opsarraytype = $trans->opsarraytype;
  +my $core_type = $trans->core_type;
   
   my $file = shift @ARGV;
   
  @@ -577,14 +578,16 @@
   */
   
   static op_lib_t op_lib = {
  -  "$base",
  -  $major_version,
  -  $minor_version,
  -  $patch_version,
  -  $num_ops,
  -  $op_info,
  -  $op_func,
  -  $getop
  +  "$base",           /* name */
  +  $core_type,                /* core_type = PARROT_XX_CORE */
  +  0,                 /* flags */
  +  $major_version,    /* major_version */
  +  $minor_version,    /* minor_version */
  +  $patch_version,    /* patch_version */
  +  $num_ops,          /* op_count */
  +  $op_info,          /* op_info_table */
  +  $op_func,          /* op_func_table */
  +  $getop             /* op_code() */
   };
   
   op_lib_t *
  
  
  
  1.94      +3 -1      parrot/include/parrot/interpreter.h
  
  Index: interpreter.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v
  retrieving revision 1.93
  retrieving revision 1.94
  diff -u -w -r1.93 -r1.94
  --- interpreter.h     15 Oct 2003 08:31:23 -0000      1.93
  +++ interpreter.h     15 Oct 2003 18:00:19 -0000      1.94
  @@ -1,7 +1,7 @@
   /* interpreter.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: interpreter.h,v 1.93 2003/10/15 08:31:23 leo Exp $
  + *     $Id: interpreter.h,v 1.94 2003/10/15 18:00:19 leo Exp $
    *  Overview:
    *     The interpreter api handles running the operations
    *  Data Structure and Algorithms:
  @@ -33,6 +33,7 @@
   /* &gen_from_enum(interpcores.pasm) */
   typedef enum {
       PARROT_SLOW_CORE,           /* slow bounds/trace/profile core */
  +    PARROT_FUNCTION_CORE = PARROT_SLOW_CORE,
       PARROT_FAST_CORE,           /* fast DO_OP core */
       PARROT_PREDEREF_CORE,       /*  P   = prederefed */
       PARROT_SWITCH_CORE,         /*  P                */
  @@ -274,6 +275,7 @@
   void prepare_for_run(Parrot_Interp interpreter);
   void *init_jit(Parrot_Interp interpreter, opcode_t *pc);
   void dynop_register(Parrot_Interp interpreter, PMC* op_lib);
  +void do_prederef(void **pc_prederef, Parrot_Interp interpreter, int type);
   
   #else
   
  
  
  
  1.10      +6 -4      parrot/include/parrot/oplib.h
  
  Index: oplib.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/oplib.h,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -w -r1.9 -r1.10
  --- oplib.h   21 Jul 2003 18:00:42 -0000      1.9
  +++ oplib.h   15 Oct 2003 18:00:19 -0000      1.10
  @@ -1,7 +1,7 @@
   /* oplib.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: oplib.h,v 1.9 2003/07/21 18:00:42 chromatic Exp $
  + *     $Id: oplib.h,v 1.10 2003/10/15 18:00:19 leo Exp $
    *  Overview:
    *     Header file for op libraries.
    *  Data Structure and Algorithms:
  @@ -23,9 +23,11 @@
   
   typedef struct {
       const char *name;
  -    INTVAL      major_version;
  -    INTVAL      minor_version;
  -    INTVAL      patch_version;
  +    int      core_type;
  +    int      flags;
  +    int      major_version;
  +    int      minor_version;
  +    int      patch_version;
       size_t      op_count;
       op_info_t * op_info_table;
       void *      op_func_table;
  
  
  
  1.5       +5 -1      parrot/lib/Parrot/OpTrans.pm
  
  Index: OpTrans.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/OpTrans.pm,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -w -r1.4 -r1.5
  --- OpTrans.pm        15 Jan 2002 16:10:39 -0000      1.4
  +++ OpTrans.pm        15 Oct 2003 18:00:24 -0000      1.5
  @@ -1,7 +1,7 @@
   #
   # OpTrans.pm
   #
  -# $Id: OpTrans.pm,v 1.4 2002/01/15 16:10:39 dan Exp $
  +# $Id: OpTrans.pm,v 1.5 2003/10/15 18:00:24 leo Exp $
   #
   
   use strict;
  @@ -17,6 +17,10 @@
   sub opsarraytype { return 'opcode_t' };
   
   # Default implementation of the goto_X methods is gen_goto(expr_X())
  +#
  +sub core_type {
  +    die "OpTrans::XX doesn't have core_type";
  +}
   
   sub gen_goto {
       my ($self, $where_str) = @_;
  
  
  
  1.18      +4 -1      parrot/lib/Parrot/OpTrans/C.pm
  
  Index: C.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/OpTrans/C.pm,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -w -r1.17 -r1.18
  --- C.pm      14 Jun 2003 17:48:59 -0000      1.17
  +++ C.pm      15 Oct 2003 18:00:30 -0000      1.18
  @@ -1,7 +1,7 @@
   #
   # C.pm
   #
  -# $Id: C.pm,v 1.17 2003/06/14 17:48:59 dan Exp $
  +# $Id: C.pm,v 1.18 2003/10/15 18:00:30 leo Exp $
   #
   
   use strict;
  @@ -13,6 +13,9 @@
   use vars qw(@ISA %arg_maps);
   @ISA = qw(Parrot::OpTrans);
   
  +sub core_type {
  +    return 'PARROT_FUNCTION_CORE';
  +}
   
   #
   # defines()
  
  
  
  1.5       +5 -1      parrot/lib/Parrot/OpTrans/CGP.pm
  
  Index: CGP.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/OpTrans/CGP.pm,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -w -r1.4 -r1.5
  --- CGP.pm    9 Feb 2003 16:55:48 -0000       1.4
  +++ CGP.pm    15 Oct 2003 18:00:30 -0000      1.5
  @@ -6,7 +6,7 @@
   #
   # Author: leo
   #
  -# $Id: CGP.pm,v 1.4 2003/02/09 16:55:48 leo Exp $
  +# $Id: CGP.pm,v 1.5 2003/10/15 18:00:30 leo Exp $
   #
   
   use strict;
  @@ -19,6 +19,10 @@
   use vars qw(@ISA);
   @ISA = qw(Parrot::OpTrans::CPrederef);
   
  +
  +sub core_type {
  +    return 'PARROT_CGP_CORE';
  +}
   
   #
   # suffix()
  
  
  
  1.21      +5 -1      parrot/lib/Parrot/OpTrans/CGoto.pm
  
  Index: CGoto.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/OpTrans/CGoto.pm,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -w -r1.20 -r1.21
  --- CGoto.pm  14 Jun 2003 17:48:59 -0000      1.20
  +++ CGoto.pm  15 Oct 2003 18:00:30 -0000      1.21
  @@ -1,7 +1,7 @@
   #
   # CGoto.pm
   #
  -# $Id: CGoto.pm,v 1.20 2003/06/14 17:48:59 dan Exp $
  +# $Id: CGoto.pm,v 1.21 2003/10/15 18:00:30 leo Exp $
   #
   
   use strict;
  @@ -14,6 +14,10 @@
   @ISA = qw(Parrot::OpTrans);
   
   sub suffix { return "_cg"; }
  +
  +sub core_type {
  +    return 'PARROT_CGOTO_CORE';
  +}
   
   sub defines
   {
  
  
  
  1.19      +4 -0      parrot/lib/Parrot/OpTrans/CPrederef.pm
  
  Index: CPrederef.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/OpTrans/CPrederef.pm,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -w -r1.18 -r1.19
  --- CPrederef.pm      19 Aug 2002 23:16:54 -0000      1.18
  +++ CPrederef.pm      15 Oct 2003 18:00:30 -0000      1.19
  @@ -14,6 +14,10 @@
   use Parrot::OpTrans::C;
   @ISA = qw(Parrot::OpTrans::C);
   
  +sub core_type {
  +    return 'PARROT_PREDEREF_CORE';
  +}
  +
   
   #
   # defines()
  
  
  
  1.2       +5 -1      parrot/lib/Parrot/OpTrans/CSwitch.pm
  
  Index: CSwitch.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/OpTrans/CSwitch.pm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- CSwitch.pm        18 May 2003 10:03:21 -0000      1.1
  +++ CSwitch.pm        15 Oct 2003 18:00:30 -0000      1.2
  @@ -6,7 +6,7 @@
   #
   # Author: leo
   #
  -# $Id: CSwitch.pm,v 1.1 2003/05/18 10:03:21 leo Exp $
  +# $Id: CSwitch.pm,v 1.2 2003/10/15 18:00:30 leo Exp $
   #
   
   use strict;
  @@ -18,6 +18,10 @@
   use Parrot::OpTrans::CPrederef;
   use vars qw(@ISA);
   @ISA = qw(Parrot::OpTrans::CPrederef);
  +
  +sub core_type {
  +    return 'PARROT_SWITCH_CORE';
  +}
   
   
   #
  
  
  

Reply via email to