Branch: Tag:

2014-07-15

2014-07-15 13:09:00 by Per Hedbor <ph@opera.com>

Added F_CALL_BUILTIN_N and F_APPLY_N.

This calls the constant in arg1 with arg2 arguments from the stack.

These opcodes are used if the number of arguments is known and bigger
than 1.

It is not really all that big an optimization, it only removes the
mark stack handling. And, in fact, due to the fact that it removes
some peep optimizations it might be somewhat slower when not using the
amd64 machine code (since, as an example, APPLY/ASSIGN_LOCAL/POP is no
longer an opcode that is used in this case).

However, when using the amd64 code the assign local + pop opcode is
higly optimized, so it's not an issue that it is not merged into the
apply opcode. It is in fact more of a feature.

For that reason the code in docode.c is currently conditional.
The only code generator using it is the amd64 one.

1902:    case F_APPLY:    if(CAR(n)->token == F_CONSTANT)    { +  int args = count_args(CDR(n));    if(TYPEOF(CAR(n)->u.sval) == T_FUNCTION)    {    if(SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) /* driver fun? */
1909:    if(!CAR(n)->u.sval.u.efun->docode ||    !CAR(n)->u.sval.u.efun->docode(n))    { -  if(count_args(CDR(n))==1) +  if(args==1)    {    do_docode(CDR(n),0);    tmp1=store_constant(& CAR(n)->u.sval,    !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),    CAR(n)->name);    emit1(F_CALL_BUILTIN1, DO_NOT_WARN((INT32)tmp1)); -  + #ifdef USE_APPLY_N +  }else if(args>0){ +  do_docode(CDR(n),0); +  tmp1=store_constant(& CAR(n)->u.sval, +  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), +  CAR(n)->name); +  emit2(F_CALL_BUILTIN_N, DO_NOT_WARN((INT32)tmp1), args); + #endif    }else{    emit0(F_MARK);    PUSH_CLEANUP_FRAME(do_pop_mark, 0);
1929:    }    if(n->type == void_type_string)    return 0; -  +     return 1;    }else{    if(CAR(n)->u.sval.u.object == Pike_compiler->fake_object)    return do_lfun_call(SUBTYPEOF(CAR(n)->u.sval), CDR(n));    }    } -  + #ifdef USE_APPLY_N +  if( args <= 1 ) + #endif +  {    emit0(F_MARK);    PUSH_CLEANUP_FRAME(do_pop_mark, 0);    do_docode(CDR(n),0);
1945:    CAR(n)->name);    emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1));    POP_AND_DONT_CLEANUP; -  +  } + #ifdef USE_APPLY_N +  else +  { +  do_docode(CDR(n),0); +  tmp1=store_constant(& CAR(n)->u.sval, +  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), +  CAR(n)->name); +  emit2(F_APPLY_N, DO_NOT_WARN((INT32)tmp1), args); +  } + #endif    return 1;    }    else if(CAR(n)->token == F_IDENTIFIER)