Branch: Tag:

2017-11-05

2017-11-05 09:37:48 by Arne Goedeke <el@laramies.com>

Interpreter: remove LOCAL_VAR macro

Ancient versions of gcc could not optimize short-lived local variables
very well and would instead allocate lots of stack space for them. The
interpreter function would then sometimes trigger crashes because the
stack frame got too big. These days making variables short-lived is
benefitial for the generated code. It also makes the code simpler.

84:   #define DONT_BRANCH SKIPJUMP   #endif    - #ifndef LOCAL_VAR - #define LOCAL_VAR(X) X - #endif -  +    #ifndef MACHINE_CODE_FORCE_FP   #define MACHINE_CODE_FORCE_FP() 0   #endif
189:      #undef DO_INDEX   #define DO_INDEX do { \ -  LOCAL_VAR(struct svalue tmp); \ +  struct svalue tmp; \    index_no_free(&tmp,Pike_sp-2,Pike_sp-1); \    pop_2_elems(); \    move_svalue (Pike_sp, &tmp); \
290:   });      OPCODE1(F_LOOKUP_LFUN, "->lfun", 0, { -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct svalue tmp); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct svalue tmp; +  struct program *p;       if ((TYPEOF(Pike_sp[-1]) == T_OBJECT) &&    (p = (o = Pike_sp[-1].u.object)->prog) &&
309:    SET_SVAL(tmp, T_INT, NUMBER_UNDEFINED, integer, 0);    }    } else { -  LOCAL_VAR(struct svalue tmp2); +  struct svalue tmp2;    SET_SVAL(tmp2, PIKE_T_STRING, 1, string, lfun_strings[arg1]);    index_no_free(&tmp, Pike_sp-1, &tmp2);    }
327:   OPCODE2(F_TRAMPOLINE, "trampoline", I_UPDATE_SP, {    struct pike_frame *f=Pike_fp;    DO_IF_DEBUG(INT32 arg2_ = arg2;) -  LOCAL_VAR(struct object *o); +  struct object *o;    o = low_clone(pike_trampoline_program);       while(arg2--) {
409:   OPCODE2(F_ASSIGN_PRIVATE_TYPED_GLOBAL_AND_POP, "assign global <private,typed> and pop", I_UPDATE_SP, {    /* lazy mode. */    union anything *tmp_s; -  LOCAL_VAR(struct object *o); +  struct object *o;    o = Pike_fp->current_object;    if(!o->prog) /* note: generate an error. */    object_low_set_index(o,0,0);
420:      OPCODE2(F_ASSIGN_PRIVATE_TYPED_GLOBAL, "assign global <private,typed>", 0, {    union anything *tmp; -  LOCAL_VAR(struct object *o); +  struct object *o;    o = Pike_fp->current_object;    if(!o->prog) /* note: generate an error. */    object_low_set_index(o,0,0);
437:      OPCODE2(F_PRIVATE_TYPED_GLOBAL, "global <private,typed>", I_UPDATE_SP, {    void *ptr; -  LOCAL_VAR(struct object *o); +  struct object *o;       o = Pike_fp->current_object;    ptr = (void *)(Pike_fp->current_storage + arg1);
475:    *(Pike_mark_sp++)=Pike_sp;       OPCODE2(F_EXTERNAL,"external", I_UPDATE_SP, { -  LOCAL_VAR(struct external_variable_context loc); +  struct external_variable_context loc;       loc.o=Pike_fp->current_object;    loc.parent_identifier=Pike_fp->fun;
503:   });      OPCODE2(F_EXTERNAL_LVALUE, "& external", I_UPDATE_SP, { -  LOCAL_VAR(struct external_variable_context loc); +  struct external_variable_context loc;       loc.o=Pike_fp->current_object;    loc.parent_identifier=Pike_fp->fun;
838:    if( (1 << TYPEOF(Pike_sp[-2])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-4, &tmp);    }
869:    if( (1 << TYPEOF(Pike_sp[-3])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-5, &tmp);    }
891:    if( (1 << TYPEOF(Pike_sp[-1])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-3, &tmp);    }
928:    if( (1 << TYPEOF(Pike_sp[-2])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-4, &tmp);    } else if (TYPEOF(Pike_sp[-2]) == T_OBJECT) {    /* One ref in the lvalue, and one on the stack. */    int i; -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct program *p;    if((o = Pike_sp[-2].u.object)->refs <= 2 &&    (p = o->prog) &&    (i = FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-2])].prog,
992:    if( (1 << TYPEOF(Pike_sp[-2])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-4, &tmp);    } else if (TYPEOF(Pike_sp[-2]) == PIKE_T_OBJECT) {    /* One ref in the lvalue, and one on the stack. */    int i; -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct program *p;    if((o = Pike_sp[-2].u.object)->refs <= 2 &&    (p = o->prog) &&    (i = FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-2])].prog,
1237:   });      OPCODE2(F_ASSIGN_GLOBAL_NUMBER_AND_POP, "assign global number and pop", 0, { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp,PIKE_T_INT,0,integer,arg2);    object_low_set_index(Pike_fp->current_object,    arg1 + Pike_fp->context->identifier_level,
1314:   });      OPCODE2_BRANCH(F_BRANCH_IF_NOT_LOCAL_ARROW, "branch if !local->x", 0, { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_STRING, 1, string,    Pike_fp->context->prog->strings[arg1]);    mark_free_svalue (Pike_sp);
1368:      OPCODE1_BRANCH(F_BRANCH_IF_TYPE_IS_NOT, "branch if type is !=", I_UPDATE_SP, {   /* fprintf(stderr,"******BRANCH IF TYPE IS NOT***** %s\n",get_name_of_type(arg1)); */ -  LOCAL_VAR(struct object *o); +  struct object *o;    if(TYPEOF(Pike_sp[-1]) == T_OBJECT &&    (o = Pike_sp[-1].u.object)->prog)    {
1641:   OPCODE1_JUMP(F_SWITCH_ON_INDEX, "switch on index", I_UPDATE_ALL, {    INT32 tmp;    PIKE_OPCODE_T *addr; -  LOCAL_VAR(struct svalue tmp2); +  struct svalue tmp2;    JUMP_SET_TO_PC_AT_NEXT (addr);    index_no_free(&tmp2, Pike_sp-2, Pike_sp-1);    move_svalue (Pike_sp++, &tmp2);
2001:   });      OPCODE0(F_PUSH_ARRAY, "@", I_UPDATE_SP, { -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct program *p;       switch(TYPEOF(Pike_sp[-1]))    {
2042:    });      OPCODE2(F_LOCAL_LOCAL_INDEX, "local[local]", I_UPDATE_SP, { -  LOCAL_VAR(struct svalue *s); +  struct svalue *s;    s = Pike_fp->locals + arg1;    if(TYPEOF(*s) == PIKE_T_STRING) SET_SVAL_SUBTYPE(*s, 0);    mark_free_svalue (Pike_sp++);
2050:   });      OPCODE1(F_LOCAL_INDEX, "local index", 0, { -  LOCAL_VAR(struct svalue *s); -  LOCAL_VAR(struct svalue tmp); +  struct svalue *s; +  struct svalue tmp;    s = Pike_fp->locals + arg1;    if(TYPEOF(*s) == PIKE_T_STRING) SET_SVAL_SUBTYPE(*s, 0);    index_no_free(&tmp,Pike_sp-1,s);
2060:   });      OPCODE2(F_GLOBAL_LOCAL_INDEX, "global[local]", I_UPDATE_SP, { -  LOCAL_VAR(struct svalue *s); -  LOCAL_VAR(struct svalue tmp); +  struct svalue *s; +  struct svalue tmp;    low_index_current_object_no_free(Pike_sp, arg1);    Pike_sp++;    s=Pike_fp->locals+arg2;
2073:      OPCODE2(F_LOCAL_ARROW, "local->x", I_UPDATE_SP, {    struct pike_frame *fp = Pike_fp; -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_STRING, 1, string,    fp->context->prog->strings[arg1]);    mark_free_svalue (Pike_sp++);
2082:   });      OPCODE1(F_ARROW, "->x", 0, { -  LOCAL_VAR(struct svalue tmp); -  LOCAL_VAR(struct svalue tmp2); +  struct svalue tmp; +  struct svalue tmp2;    SET_SVAL(tmp, PIKE_T_STRING, 1, string,    Pike_fp->context->prog->strings[arg1]);    index_no_free(&tmp2, Pike_sp-1, &tmp);
2093:   });      OPCODE1(F_STRING_INDEX, "string index", 0, { -  LOCAL_VAR(struct svalue tmp); -  LOCAL_VAR(struct svalue tmp2); +  struct svalue tmp; +  struct svalue tmp2;    SET_SVAL(tmp, PIKE_T_STRING, 0, string,    Pike_fp->context->prog->strings[arg1]);    index_no_free(&tmp2, Pike_sp-1, &tmp);
2164:   OPCODE1_ALIAS(F_RANGE, "range", I_UPDATE_SP, o_range2);      OPCODE0(F_COPY_VALUE, "copy_value", 0, { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    copy_svalues_recursively_no_free(&tmp,Pike_sp-1,1,0);    free_svalue(Pike_sp-1);    move_svalue (Pike_sp - 1, &tmp);
2172:   });      OPCODE0(F_INDIRECT, "indirect", I_UPDATE_SP, { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    lvalue_to_svalue_no_free(&tmp, Pike_sp-2);    if(TYPEOF(tmp) != PIKE_T_STRING)    {
2181:    Pike_sp++;    }else{    struct string_assignment_storage *s; -  LOCAL_VAR(struct object *o); +  struct object *o;    o=low_clone(string_assignment_program);    s = (struct string_assignment_storage *)o->storage;    move_svalue (s->lval, Pike_sp - 2);
2218:   #define MKAPPLY(OP,OPCODE,NAME,TYPE, ARG2, ARG3) \   PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT(F_,OPCODE),NAME,I_UPDATE_ALL, \   { \ -  LOCAL_VAR(PIKE_OPCODE_T *addr); \ +  PIKE_OPCODE_T *addr; \    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if((addr=low_mega_apply(TYPE,(INT32)(Pike_sp - *--Pike_mark_sp), \    ARG2, ARG3))) \
2234:   PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT3(F_,OPCODE,_AND_POP),NAME " & pop", \    I_UPDATE_ALL, \   { \ -  LOCAL_VAR(PIKE_OPCODE_T *addr); \ +  PIKE_OPCODE_T *addr; \    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if((addr=low_mega_apply(TYPE, (INT32)(Pike_sp - *--Pike_mark_sp), \    ARG2, ARG3))) \
2251:   PIKE_CONCAT(OP,_RETURN)(PIKE_CONCAT3(F_,OPCODE,_AND_RETURN), \    NAME " & return",I_UPDATE_ALL, \   { \ -  LOCAL_VAR(PIKE_OPCODE_T *addr); \ +  PIKE_OPCODE_T *addr; \    if((addr = low_mega_apply(TYPE, (INT32)(Pike_sp - *--Pike_mark_sp), \    ARG2,ARG3))) \    { \
2272:   PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT(F_MARK_,OPCODE),"mark, " NAME, \    I_UPDATE_ALL, \   { \ -  LOCAL_VAR(PIKE_OPCODE_T *addr); \ +  PIKE_OPCODE_T *addr; \    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if((addr=low_mega_apply(TYPE, 0, ARG2, ARG3))) \    { \
2287:   PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_POP), \    "mark, " NAME " & pop",I_UPDATE_ALL, \   { \ -  LOCAL_VAR(PIKE_OPCODE_T *addr); \ +  PIKE_OPCODE_T *addr; \    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if((addr=low_mega_apply(TYPE, 0, ARG2, ARG3))) \    { \
2303:   PIKE_CONCAT(OP,_RETURN)(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_RETURN), \    "mark, " NAME " & return",I_UPDATE_ALL, \   { \ -  LOCAL_VAR(PIKE_OPCODE_T *pc); \ +  PIKE_OPCODE_T *pc; \    if((pc=low_mega_apply(TYPE, 0, ARG2, ARG3))) \    { \    DO_IF_DEBUG(Pike_fp->next->pc=0); \
2317:         OPCODE1_JUMP(F_CALL_LFUN , "call lfun", I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if((addr = lower_mega_apply((INT32)(Pike_sp - *--Pike_mark_sp),    Pike_fp->current_object,
2333:    });      OPCODE2_JUMP(F_CALL_LFUN_N , "call lfun <n>", I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if((addr = lower_mega_apply(arg2,    Pike_fp->current_object,
2349:    });      OPCODE1_JUMP(F_CALL_LFUN_AND_POP, "call lfun & pop", I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if((addr = lower_mega_apply((INT32)(Pike_sp - *--Pike_mark_sp),    Pike_fp->current_object,
2366:    });      OPCODE1_RETURN(F_CALL_LFUN_AND_RETURN , "call lfun & return", I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    if((addr = lower_mega_apply((INT32)(Pike_sp - *--Pike_mark_sp),    Pike_fp->current_object,    (arg1+Pike_fp->context->identifier_level))))
2380:    });      OPCODE1_JUMP(F_MARK_CALL_LFUN, "mark, call lfun" , I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if((addr = lower_mega_apply(0, Pike_fp->current_object,    (arg1+Pike_fp->context->identifier_level)))) {
2392:    });      OPCODE1_JUMP( F_MARK_CALL_LFUN_AND_POP , "mark, call lfun & pop", I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if((addr = lower_mega_apply(0, Pike_fp->current_object,    (arg1+Pike_fp->context->identifier_level) )))
2408:    });      OPCODE1_RETURN(F_MARK_CALL_LFUN_AND_RETURN , "mark, call lfun & return", I_UPDATE_ALL, { -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  PIKE_OPCODE_T *addr;    if((addr = lower_mega_apply(0, Pike_fp->current_object,    (arg1+Pike_fp->context->identifier_level))))    {
2429:      OPCODE1_JUMP(F_CALL_OTHER,"call other", I_UPDATE_ALL, {    INT32 args=(INT32)(Pike_sp - *--Pike_mark_sp); -  LOCAL_VAR(struct svalue *s); +  struct svalue *s;    s = Pike_sp-args;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if(TYPEOF(*s) == T_OBJECT)    { -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct program *p;    o = s->u.object;    if((p=o->prog))    {
2463:    }       { -  LOCAL_VAR(struct svalue tmp); -  LOCAL_VAR(struct svalue tmp2); -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  struct svalue tmp; +  struct svalue tmp2; +  PIKE_OPCODE_T *addr;    SET_SVAL(tmp, PIKE_T_STRING, 1, string,    Pike_fp->context->prog->strings[arg1]);   
2487:      OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_UPDATE_ALL, {    INT32 args=(INT32)(Pike_sp - *--Pike_mark_sp); -  LOCAL_VAR(struct svalue *s); +  struct svalue *s;    s = Pike_sp-args;    JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if(TYPEOF(*s) == T_OBJECT)    { -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct program *p;    o = s->u.object;    if((p=o->prog))    {
2523:    }       { -  LOCAL_VAR(struct svalue tmp); -  LOCAL_VAR(struct svalue tmp2); -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  struct svalue tmp; +  struct svalue tmp2; +  PIKE_OPCODE_T *addr;       SET_SVAL(tmp, PIKE_T_STRING, 1, string,    Pike_fp->context->prog->strings[arg1]);
2549:      OPCODE1_RETURN(F_CALL_OTHER_AND_RETURN,"call other & return", I_UPDATE_ALL, {    INT32 args=(INT32)(Pike_sp - *--Pike_mark_sp); -  LOCAL_VAR(struct svalue *s); +  struct svalue *s;    s = Pike_sp - args;    if(TYPEOF(*s) == T_OBJECT)    { -  LOCAL_VAR(struct object *o); -  LOCAL_VAR(struct program *p); +  struct object *o; +  struct program *p;    o = s->u.object;    if((p=o->prog))    {
2583:    }       { -  LOCAL_VAR(struct svalue tmp); -  LOCAL_VAR(struct svalue tmp2); -  LOCAL_VAR(PIKE_OPCODE_T *addr); +  struct svalue tmp; +  struct svalue tmp2; +  PIKE_OPCODE_T *addr;    SET_SVAL(tmp, PIKE_T_STRING, 1, string,    Pike_fp->context->prog->strings[arg1]);   
2609:   #define DO_CALL_BUILTIN(ARGS) do { \    int args_=(ARGS); \    struct svalue *expected_stack=Pike_sp-args_; \ -  LOCAL_VAR(struct svalue *s); \ +  struct svalue *s; \    s = &Pike_fp->context->prog->constants[arg1].sval; \    if(Pike_interpreter.trace_level) \    { \
2741:    if( (1 << TYPEOF(Pike_sp[-args])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-args-2, &tmp);    }
2787:    if( (1 << TYPEOF(Pike_sp[-args])) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    { -  LOCAL_VAR(struct svalue tmp); +  struct svalue tmp;    SET_SVAL(tmp, PIKE_T_INT, NUMBER_NUMBER, integer, 0);    assign_lvalue(Pike_sp-args-2, &tmp);    }
2870:   /* Assume that the number of arguments is correct */   OPCODE1_PTRJUMP(F_COND_RECUR, "recur if not overloaded", I_UPDATE_ALL, {    PIKE_OPCODE_T *addr; -  LOCAL_VAR(struct program *p); +  struct program *p;    p = Pike_fp->current_program;    JUMP_SET_TO_PC_AT_NEXT (addr);    Pike_fp->return_addr = (PIKE_OPCODE_T *)(((INT32 *)addr) + 1);
2957:      OPCODE1(F_THIS_OBJECT, "this_object", I_UPDATE_SP, {    int level; -  LOCAL_VAR(struct object *o); +  struct object *o;    o = Pike_fp->current_object;    for (level = 0; level < arg1; level++) { -  LOCAL_VAR(struct program *p); +  struct program *p;    p = o->prog;    if (!p)    Pike_error ("Object %d level(s) up is destructed - cannot get the parent.\n",
3031:   });      OPCODE2(F_THIS, "this", I_UPDATE_SP, { -  LOCAL_VAR(struct external_variable_context loc); +  struct external_variable_context loc;       loc.o = Pike_fp->current_object;    loc.parent_identifier = Pike_fp->fun;