From 64415f09de0691c2ccdf65df169a211b7917728b Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 5 Feb 2010 11:03:51 +0100 Subject: Turn on instruction packing in the loader and virtual machine --- erts/emulator/beam/beam_debug.c | 38 +++++++++++++++++++++++++++++++++++--- erts/emulator/beam/beam_load.c | 24 ++++++++++++++---------- erts/emulator/beam/erl_alloc.h | 4 ++-- erts/emulator/beam/erl_process.c | 2 +- erts/emulator/beam/external.c | 2 +- erts/emulator/beam/io.c | 2 +- erts/emulator/utils/beam_makeops | 17 ++++++++++------- 7 files changed, 64 insertions(+), 25 deletions(-) diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 43dcebd0fb..355f2b89c5 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -125,6 +125,38 @@ erts_debug_breakpoint_2(Process* p, Eterm MFA, Eterm bool) BIF_ERROR(p, BADARG); } +#if 0 /* XXX:PaN - not used */ +void debug_dump_code(BeamInstr *I, int num) +{ + BeamInstr *code_ptr = I; + BeamInstr *end = code_ptr + num; + erts_dsprintf_buf_t *dsbufp; + BeamInstr instr; + int i; + + dsbufp = erts_create_tmp_dsbuf(0); + while (code_ptr < end) { + erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr); + instr = (BeamInstr) code_ptr[0]; + for (i = 0; i < NUM_SPECIFIC_OPS; i++) { + if (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') { + code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp, + i, opc[i].sz-1, code_ptr+1) + 1; + break; + } + } + if (i >= NUM_SPECIFIC_OPS) { + erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, + "unknown " HEXF "\n", instr); + code_ptr++; + } + } + dsbufp->str[dsbufp->str_len] = 0; + erts_fprintf(stderr,"%s", dsbufp->str); + erts_destroy_tmp_dsbuf(dsbufp); +} +#endif + Eterm erts_debug_disassemble_1(Process* p, Eterm addr) { @@ -325,8 +357,8 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr) packed >>= BEAM_TIGHT_SHIFT; break; case '6': /* Shift 16 steps */ - *ap++ = packed & 0xffff; - packed >>= 16; + *ap++ = packed & BEAM_LOOSE_MASK; + packed >>= BEAM_LOOSE_SHIFT; break; case 'p': *sp++ = *--ap; @@ -474,7 +506,7 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr) ap++; break; case 'P': /* Byte offset into tuple (see beam_load.c) */ - erts_print(to, to_arg, "%d", (*ap / sizeof(BeamInstr)) - 1); + erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm)) - 1); ap++; break; case 'l': /* fr(N) */ diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 5b56002d3b..22c6c39cf5 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -591,6 +591,7 @@ erts_load_module(Process *c_p, } return result; } +/* #define LOAD_MEMORY_HARD_DEBUG 1*/ #if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG) /* Requires allocators ERTS_ALLOC_UTIL_HARD_DEBUG also set in erl_alloc_util.h */ @@ -731,6 +732,12 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Loading succeded. */ CHKBLK(ERTS_ALC_T_CODE,state.code); +#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG) + erts_fprintf(stderr,"Loaded %T\n",*modp); +#if 0 + debug_dump_code(state.code,state.ci); +#endif +#endif rval = 0; state.code = NULL; /* Prevent code from being freed. */ *modp = state.module; @@ -786,9 +793,6 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.genop_blocks); state.genop_blocks = next; } -#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG) - erts_fprintf(stderr,"Loaded %T\n",*modp); -#endif return rval; } @@ -2031,16 +2035,16 @@ load_code(LoaderState* stp) tag_to_letter[tmp_op->a[arg].type]); } } -#if !HALFWORD_HEAP /* XXX:PaN - just disabled during development */ + /* * The packing engine. */ if (opc[stp->specific_op].pack[0]) { char* prog; /* Program for packing engine. */ - Uint stack[8]; /* Stack. */ - Uint* sp = stack; /* Points to next free position. */ - Uint packed = 0; /* Accumulator for packed operations. */ - ASSERT(0); /* XXX:PaN - just to check that this does not happen when packing is disabled... */ + BeamInstr stack[8]; /* Stack. */ + BeamInstr* sp = stack; /* Points to next free position. */ + BeamInstr packed = 0; /* Accumulator for packed operations. */ + for (prog = opc[stp->specific_op].pack; *prog; prog++) { switch (*prog) { case 'g': /* Get instruction; push on stack. */ @@ -2053,7 +2057,7 @@ load_code(LoaderState* stp) packed = (packed << BEAM_TIGHT_SHIFT) | code[--ci]; break; case '6': /* Shift 16 steps */ - packed = (packed << 16) | code[--ci]; + packed = (packed << BEAM_LOOSE_SHIFT) | code[--ci]; break; case 'p': /* Put instruction (from stack). */ code[ci++] = *--sp; @@ -2068,7 +2072,7 @@ load_code(LoaderState* stp) } ASSERT(sp == stack); /* Incorrect program? */ } -#endif /* !HALFWORD_HEAP */ + /* * Handle a few special cases. */ diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h index 3f090abdc2..1080a24214 100644 --- a/erts/emulator/beam/erl_alloc.h +++ b/erts/emulator/beam/erl_alloc.h @@ -486,9 +486,9 @@ init_##NAME##_alloc(void) \ qa_data_##NAME##__ = erts_alloc(ERTS_ALC_T_PRE_ALLOC_DATA,tot_size);\ chunk_start = (((char *) qa_data_##NAME##__) \ + sizeof(erts_sched_pref_quick_alloc_data_t)); \ - if ((((Uint) chunk_start) & ERTS_CACHE_LINE_MASK) != ((Uint) 0)) \ + if ((((UWord) chunk_start) & ERTS_CACHE_LINE_MASK) != ((UWord) 0)) \ chunk_start = ((char *) \ - ((((Uint) chunk_start) & ~ERTS_CACHE_LINE_MASK) \ + ((((UWord) chunk_start) & ~ERTS_CACHE_LINE_MASK) \ + ERTS_CACHE_LINE_SIZE)); \ qa_data_##NAME##__->chunks_mem_size = chunk_mem_size; \ qa_data_##NAME##__->start = (void *) chunk_start; \ diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index b12402600b..436d81f791 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -6238,7 +6238,7 @@ Process *schedule(Process *p, int calls) erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS); if (erts_sched_stat.enabled) { - Uint old = ERTS_PROC_SCHED_ID(p, + UWord old = ERTS_PROC_SCHED_ID(p, (ERTS_PROC_LOCK_MAIN | ERTS_PROC_LOCK_STATUS), esdp->no); diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index d6cb6efb79..7f39f8eb12 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2611,7 +2611,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) Uint m, i, arity; Uint result = 0; #if HALFWORD_HEAP - UWord wobj; + UWord wobj = 0; #endif goto L_jump_start; diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index f3062c894c..0a2a2c60e2 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -4053,7 +4053,7 @@ driver_read_timer(ErlDrvPort ix, unsigned long* t) int driver_get_now(ErlDrvNowData *now_data) { - Uint mega,secs,micro + Uint mega,secs,micro; ERTS_SMP_CHK_NO_PROC_LOCKS; if (now_data == NULL) { diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops index 1a76e80620..7b1cd817cf 100755 --- a/erts/emulator/utils/beam_makeops +++ b/erts/emulator/utils/beam_makeops @@ -499,7 +499,11 @@ sub emulator_output { print "\n"; print "#ifdef ARCH_64\n"; print "# define BEAM_LOOSE_MASK 0x1FFFUL\n"; + print "#if HALFWORD_HEAP\n"; + print "# define BEAM_TIGHT_MASK 0x1FFCUL\n"; + print "#else\n"; print "# define BEAM_TIGHT_MASK 0x1FF8UL\n"; + print "#endif\n"; print "# define BEAM_LOOSE_SHIFT 16\n"; print "# define BEAM_TIGHT_SHIFT 16\n"; print "#else\n"; @@ -812,10 +816,9 @@ sub basic_generator { # Pack arguments if requested. # - # /* XXX:PaN temporarilly disabled during halfword implementation step 1 */ - #if ($flags =~ /-pack/ && $hot) { - # ($prefix, $pack_spec, @args) = &do_pack(@args); - #} + if ($flags =~ /-pack/ && $hot) { + ($prefix, $pack_spec, @args) = &do_pack(@args); + } # # Calculate the size of the instruction and generate each argument for @@ -908,16 +911,16 @@ sub basic_generator { my($code); if (defined $macro{$name}) { my($macro_code) = "$prefix$macro(" . join(', ', @f) . ");"; - $var_decls .= "Uint tmp_packed1;" + $var_decls .= "BeamInstr tmp_packed1;" if $macro_code =~ /tmp_packed1/; - $var_decls .= "Uint tmp_packed2;" + $var_decls .= "BeamInstr tmp_packed2;" if $macro_code =~ /tmp_packed2/; if ($flags =~ /-nonext/) { $code = "$macro_code\n"; } else { $code = join("\n", "{ $var_decls", - "UWord* next;", + "BeamInstr* next;", "PreFetch($size, next);", "$macro_code", "NextPF($size, next);", -- cgit v1.2.3