diff options
-rw-r--r-- | erts/emulator/hipe/hipe_arm.c | 3 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_x86.h | 25 | ||||
-rw-r--r-- | erts/etc/common/erlexec.c | 51 | ||||
-rw-r--r-- | erts/etc/unix/cerl.src | 3 | ||||
-rwxr-xr-x | erts/etc/unix/gcov-gen-html | 62 | ||||
-rw-r--r-- | lib/erl_interface/src/misc/ei_printterm.c | 31 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_print_SUITE.erl | 45 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c | 61 |
8 files changed, 242 insertions, 39 deletions
diff --git a/erts/emulator/hipe/hipe_arm.c b/erts/emulator/hipe/hipe_arm.c index c5e2af0b5e..3e1d7e4d5e 100644 --- a/erts/emulator/hipe/hipe_arm.c +++ b/erts/emulator/hipe/hipe_arm.c @@ -18,6 +18,7 @@ * %CopyrightEnd% */ +#ifdef __arm__ #include <stddef.h> /* offsetof() */ #ifdef HAVE_CONFIG_H @@ -285,3 +286,5 @@ void hipe_arch_print_pcb(struct hipe_process_state *p) U("narity ", narity); #undef U } + +#endif /*__arm__*/ diff --git a/erts/emulator/hipe/hipe_x86.h b/erts/emulator/hipe/hipe_x86.h index 8967793171..a1fe75e792 100644 --- a/erts/emulator/hipe/hipe_x86.h +++ b/erts/emulator/hipe/hipe_x86.h @@ -22,17 +22,28 @@ #ifndef HIPE_X86_H #define HIPE_X86_H -static __inline__ void hipe_flush_icache_word(void *address) -{ - /* Do nothing. This works as long as compiled code is - executed by a single CPU thread. */ -} +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif static __inline__ void hipe_flush_icache_range(void *address, unsigned int nbytes) { - /* Do nothing. This works as long as compiled code is - executed by a single CPU thread. */ + void* end = (char*)address + nbytes; + +#if ERTS_AT_LEAST_GCC_VSN__(4, 3, 0) || __has_builtin(__builtin___clear_cache) + __builtin___clear_cache(address, end); +#elif defined(__clang__) + void __clear_cache(void *start, void *end); + __clear_cache(address, end); +#else +# warning "Don't know how to flush instruction cache" +#endif +} + +static __inline__ void hipe_flush_icache_word(void *address) +{ + hipe_flush_icache_range(address, sizeof(void*)); } /* for stack descriptor hash lookup */ diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 8203c46a39..c793243c13 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -255,7 +255,9 @@ static char* key_val_name = ERLANG_VERSION; /* Used by the registry * access functions. */ static char* boot_script = NULL; /* used by option -start_erl and -boot */ -static char* config_script = NULL; /* used by option -start_erl and -config */ +static char** config_scripts = NULL; /* used by option -start_erl and -config */ +static int config_script_cnt = 0; +static int got_start_erl = 0; static HANDLE this_module_handle; static int run_werl; @@ -392,6 +394,22 @@ add_extra_suffixes(char *prog) } #ifdef __WIN32__ +static void add_boot_config(void) +{ + int i; + if (boot_script) + add_args("-boot", boot_script, NULL); + for (i = 0; i < config_script_cnt; i++) { + add_args("-config", config_scripts[i], NULL); + } +} +# define ADD_BOOT_CONFIG add_boot_config() +#else +# define ADD_BOOT_CONFIG +#endif + + +#ifdef __WIN32__ __declspec(dllexport) int win_erlexec(int argc, char **argv, HANDLE module, int windowed) #else int main(int argc, char **argv) @@ -581,16 +599,6 @@ int main(int argc, char **argv) i = 1; -#ifdef __WIN32__ -#define ADD_BOOT_CONFIG \ - if (boot_script) \ - add_args("-boot", boot_script, NULL); \ - if (config_script) \ - add_args("-config", config_script, NULL); -#else -#define ADD_BOOT_CONFIG -#endif - get_home(); add_args("-home", home, NULL); @@ -610,7 +618,9 @@ int main(int argc, char **argv) case 'b': if (strcmp(argv[i], "-boot") == 0) { if (boot_script) - error("Conflicting -start_erl and -boot options"); + error("Conflicting -boot options"); + if (got_start_erl) + error("Conflicting -start_erl and -boot options"); if (i+1 >= argc) usage("-boot"); boot_script = strsave(argv[i+1]); @@ -634,11 +644,14 @@ int main(int argc, char **argv) } #ifdef __WIN32__ else if (strcmp(argv[i], "-config") == 0){ - if (config_script) + if (got_start_erl) error("Conflicting -start_erl and -config options"); if (i+1 >= argc) usage("-config"); - config_script = strsave(argv[i+1]); + config_script_cnt++; + config_scripts = erealloc(config_scripts, + config_script_cnt * sizeof(char*)); + config_scripts[config_script_cnt-1] = strsave(argv[i+1]); i++; } #endif @@ -1371,6 +1384,7 @@ strsave(char* string) static void get_start_erl_data(char *file) { + static char* a_config_script; int fp; char tmpbuffer[512]; char start_erl_data[512]; @@ -1381,7 +1395,7 @@ static void get_start_erl_data(char *file) char* tprogname; if (boot_script) error("Conflicting -start_erl and -boot options"); - if (config_script) + if (config_scripts) error("Conflicting -start_erl and -config options"); env = get_env("RELDIR"); if (env) @@ -1431,10 +1445,13 @@ static void get_start_erl_data(char *file) erts_snprintf(progname,strlen(tprogname) + 20,"%s -start_erl",tprogname); boot_script = emalloc(512); - config_script = emalloc(512); + a_config_script = emalloc(512); erts_snprintf(boot_script, 512, "%s/%s/start", reldir, otpstring); - erts_snprintf(config_script, 512, "%s/%s/sys", reldir, otpstring); + erts_snprintf(a_config_script, 512, "%s/%s/sys", reldir, otpstring); + config_scripts = &a_config_script; + config_script_cnt = 1; + got_start_erl = 1; } diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 8cfc2d549e..7a5d31b9eb 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -293,7 +293,8 @@ if [ "x$GDB" = "x" ]; then fi fi if [ "x$VALGRIND_MISC_FLAGS" = "x" ]; then - valgrind_misc_flags= + valgrind_misc_flags="--show-possibly-lost=no --child-silent-after-fork=yes\ + --suppressions=$ROOTDIR/erts/emulator/valgrind/suppress.standard" else valgrind_misc_flags="$VALGRIND_MISC_FLAGS" fi diff --git a/erts/etc/unix/gcov-gen-html b/erts/etc/unix/gcov-gen-html new file mode 100755 index 0000000000..3fd9f1ca49 --- /dev/null +++ b/erts/etc/unix/gcov-gen-html @@ -0,0 +1,62 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +@ARGV == 2 or die "Usage: gcov-gen-html \$ERL_TOP <output directory>\n"; + +my $srcdir = shift @ARGV; +my $outdir = shift @ARGV; + +my $verbose = 1; +my $flavor = "smp"; + +# setup filenames and paths, observe geninfos --base-directory +# it needs a correct path just after the $geninfo + +my $lcov_path = ""; #/usr/local/bin/"; + +my $geninfo = $lcov_path . "geninfo --no-checksum --base-directory"; +my $genhtml = $lcov_path . "genhtml"; + +# src paths + +my $emu_src_path = "$srcdir/erts/emulator"; +my $elib_src_path = "$srcdir/erts/lib_src"; +my $pcre_src_path = "$emu_src_path"; +my $zlib_src_path = "$emu_src_path"; + +# obj paths + +my $emu_obj_path = <$emu_src_path/obj/*-linux-*/gcov/$flavor>; +my $elib_obj_path = <$elib_src_path/obj/*-linux-*/gcov>; +my $pcre_obj_path = <$emu_src_path/pcre/obj/*-linux-*/gcov>; +my $zlib_obj_path = <$emu_src_path/zlib/obj/*-linux-*/gcov>; + +# info files + +my $emu_info = "$srcdir/emulator-cover.info"; +my $elib_info = "$srcdir/elib-cover.info"; +my $pcre_info = "$srcdir/pcre-cover.info"; + +my $infofiles = "$emu_info $elib_info $pcre_info"; + +run("$geninfo $emu_src_path -o $emu_info $emu_obj_path"); +run("$geninfo $elib_src_path -o $elib_info $elib_obj_path"); +run("$geninfo $pcre_src_path -o $pcre_info $pcre_obj_path"); + +if (<$zlib_obj_path/*.o>) { + my $zlib_info = "$srcdir/zlib-cover.info"; + $infofiles .= " $zlib_info"; + run("$geninfo $zlib_src_path -o $zlib_info $zlib_obj_path"); +} + +run("$genhtml -o $outdir $infofiles"); + + + +sub run { + my $cmd = shift; + print STDERR "\nrun($cmd)\n" if $verbose > 0; + system("$cmd 2>&1") == 0 or die "\nCan't run \"$cmd\": $?"; +} diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c index a94d6e2ad8..aee7f7eeb0 100644 --- a/lib/erl_interface/src/misc/ei_printterm.c +++ b/lib/erl_interface/src/misc/ei_printterm.c @@ -124,6 +124,7 @@ static int print_term(FILE* fp, ei_x_buff* x, erlang_fun fun; double d; long l; + const char* delim; int tindex = *index; @@ -240,41 +241,47 @@ static int print_term(FILE* fp, ei_x_buff* x, m = BINPRINTSIZE; else m = l; - --m; + delim = ""; for (i = 0; i < m; ++i) { - ch_written += xprintf(fp, x, "%d,", p[i]); + ch_written += xprintf(fp, x, "%s%u", delim, (unsigned char)p[i]); + delim = ","; } - ch_written += xprintf(fp, x, "%d", p[i]); if (l > BINPRINTSIZE) ch_written += xprintf(fp, x, ",..."); xputc('>', fp, x); ++ch_written; ei_free(p); break; case ERL_BIT_BINARY_EXT: { - const char* cp; + const unsigned char* cp; size_t bits; unsigned int bitoffs; int trunc = 0; - if (ei_decode_bitstring(buf, index, &cp, &bitoffs, &bits) < 0 + if (ei_decode_bitstring(buf, index, (const char**)&cp, &bitoffs, &bits) < 0 || bitoffs != 0) { goto err; } ch_written += xprintf(fp, x, "#Bits<"); - m = (bits+7) / 8; - if (m > BINPRINTSIZE) { + if ((bits+7) / 8 > BINPRINTSIZE) { m = BINPRINTSIZE; trunc = 1; } - --m; + else + m = bits / 8; + + delim = ""; for (i = 0; i < m; ++i) { - ch_written += xprintf(fp, x, "%d,", cp[i]); + ch_written += xprintf(fp, x, "%s%u", delim, cp[i]); + delim = ","; } - ch_written += xprintf(fp, x, "%d", cp[i]); if (trunc) ch_written += xprintf(fp, x, ",..."); - else if (bits % 8 != 0) - ch_written += xprintf(fp, x, ":%u", (unsigned)(bits % 8)); + else { + bits %= 8; + if (bits) + ch_written += xprintf(fp, x, "%s%u:%u", delim, + (cp[i] >> (8-bits)), bits); + } xputc('>', fp, x); ++ch_written; break; } diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl index f2a2548183..8a35b22ae5 100644 --- a/lib/erl_interface/test/ei_print_SUITE.erl +++ b/lib/erl_interface/test/ei_print_SUITE.erl @@ -27,7 +27,7 @@ -export([all/0, suite/0, init_per_testcase/2, atoms/1, tuples/1, lists/1, strings/1, - maps/1, funs/1]). + maps/1, funs/1, binaries/1, bitstrings/1]). -import(runner, [get_term/1]). @@ -38,7 +38,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [atoms, tuples, lists, strings, maps, funs]. + [atoms, tuples, lists, strings, maps, funs, binaries, bitstrings]. init_per_testcase(Case, Config) -> runner:init_per_testcase(?MODULE, Case, Config). @@ -163,3 +163,44 @@ funs(Config) -> runner:recv_eot(P), ok. + +binaries(Config) -> + P = runner:start(Config, ?binaries), + + "#Bin<>" = send_term_get_printed(P, <<>>), + "#Bin<1,2,3>" = send_term_get_printed(P, <<1,2,3>>), + "#Bin<0,127,128,255>" = send_term_get_printed(P, <<0,127,128,255>>), + Bin30 = <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30>>, + "#Bin<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30>" + = send_term_get_printed(P, Bin30), + "#Bin<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,...>" + = send_term_get_printed(P, <<Bin30/binary,31>>), + + runner:recv_eot(P), + ok. + +bitstrings(Config) -> + P = runner:start(Config, ?bitstrings), + + "#Bits<1:1>" = send_term_get_printed(P, <<1:1>>), + "#Bits<123:7>" = send_term_get_printed(P, <<123:7>>), + "#Bits<1,2,3:4>" = send_term_get_printed(P, <<1,2,3:4>>), + "#Bits<0,127,128,255,126:7>" = send_term_get_printed(P, <<0,127,128,255,-2:7>>), + Bits30 = <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29,30:5>>, + "#Bits<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30:5>" + = send_term_get_printed(P, Bits30), + "#Bin<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,241>" + = send_term_get_printed(P, <<Bits30/bits,1:3>>), + "#Bits<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,240,...>" + = send_term_get_printed(P, <<Bits30/bits,1:4>>), + + runner:recv_eot(P), + ok. + + + +send_term_get_printed(Port, Term) -> + Port ! {self(), {command, term_to_binary(Term)}}, + {term, String} = get_term(Port), + String. diff --git a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c index 0e2b24e45a..27d4153250 100644 --- a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c +++ b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c @@ -288,3 +288,64 @@ TESTCASE(funs) report(1); } + + +TESTCASE(binaries) +{ + char *buf; + long len; + int err, n, index; + ei_x_buff x; + + ei_init(); + + for (n = 5; n; n--) { + buf = read_packet(NULL); + + index = 0; + err = ei_decode_version(buf, &index, NULL); + if (err != 0) + fail1("ei_decode_version returned %d", err); + err = ei_decode_binary(buf, &index, NULL, &len); + if (err != 0) + fail1("ei_decode_binary returned %d", err); + + ei_x_new(&x); + ei_x_append_buf(&x, buf, index); + send_printed_buf(&x); + ei_x_free(&x); + + free_packet(buf); + } + report(1); +} + +TESTCASE(bitstrings) +{ + char *buf; + long len; + int err, n, index; + ei_x_buff x; + + ei_init(); + + for (n = 7; n; n--) { + buf = read_packet(NULL); + + index = 0; + err = ei_decode_version(buf, &index, NULL); + if (err != 0) + fail1("ei_decode_version returned %d", err); + err = ei_decode_bitstring(buf, &index, NULL, NULL, NULL); + if (err != 0) + fail1("ei_decode_bitstring returned %d", err); + + ei_x_new(&x); + ei_x_append_buf(&x, buf, index); + send_printed_buf(&x); + ei_x_free(&x); + + free_packet(buf); + } + report(1); +} |