From f8222682d94e30c39d86fc6a510b1139d74feb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Mon, 16 Jul 2001 12:48:59 -0700 Subject: [PATCH] first incarnation of --with-machine-code it only work on x86 with gcc so far, and that doesn't even work either... Rev: bin/make_interpret_functions.pike:1.1 Rev: src/Makefile.in:1.268 Rev: src/acconfig.h:1.92 Rev: src/configure.in:1.538 Rev: src/interpret.c:1.220 Rev: src/interpret_functions.h:1.76 Rev: src/interpreter.h:1.70 Rev: src/las.c:1.257 Rev: src/lex.c:1.98 Rev: src/lex.h:1.19 Rev: src/peep.c:1.54 Rev: src/program.c:1.354 Rev: src/program.h:1.139 --- bin/make_interpret_functions.pike | 140 ++++++++++++++++++++ src/Makefile.in | 6 +- src/acconfig.h | 5 +- src/configure.in | 7 +- src/interpret.c | 104 ++++++++++++++- src/interpret_functions.h | 207 +++++++++++++++++++++--------- src/interpreter.h | 42 ++---- src/las.c | 4 +- src/lex.c | 156 ++++++++++++++-------- src/lex.h | 8 +- src/peep.c | 51 +++++++- src/program.c | 36 +++++- src/program.h | 7 +- 13 files changed, 608 insertions(+), 165 deletions(-) create mode 100644 bin/make_interpret_functions.pike diff --git a/bin/make_interpret_functions.pike b/bin/make_interpret_functions.pike new file mode 100644 index 0000000000..80655d08dd --- /dev/null +++ b/bin/make_interpret_functions.pike @@ -0,0 +1,140 @@ +#!/usr/local/bin/pike + +#ifdef OLD +import "."; +#define PC .Pike +#else /* !OLD */ +#if constant(Parser.Pike) +#define PC Parser.Pike +#else /* !constant(Parser.Pike) */ +#define PC Parser.C +#endif /* constant(Parser.Pike) */ +#endif /* OLD */ + +mapping ops=([]); + +array fixit2(array x) +{ + array ret=({}); + array opcodes=({}); + for(int e=0;e<sizeof(x);e++) + { + if(objectp(x[e]) && ops[(string)x[e]]) + { + opcodes+=x[e..e+1]; + array tmp=fixit2((x[e+1]/ ({ PC.Token(",") }) )[-1][0]); + + ret+=({ tmp[0] }); + opcodes+=tmp[1]; + e++; + } + else if(arrayp(x[e])) + { + array tmp=fixit2(x[e]); + ret+=tmp[0]; + opcodes+=tmp[1]; + } + else + { + ret+=({x[e]}); + } + } + return ({ ret, opcodes }); +} + +array fixit(array x) +{ + array ret=({}); + for(int e=0;e<sizeof(x);e++) + { + if(objectp(x[e]) && ops[(string)x[e]]) + { +// werror("DOING %s\n",(string)(x[e+1][1])); + array tmp=fixit2(x[e+1]); + ret+=({x[e]}) + tmp[0] + tmp[1]; + e++; + + /* Skip traling ; */ + if(e+1<sizeof(x) && objectp(x[e+1]) && ";" == (string)x[e+1]) + { + object tmp=x[e+1]; + tmp->text=""; + ret+=({tmp}); + e++; + } + } + else + { + ret+=({x[e]}); + } + } + return ret; +} + +array filter_out_cases(array x) +{ + array y=x/({ PC.Token("CASE") }); + for(int e=1;e<sizeof(y);e++) y[e]=y[e][1..]; + return y*({}); +} + +array fix_cases(array x) +{ + int start=0; + int undone=0; + array ret=({}); + + while(1) + { + int casepos=search(x,PC.Token("CASE"), start); + werror("%O\n",PC.simple_reconstitute(x[casepos..casepos+1])); + if(casepos == -1) break; + int donepos=search(x,PC.Token("DONE"),casepos+1); + + ret+=x[undone..casepos-1]+ + ({ + PC.Token("OPCODE0"), + ({ + PC.Token("("), + x[casepos+1][1], + PC.Token(","), + PC.Token(sprintf("%O",(string)x[casepos+1][1])), + PC.Token(","), + ({ PC.Token("{") })+ + filter_out_cases(x[casepos+2..donepos-1])+ + ({ PC.Token("}") }), + PC.Token(")"), + PC.Token(";"), + }) + }); + + start=casepos+1; + undone=donepos+1; + } + + return ret + x[undone..]; +} + +int main(int argc, array(string) argv) +{ + string file=argv[1]; + mixed x=Stdio.read_file(file); + x=PC.split(x); + x=PC.tokenize(x,file); + x=PC.hide_whitespaces(x); + x=PC.group(x); + + for(int e=0;e<=2;e++) + foreach( ({"","_JUMP","_TAIL","_TAILJUMP"}) , string postfix) + ops[sprintf("OPCODE%d%s",e,postfix)]=1; + +// werror("%O\n",ops); + + x=fix_cases(x); + x=fixit(x); + + if(getenv("PIKE_DEBUG_PRECOMPILER")) + write(PC.simple_reconstitute(x)); + else + write(PC.reconstitute_with_line_numbers(x)); +} diff --git a/src/Makefile.in b/src/Makefile.in index 2cd12a2f86..853182c43e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.267 2001/07/13 18:19:07 grubba Exp $ +# $Id: Makefile.in,v 1.268 2001/07/16 19:48:56 hubbe Exp $ # # This line is needed on some machines. @@ -718,6 +718,10 @@ $(SRCDIR)/language.h_src: $(SRCDIR)/language.yacc $(SRCDIR)/language.c: $(SRCDIR)/language.h_src touch $(SRCDIR)/language.c + +interpret_functions_fixed.h: interpret_functions.h + ./precompile.sh make_interpret_functions.pike >"$@" "$<" || { rm "$@"; exit 1; } + # UnixWare make needs help to find the source file... builtin.o: $(SRCDIR)/builtin.c diff --git a/src/acconfig.h b/src/acconfig.h index 4dedd5f53a..629819abff 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -1,5 +1,5 @@ /* - * $Id: acconfig.h,v 1.91 2001/07/13 18:19:06 grubba Exp $ + * $Id: acconfig.h,v 1.92 2001/07/16 19:48:56 hubbe Exp $ */ #ifndef MACHINE_H #define MACHINE_H @@ -239,6 +239,9 @@ /* Define if you have gcc-style computed goto, and want to use them. */ #undef HAVE_COMPUTED_GOTO +/* Define this to use machine code */ +#undef PIKE_USE_MACHINE_CODE + /* You have gcc-type function attributes? */ #undef HAVE_FUNCTION_ATTRIBUTES diff --git a/src/configure.in b/src/configure.in index 64804870fc..2489cd7866 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.537 2001/07/13 18:19:06 grubba Exp $") +AC_REVISION("$Id: configure.in,v 1.538 2001/07/16 19:48:56 hubbe Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -989,6 +989,11 @@ AC_ARG_WITH(security, [ --with-security enable internal pike security AC_ARG_WITH(bignums, [ --without-bignums disable internal conversion to bignums],[],[with_bignums=yes]) AC_ARG_WITH(shared-nodes,[ --without-shared-nodes disable the SHARED_NODES mode of the optimizer],[],[with_shared_nodes=yes]) AC_ARG_WITH(computed-goto,[ --with-computed-goto Enable use of gcc-style computed goto (EXPERIMENTAL).], [], [with_computed_goto=no]) +AC_ARG_WITH(computed-goto,[ --with-machine-code Enable use of machine code when possible (EXPERIMENTAL).], [ + if test "$with_machine_code" = "yes"; then + AC_DEFINE(PIKE_USE_MACHINE_CODE) + else :; fi +], []) AC_ARG_WITH(keypair-loop,[ --with-keypair-loop Enable use of the keypair mapping loop method (EXPERIMENTAL).],[ if test "$with_keypair_loop" = "yes"; then diff --git a/src/interpret.c b/src/interpret.c index 40bfa6c798..fed49fbbcc 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.219 2001/07/13 11:26:38 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.220 2001/07/16 19:48:57 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -744,6 +744,93 @@ static int o_catch(PIKE_OPCODE_T *pc); #define EVAL_INSTR_RET_CHECK(x) #endif + +#ifdef PIKE_USE_MACHINE_CODE + +#define LOW_GET_JUMP() EXTRACT_INT(PROG_COUNTER) +#define LOW_SKIPJUMP() (PROG_COUNTER += sizeof(INT32)) + +/* Labels to jump to to cause eval_instruction to return */ +/* FIXME: Replace these with assembler lables */ +void *do_inter_return_label; +void *do_escape_catch_label; +void *dummy_label; + + +#define OPCODE0(O,N,C) void PIKE_CONCAT(opcode_,O)(void) C +#define OPCODE1(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1) C +#define OPCODE2(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1,INT32 arg2) C + +#define OPCODE0_JUMP(O,N,C) void PIKE_CONCAT(opcode_,O)(void) C +#define OPCODE1_JUMP(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1) C +#define OPCODE2_JUMP(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1,INT32 arg2) C + +#define OPCODE0_TAIL(O,N,C) void PIKE_CONCAT(opcode_,O)(void) C +#define OPCODE1_TAIL(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1) C +#define OPCODE2_TAIL(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1,INT32 arg2) C + +#define OPCODE0_TAILJUMP(O,N,C) void PIKE_CONCAT(opcode_,O)(void) C +#define OPCODE1_TAILJUMP(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1) C +#define OPCODE2_TAILJUMP(O,N,C) void PIKE_CONCAT(opcode_,O)(INT32 arg1,INT32 arg2) C + +#undef HAVE_COMPUTED_GOTO + +#if defined(__i386__) && defined(__GNUC__) +#define PROG_COUNTER (((unsigned char **)__builtin_frame_address(0))[1]) + +static int eval_instruction(PIKE_OPCODE_T *pc) +{ + do_inter_return_label = && inter_return_label; + do_escape_catch_label = && inter_escape_catch_label; + + /* This code does not clobber %eax, but + * the code jumped to does. + */ + __asm__ __volatile__( " sub $8,%%esp\n" + " jmp *%0" + : "=m" (pc) + : + : "cc", "memory", "eax" ); + + /* This code is never reached, but will + * prevent gcc from optimizing the labels below too much + */ + + fprintf(stderr,"We have reached the end of the world!\n"); + goto *dummy_label; + + /* %%esp will be slightly buggered after + * returning from the function code (8 bytes off), but that + * should not matter to these return statements. -Hubbe + */ + + inter_return_label: return -1; + inter_escape_catch_label: return -2; +} + +#endif + +#ifdef PIKE_USE_SPARC_GCC +#define PROG_COUNTER reg_pc +register void *reg_pc __asm__ ("%i7"); +#endif + +#undef DONE +#undef FETCH +#undef INTER_RETURN +#undef INTER_ESCAPE_CATCH + +#define DONE return +#define FETCH +#define INTER_RETURN {PROG_COUNTER=do_inter_return_label;DONE;} +#define INTER_ESCAPE_CATCH {PROG_COUNTER=do_escape_catch_label;DONE;} + +#include "interpret_functions_fixed.h" + + +#else /* PIKE_USE_MACHINE_CODE */ + + #ifdef HAVE_COMPUTED_GOTO int lookup_sort_fun(const void *a, const void *b) { @@ -761,11 +848,20 @@ int lookup_sort_fun(const void *a, const void *b) #undef eval_instruction #define eval_instruction eval_instruction_without_debug + #undef PIKE_DEBUG +#undef NDEBUG +#undef DO_IF_DEBUG +#define DO_IF_DEBUG(X) #define print_return_value() #include "interpreter.h" -#undef print_return_value + #define PIKE_DEBUG +#define NDEBUG +#undef DO_IF_DEBUG +#define DO_IF_DEBUG(X) X +#undef print_return_value + #undef eval_instruction static inline int eval_instruction(unsigned char *pc) @@ -781,6 +877,9 @@ static inline int eval_instruction(unsigned char *pc) #include "interpreter.h" #endif + +#endif /* PIKE_USE_MACHINE_CODE */ + static void trace_return_value(void) { char *s; @@ -2080,4 +2179,3 @@ void really_clean_up_interpret(void) free_all_pike_frame_blocks(); #endif } - diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 3ab6470274..391859e31b 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -1,5 +1,5 @@ /* - * $Id: interpret_functions.h,v 1.75 2001/07/15 23:14:36 hubbe Exp $ + * $Id: interpret_functions.h,v 1.76 2001/07/16 19:48:57 hubbe Exp $ * * Opcode definitions for the interpreter. */ @@ -56,6 +56,40 @@ #define INTER_RETURN return -1 #endif +#ifndef OVERRIDE_JUMPS + +#undef GET_JUMP +#undef SKIPJUMP +#undef DOJUMP + +#ifdef PIKE_DEBUG + +#define GET_JUMP() (backlog[backlogp].arg=(\ + (t_flag>3 ? sprintf(trace_buffer, "- Target = %+ld\n", \ + (long)LOW_GET_JUMP()), \ + write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0), \ + LOW_GET_JUMP())) + +#define SKIPJUMP() (GET_JUMP(), LOW_SKIPJUMP()) + +#else /* !PIKE_DEBUG */ + +#define GET_JUMP() LOW_GET_JUMP() +#define SKIPJUMP() LOW_SKIPJUMP() + +#endif /* PIKE_DEBUG */ + +#define DOJUMP() do { \ + INT32 tmp; \ + tmp = GET_JUMP(); \ + PROG_COUNTER += tmp; \ + FETCH; \ + if(tmp < 0) \ + fast_check_threads_etc(6); \ + } while(0) + +#endif /* OVERRIDE_JUMPS */ + /* WARNING: * The surgeon general has stated that define code blocks @@ -1851,71 +1885,120 @@ OPCODE1_JUMP(F_COND_RECUR, "recur if not overloaded", { /* Assume that the number of arguments is correct */ /* FIXME: Use new recursion stuff */ OPCODE0_TAILJUMP(F_RECUR, "recur", { - instr = 0; - - OPCODE0_TAILJUMP(F_RECUR_AND_POP, "recur & pop", { - PIKE_OPCODE_T opcode = instr; - PIKE_OPCODE_T *addr; - struct pike_frame *new_frame; - - fast_check_threads_etc(6); - check_c_stack(8192); - check_stack(256); - - new_frame=alloc_pike_frame(); - new_frame[0]=Pike_fp[0]; - - new_frame->refs=1; - new_frame->next=Pike_fp; - - new_frame->save_sp = new_frame->expendible = - new_frame->locals = *--Pike_mark_sp; - new_frame->num_args = new_frame->args = - DO_NOT_WARN((INT32)(Pike_sp - new_frame->locals)); - new_frame->save_mark_sp = Pike_mark_sp; - new_frame->mark_sp_base = Pike_mark_sp; - - addr = PROG_COUNTER+GET_JUMP(); - new_frame->num_locals = - DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-2], - EXTRACT_UCHAR(addr-2)); - - DO_IF_DEBUG({ - if(new_frame->num_args != - DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-1], - EXTRACT_UCHAR(addr-1))) - fatal("Wrong number of arguments in F_RECUR %d!=%d\n", - new_frame->num_args, - DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-1], - EXTRACT_UCHAR(addr-1))); - - if(t_flag > 3) - fprintf(stderr,"- Allocating %d extra locals.\n", - new_frame->num_locals - new_frame->num_args); - }); - - Pike_fp->pc = PROG_COUNTER + DO_IF_ELSE_COMPUTED_GOTO(1, sizeof(INT32)); - PROG_COUNTER=addr; - FETCH; - - clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args); - Pike_sp += new_frame->num_locals - new_frame->args; - - if(new_frame->scope) add_ref(new_frame->scope); - add_ref(new_frame->current_object); - add_ref(new_frame->context.prog); - if(new_frame->context.parent) - add_ref(new_frame->context.parent); - Pike_fp=new_frame; - new_frame->flags=PIKE_FRAME_RETURN_INTERNAL; - if (opcode) { - /* F_RECUR_AND_POP */ - new_frame->flags|=PIKE_FRAME_RETURN_POP; - } + PIKE_OPCODE_T *addr; + struct pike_frame *new_frame; + + fast_check_threads_etc(6); + check_c_stack(8192); + check_stack(256); + + new_frame=alloc_pike_frame(); + new_frame[0]=Pike_fp[0]; + + new_frame->refs=1; + new_frame->next=Pike_fp; + + new_frame->save_sp = new_frame->expendible = + new_frame->locals = *--Pike_mark_sp; + new_frame->num_args = new_frame->args = + DO_NOT_WARN((INT32)(Pike_sp - new_frame->locals)); + new_frame->save_mark_sp = Pike_mark_sp; + new_frame->mark_sp_base = Pike_mark_sp; + + addr = PROG_COUNTER+GET_JUMP(); + new_frame->num_locals = + DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-2], + EXTRACT_UCHAR(addr-2)); + + DO_IF_DEBUG({ + if(new_frame->num_args != + DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-1], + EXTRACT_UCHAR(addr-1))) + fatal("Wrong number of arguments in F_RECUR %d!=%d\n", + new_frame->num_args, + DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-1], + EXTRACT_UCHAR(addr-1))); + + if(t_flag > 3) + fprintf(stderr,"- Allocating %d extra locals.\n", + new_frame->num_locals - new_frame->num_args); }); + + Pike_fp->pc = PROG_COUNTER + DO_IF_ELSE_COMPUTED_GOTO(1, sizeof(INT32)); + PROG_COUNTER=addr; + FETCH; + + clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args); + Pike_sp += new_frame->num_locals - new_frame->args; + + if(new_frame->scope) add_ref(new_frame->scope); + add_ref(new_frame->current_object); + add_ref(new_frame->context.prog); + if(new_frame->context.parent) + add_ref(new_frame->context.parent); + Pike_fp=new_frame; + new_frame->flags=PIKE_FRAME_RETURN_INTERNAL; + }); +}); + +/* Ugly code duplication */ +OPCODE0_JUMP(F_RECUR_AND_POP, "recur & pop", { + PIKE_OPCODE_T *addr; + struct pike_frame *new_frame; + + fast_check_threads_etc(6); + check_c_stack(8192); + check_stack(256); + + new_frame=alloc_pike_frame(); + new_frame[0]=Pike_fp[0]; + + new_frame->refs=1; + new_frame->next=Pike_fp; + + new_frame->save_sp = new_frame->expendible = + new_frame->locals = *--Pike_mark_sp; + new_frame->num_args = new_frame->args = + DO_NOT_WARN((INT32)(Pike_sp - new_frame->locals)); + new_frame->save_mark_sp = Pike_mark_sp; + new_frame->mark_sp_base = Pike_mark_sp; + + addr = PROG_COUNTER+GET_JUMP(); + new_frame->num_locals = + DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-2], + EXTRACT_UCHAR(addr-2)); + + DO_IF_DEBUG({ + if(new_frame->num_args != + DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-1], + EXTRACT_UCHAR(addr-1))) + fatal("Wrong number of arguments in F_RECUR %d!=%d\n", + new_frame->num_args, + DO_IF_ELSE_COMPUTED_GOTO((ptrdiff_t)addr[-1], + EXTRACT_UCHAR(addr-1))); + + if(t_flag > 3) + fprintf(stderr,"- Allocating %d extra locals.\n", + new_frame->num_locals - new_frame->num_args); }); + + Pike_fp->pc = PROG_COUNTER + DO_IF_ELSE_COMPUTED_GOTO(1, sizeof(INT32)); + PROG_COUNTER=addr; + FETCH; + + clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args); + Pike_sp += new_frame->num_locals - new_frame->args; + + if(new_frame->scope) add_ref(new_frame->scope); + add_ref(new_frame->current_object); + add_ref(new_frame->context.prog); + if(new_frame->context.parent) + add_ref(new_frame->context.parent); + Pike_fp=new_frame; + new_frame->flags=PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; }); + /* Assume that the number of arguments is correct */ /* FIXME: adjust Pike_mark_sp */ OPCODE0_JUMP(F_TAIL_RECUR, "tail recursion", { diff --git a/src/interpreter.h b/src/interpreter.h index d88de1b1a5..28ccb89dad 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -14,20 +14,20 @@ #ifdef HAVE_COMPUTED_GOTO #define CASE(OP) PIKE_CONCAT(LABEL_,OP): FETCH -#define FETCH (instr = pc[0]) +#define FETCH (instr = PROG_COUNTER[0]) #ifdef PIKE_DEBUG #define DONE continue #else /* !PIKE_DEBUG */ #define DONE do { \ - Pike_fp->pc = pc++; \ + Pike_fp->pc = PROG_COUNTER++; \ goto *instr; \ } while(0) #endif /* PIKE_DEBUG */ -#define LOW_GET_ARG() ((INT32)(ptrdiff_t)(*(pc++))) -#define LOW_GET_JUMP() ((INT32)(ptrdiff_t)(*(pc))) -#define LOW_SKIPJUMP() (instr = (++pc)[0]) +#define LOW_GET_ARG() ((INT32)(ptrdiff_t)(*(PROG_COUNTER++))) +#define LOW_GET_JUMP() ((INT32)(ptrdiff_t)(*(PROG_COUNTER))) +#define LOW_SKIPJUMP() (instr = (++PROG_COUNTER)[0]) #define GET_ARG() LOW_GET_ARG() #define GET_ARG2() LOW_GET_ARG() @@ -38,9 +38,9 @@ #define DONE break #define FETCH -#define LOW_GET_ARG() ((pc++)[0]) -#define LOW_GET_JUMP() EXTRACT_INT(pc) -#define LOW_SKIPJUMP() (pc += sizeof(INT32)) +#define LOW_GET_ARG() ((PROG_COUNTER++)[0]) +#define LOW_GET_JUMP() EXTRACT_INT(PROG_COUNTER) +#define LOW_SKIPJUMP() (PROG_COUNTER += sizeof(INT32)) #ifdef PIKE_DEBUG @@ -71,32 +71,6 @@ #endif /* HAVE_COMPUTED_GOTO */ -#ifdef PIKE_DEBUG - -#define GET_JUMP() (backlog[backlogp].arg=(\ - (t_flag>3 ? sprintf(trace_buffer, "- Target = %+ld\n", \ - (long)LOW_GET_JUMP()), \ - write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0), \ - LOW_GET_JUMP())) - -#define SKIPJUMP() (GET_JUMP(), LOW_SKIPJUMP()) - -#else /* !PIKE_DEBUG */ - -#define GET_JUMP() LOW_GET_JUMP() -#define SKIPJUMP() LOW_SKIPJUMP() - -#endif /* PIKE_DEBUG */ - -#define DOJUMP() do { \ - INT32 tmp; \ - tmp = GET_JUMP(); \ - pc += tmp; \ - FETCH; \ - if(tmp < 0) \ - fast_check_threads_etc(6); \ - } while(0) - #ifndef STEP_BREAK_LINE #define STEP_BREAK_LINE #endif diff --git a/src/las.c b/src/las.c index 59402556f4..4d48eeba8b 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.256 2001/07/13 14:29:56 grubba Exp $"); +RCSID("$Id: las.c,v 1.257 2001/07/16 19:48:58 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -4975,6 +4975,8 @@ ptrdiff_t eval_low(node *n) foo.counter=10000; foo.yes=0; + make_program_executable(Pike_compiler->new_program); + tmp_callback=add_to_callback(&evaluator_callbacks, check_evaluation_time, (void *)&foo,0); diff --git a/src/lex.c b/src/lex.c index e075ffd75b..4e434ff346 100644 --- a/src/lex.c +++ b/src/lex.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: lex.c,v 1.97 2001/07/15 23:14:37 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.98 2001/07/16 19:48:58 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -145,21 +145,64 @@ void exit_lex(void) #endif } -#define OPCODE0(OP,DESC) { DESC, OP, 0 }, -#define OPCODE1(OP,DESC) { DESC, OP, I_HASARG }, -#define OPCODE2(OP,DESC) { DESC, OP, I_TWO_ARGS }, +#ifdef PIKE_USE_MACHINE_CODE +#define ADDR(X) , (void *)PIKE_CONCAT(opcode_,X) +#define NULLADDR , 0 -#define OPCODE0_TAIL(OP,DESC) { DESC, OP, 0 }, -#define OPCODE1_TAIL(OP,DESC) { DESC, OP, I_HASARG }, -#define OPCODE2_TAIL(OP,DESC) { DESC, OP, I_TWO_ARGS }, +#define OPCODE0(OP,DESC) void PIKE_CONCAT(opcode_,OP)(void); +#define OPCODE1(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32); +#define OPCODE2(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32,INT32); -#define OPCODE0_JUMP(OP,DESC) { DESC, OP, I_ISJUMP }, -#define OPCODE1_JUMP(OP,DESC) { DESC, OP, I_HASARG }, -#define OPCODE2_JUMP(OP,DESC) { DESC, OP, I_TWO_ARGS }, +#define OPCODE0_TAIL(OP,DESC) void PIKE_CONCAT(opcode_,OP)(void); +#define OPCODE1_TAIL(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32); +#define OPCODE2_TAIL(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32,INT32); -#define OPCODE0_TAILJUMP(OP,DESC) { DESC, OP, I_ISJUMP }, -#define OPCODE1_TAILJUMP(OP,DESC) { DESC, OP, I_HASARG }, -#define OPCODE2_TAILJUMP(OP,DESC) { DESC, OP, I_TWO_ARGS }, +#define OPCODE0_JUMP(OP,DESC) void PIKE_CONCAT(opcode_,OP)(void); +#define OPCODE1_JUMP(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32); +#define OPCODE2_JUMP(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32,INT32); + +#define OPCODE0_TAILJUMP(OP,DESC) void PIKE_CONCAT(opcode_,OP)(void); +#define OPCODE1_TAILJUMP(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32); +#define OPCODE2_TAILJUMP(OP,DESC) void PIKE_CONCAT(opcode_,OP)(INT32,INT32); + +#include "interpret_protos.h" + +#undef OPCODE0 +#undef OPCODE1 +#undef OPCODE2 + +#undef OPCODE0_TAIL +#undef OPCODE1_TAIL +#undef OPCODE2_TAIL + +#undef OPCODE0_JUMP +#undef OPCODE1_JUMP +#undef OPCODE2_JUMP + +#undef OPCODE0_TAILJUMP +#undef OPCODE1_TAILJUMP +#undef OPCODE2_TAILJUMP + +#else +#define ADDR(X) +#define NULLADDR +#endif + +#define OPCODE0(OP,DESC) { DESC, OP, 0 ADDR(OP) }, +#define OPCODE1(OP,DESC) { DESC, OP, I_HASARG ADDR(OP) }, +#define OPCODE2(OP,DESC) { DESC, OP, I_TWO_ARGS ADDR(OP) }, + +#define OPCODE0_TAIL(OP,DESC) { DESC, OP, 0 ADDR(OP) }, +#define OPCODE1_TAIL(OP,DESC) { DESC, OP, I_HASARG ADDR(OP) }, +#define OPCODE2_TAIL(OP,DESC) { DESC, OP, I_TWO_ARGS ADDR(OP) }, + +#define OPCODE0_JUMP(OP,DESC) { DESC, OP, I_ISJUMP ADDR(OP) }, +#define OPCODE1_JUMP(OP,DESC) { DESC, OP, I_HASARG ADDR(OP) }, +#define OPCODE2_JUMP(OP,DESC) { DESC, OP, I_TWO_ARGS ADDR(OP) }, + +#define OPCODE0_TAILJUMP(OP,DESC) { DESC, OP, I_ISJUMP ADDR(OP) }, +#define OPCODE1_TAILJUMP(OP,DESC) { DESC, OP, I_HASARG ADDR(OP) }, +#define OPCODE2_TAILJUMP(OP,DESC) { DESC, OP, I_TWO_ARGS ADDR(OP) }, #define LEXER @@ -168,48 +211,48 @@ struct keyword instr_names[]= #ifndef PIKE_PRECOMPILER #include "interpret_protos.h" #endif /* !PIKE_PRECOMPILER */ -{ "%=", F_MOD_EQ,0 }, -{ "&=", F_AND_EQ,0 }, -{ "|=", F_OR_EQ,0 }, -{ "*=", F_MULT_EQ,0 }, -{ "+=", F_ADD_EQ,0 }, -{ "-=", F_SUB_EQ,0 }, -{ "/=", F_DIV_EQ,0 }, -{ "<<=", F_LSH_EQ,0 }, -{ ">>=", F_RSH_EQ,0 }, -{ "^=", F_XOR_EQ,0 }, -{ "arg+=1024", F_PREFIX_1024,0 }, -{ "arg+=256", F_PREFIX_256,0 }, -{ "arg+=256*X", F_PREFIX_CHARX256,0 }, -{ "arg+=256*XX", F_PREFIX_WORDX256,0 }, -{ "arg+=256*XXX", F_PREFIX_24BITX256,0 }, -{ "arg+=512", F_PREFIX_512,0 }, -{ "arg+=768", F_PREFIX_768,0 }, - -{ "arg+=1024", F_PREFIX2_1024,0 }, -{ "arg+=256", F_PREFIX2_256,0 }, -{ "arg+=256*X", F_PREFIX2_CHARX256,0 }, -{ "arg+=256*XX", F_PREFIX2_WORDX256,0 }, -{ "arg+=256*XXX", F_PREFIX2_24BITX256,0 }, -{ "arg+=512", F_PREFIX2_512,0 }, -{ "arg+=768", F_PREFIX2_768,0 }, - -{ "break", F_BREAK,0 }, -{ "case", F_CASE,0 }, -{ "continue", F_CONTINUE,0 }, -{ "default", F_DEFAULT,0 }, -{ "do-while", F_DO,0 }, -{ "for", F_FOR,0 }, - -{ "pointer", F_POINTER, I_ISPOINTER }, -{ "data", F_DATA, I_DATA }, -{ "byte", F_BYTE, I_DATA }, -{ "lvalue_list", F_LVALUE_LIST,0 }, -{ "label", F_LABEL,I_HASARG }, -{ "align", F_ALIGN, I_HASARG }, -{ "nop", F_NOP,0 }, -{ "function start", F_START_FUNCTION,0 }, -{ "notreached!", F_NOTREACHED, 0 }, +{ "%=", F_MOD_EQ,0 NULLADDR }, +{ "&=", F_AND_EQ,0 NULLADDR }, +{ "|=", F_OR_EQ,0 NULLADDR }, +{ "*=", F_MULT_EQ,0 NULLADDR }, +{ "+=", F_ADD_EQ,0 NULLADDR }, +{ "-=", F_SUB_EQ,0 NULLADDR }, +{ "/=", F_DIV_EQ,0 NULLADDR }, +{ "<<=", F_LSH_EQ,0 NULLADDR }, +{ ">>=", F_RSH_EQ,0 NULLADDR }, +{ "^=", F_XOR_EQ,0 NULLADDR }, +{ "arg+=1024", F_PREFIX_1024,0 NULLADDR }, +{ "arg+=256", F_PREFIX_256,0 NULLADDR }, +{ "arg+=256*X", F_PREFIX_CHARX256,0 NULLADDR }, +{ "arg+=256*XX", F_PREFIX_WORDX256,0 NULLADDR }, +{ "arg+=256*XXX", F_PREFIX_24BITX256,0 NULLADDR }, +{ "arg+=512", F_PREFIX_512,0 NULLADDR }, +{ "arg+=768", F_PREFIX_768,0 NULLADDR }, + +{ "arg+=1024", F_PREFIX2_1024,0 NULLADDR }, +{ "arg+=256", F_PREFIX2_256,0 NULLADDR }, +{ "arg+=256*X", F_PREFIX2_CHARX256,0 NULLADDR }, +{ "arg+=256*XX", F_PREFIX2_WORDX256,0 NULLADDR }, +{ "arg+=256*XXX", F_PREFIX2_24BITX256,0 NULLADDR }, +{ "arg+=512", F_PREFIX2_512,0 NULLADDR }, +{ "arg+=768", F_PREFIX2_768,0 NULLADDR }, + +{ "break", F_BREAK,0 NULLADDR }, +{ "case", F_CASE,0 NULLADDR }, +{ "continue", F_CONTINUE,0 NULLADDR }, +{ "default", F_DEFAULT,0 NULLADDR }, +{ "do-while", F_DO,0 NULLADDR }, +{ "for", F_FOR,0 NULLADDR }, + +{ "pointer", F_POINTER, I_ISPOINTER NULLADDR }, +{ "data", F_DATA, I_DATA NULLADDR }, +{ "byte", F_BYTE, I_DATA NULLADDR }, +{ "lvalue_list", F_LVALUE_LIST,0 NULLADDR }, +{ "label", F_LABEL,I_HASARG NULLADDR }, +{ "align", F_ALIGN, I_HASARG NULLADDR }, +{ "nop", F_NOP,0 NULLADDR }, +{ "function start", F_START_FUNCTION,0 NULLADDR }, +{ "notreached!", F_NOTREACHED, 0 NULLADDR }, }; struct instr instrs[F_MAX_INSTR - F_OFFSET]; @@ -248,6 +291,9 @@ void init_lex() instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word; instrs[instr_names[i].token - F_OFFSET].flags=instr_names[i].flags; +#ifdef PIKE_USE_MACHINE_CODE + instrs[instr_names[i].token - F_OFFSET].address=instr_names[i].address; +#endif } #ifdef PIKE_DEBUG diff --git a/src/lex.h b/src/lex.h index 96a47efe29..013e5cc290 100644 --- a/src/lex.h +++ b/src/lex.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: lex.h,v 1.18 2001/07/09 14:19:16 grubba Exp $ + * $Id: lex.h,v 1.19 2001/07/16 19:48:58 hubbe Exp $ */ #ifndef LEX_H #define LEX_H @@ -17,6 +17,9 @@ struct keyword char *word; int token; int flags; +#ifdef PIKE_USE_MACHINE_CODE + void *address; +#endif }; #define I_HASARG 1 @@ -40,6 +43,9 @@ struct instr #endif int flags; char *name; +#ifdef PIKE_USE_MACHINE_CODE + void *address; +#endif }; #ifdef PIKE_DEBUG diff --git a/src/peep.c b/src/peep.c index d005636506..02020591f7 100644 --- a/src/peep.c +++ b/src/peep.c @@ -17,7 +17,7 @@ #include "builtin_functions.h" #include "constants.h" -RCSID("$Id: peep.c,v 1.53 2001/07/09 14:19:16 grubba Exp $"); +RCSID("$Id: peep.c,v 1.54 2001/07/16 19:48:59 hubbe Exp $"); static void asm_opt(void); @@ -135,6 +135,22 @@ void update_arg(int instr,INT32 arg) /**** Bytecode Generator *****/ + +#if defined(__i386__) && defined(__GNUC__) + +#define PUSH_INT(X) ins_int((INT32)(X), add_to_program) +#define PUSH_ADDR(X) PUSH_INT((X)) +#define PUSHL(X) add_to_program(0x68),PUSH_INT((X) +#define CALL_ABSOLUTE(X) add_to_program(0x9a),PUSH_ADDR((X)) +#define RET() add_to_program(0xc3); +#define POP(X) \ + add_to_program(0x83), /* Addl.b 0x4, %esp */ \ + add_to_program(0xc4), \ + add_to_program(-X) + +#endif + + void ins_f_byte(unsigned int b) { #ifdef PIKE_DEBUG @@ -147,6 +163,14 @@ void ins_f_byte(unsigned int b) if(b>255) Pike_error("Instruction too big %d\n",b); #endif + +#ifdef PIKE_USE_MACHINE_CODE +#if defined(__i386__) && defined(__GNUC__) + CALL_ABSOLUTE(instrs[b].address); + return +#endif +#endif + #ifdef HAVE_COMPUTED_GOTO add_to_program(fcode_to_opcode[b]); #else /* !HAVE_COMPUTED_GOTO */ @@ -156,6 +180,17 @@ void ins_f_byte(unsigned int b) static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b) { +#ifdef PIKE_USE_MACHINE_CODE +#if defined(__i386__) && defined(__GNUC__) + add_to_program(0xc7); /* movl $xxxx, (%esp) */ + add_to_program(0x04); + add_to_program(0x24); + PUSH_INT(b); + ins_f_byte(a); + return; +#endif +#endif + #ifndef HAVE_COMPUTED_GOTO switch(b >> 8) { @@ -189,7 +224,19 @@ static void ins_f_byte_with_2_args(unsigned int a, unsigned INT32 c, unsigned INT32 b) { -#ifndef HAVE_COMPUTED_GOTO +#ifdef PIKE_USE_MACHINE_CODE +#if defined(__i386__) && defined(__GNUC__) + add_to_program(0xc7); /* movl $xxxx, 4(%esp) */ + add_to_program(0x44); + add_to_program(0x24); + add_to_program(0x04); + PUSH_INT(c); + ins_f_byte_with_arg(a,b); + return +#endif +#endif + +#ifdef HAVE_COMPUTED_GOTO switch(b >> 8) { case 0 : break; diff --git a/src/program.c b/src/program.c index 6eed93cc8a..4be097b974 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.353 2001/07/13 11:26:39 grubba Exp $"); +RCSID("$Id: program.c,v 1.354 2001/07/16 19:48:59 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -991,7 +991,11 @@ void optimize_program(struct program *p) #include "program_areas.h" data=malloc(size); - if(!data) return; /* We are out of memory, but we don't care! */ + if(!data) + { + make_program_executable(p); + return; /* We are out of memory, but we don't care! */ + } size=0; @@ -1006,6 +1010,7 @@ void optimize_program(struct program *p) p->total_size=size + sizeof(struct program); p->flags |= PROGRAM_OPTIMIZED; + make_program_executable(p); } /* internal function to make the index-table */ @@ -3995,6 +4000,20 @@ void store_linenumber(INT32 current_line, struct pike_string *current_file) if(Pike_compiler->last_line != current_line || Pike_compiler->last_file != current_file) { +#ifdef PIKE_USE_MACHINE_CODE +#if defined(__i386__) && defined(__GNUC__) + /* We need to update Pike_interpreter.frame_pointer->pc */ + INT32 tmp=PC; + add_to_program(0x4c /* mov $xxxxx, %eax */); + ins_int((INT32)(&Pike_interpreter.frame_pointer), add_to_program); + + add_to_program(0xc7); /* movl $xxxxx, yy%(eax) */ + add_to_program(0x40); + add_to_program(OFFSETOF(pike_frame, pc)); + ins_int((INT32)tmp, add_to_program); +#endif +#endif + if((Pike_compiler->last_file != current_file) || (DO_NOT_WARN((INT32)(PC - Pike_compiler->last_pc)) == 127)) { @@ -5484,7 +5503,6 @@ PMOD_EXPORT void *parent_storage(int depth) } - PMOD_EXPORT void change_compiler_compatibility(int major, int minor) { if(major == Pike_compiler->compat_major && @@ -5563,3 +5581,15 @@ PMOD_EXPORT void change_compiler_compatibility(int major, int minor) Pike_compiler->compat_major=major; Pike_compiler->compat_minor=minor; } + +#ifdef PIKE_USE_MACHINE_CODE + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + +void make_program_executable(struct program *p) +{ + mprotect(p->program, p->num_program, PROT_EXEC | PROT_READ | PROT_WRITE); +} +#endif diff --git a/src/program.h b/src/program.h index 8f94190df2..37d023b16b 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.138 2001/07/13 11:26:39 grubba Exp $ + * $Id: program.h,v 1.139 2001/07/16 19:48:59 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -563,8 +563,13 @@ PMOD_EXPORT int is_compatible(struct program *a, struct program *b); int yyexplain_not_implements(struct program *a, struct program *b, int flags); PMOD_EXPORT void *parent_storage(int depth); PMOD_EXPORT void change_compiler_compatibility(int major, int minor); +void make_program_executable(struct program *p); /* Prototypes end here */ +#ifndef PIKE_USE_MACHINE_CODE +#define make_program_executable(X) +#endif + #define ADD_FUNCTION(NAME, FUNC, TYPE, FLAGS) \ quick_add_function(NAME, CONSTANT_STRLEN(NAME), FUNC, TYPE,\ CONSTANT_STRLEN(TYPE), FLAGS, \ -- GitLab