aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.beambin3808 -> 3908 bytes
-rw-r--r--erts/configure.in9
-rw-r--r--erts/emulator/Makefile.in4
-rw-r--r--erts/emulator/beam/beam_load.c6
-rw-r--r--erts/emulator/beam/copy.c5
-rw-r--r--erts/emulator/beam/erl_alloc.types5
-rw-r--r--erts/emulator/beam/erl_mtrace.c7
-rw-r--r--erts/emulator/beam/erl_nif.c20
-rw-r--r--erts/emulator/beam/erl_term.h15
-rw-r--r--erts/emulator/drivers/common/inet_drv.c13
-rw-r--r--erts/emulator/hipe/elf64ppc.x2
-rw-r--r--erts/emulator/hipe/hipe_bif0.c41
-rw-r--r--erts/emulator/hipe/hipe_bif1.c4
-rw-r--r--erts/emulator/hipe/hipe_load.c2
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c6
-rw-r--r--erts/emulator/hipe/hipe_module.c4
-rw-r--r--erts/emulator/hipe/hipe_process.h2
-rw-r--r--erts/emulator/hipe/hipe_stack.c8
-rw-r--r--erts/emulator/hipe/hipe_x86_signal.c2
-rw-r--r--erts/etc/common/erlexec.c2
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c9
-rw-r--r--lib/erl_interface/src/prog/erl_call.c3
-rw-r--r--lib/hipe/arm/hipe_arm_assemble.erl2
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl5
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl20
-rw-r--r--lib/hipe/llvm/hipe_llvm_merge.erl2
-rw-r--r--lib/hipe/misc/hipe_consttab.erl15
-rw-r--r--lib/hipe/misc/hipe_pack_constants.erl12
-rw-r--r--lib/hipe/ppc/hipe_ppc_assemble.erl2
-rw-r--r--lib/hipe/regalloc/hipe_coalescing_regalloc.erl2
-rw-r--r--lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl6
-rw-r--r--lib/hipe/regalloc/hipe_optimistic_regalloc.erl2
-rw-r--r--lib/hipe/sparc/hipe_sparc_assemble.erl2
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl42
-rw-r--r--lib/hipe/x86/hipe_x86_assemble.erl2
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_client.c4
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c4
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c4
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/c_server.c4
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c4
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml17
-rw-r--r--lib/kernel/doc/src/inet.xml2
-rw-r--r--lib/kernel/src/kernel.erl244
43 files changed, 352 insertions, 214 deletions
diff --git a/bootstrap/lib/kernel/ebin/kernel.beam b/bootstrap/lib/kernel/ebin/kernel.beam
index 3314ad6e0b..5cd4a762ed 100644
--- a/bootstrap/lib/kernel/ebin/kernel.beam
+++ b/bootstrap/lib/kernel/ebin/kernel.beam
Binary files differ
diff --git a/erts/configure.in b/erts/configure.in
index 1c4a3e90ef..d7d56d45b6 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -622,7 +622,7 @@ case $chk_arch_ in
powerpc) ARCH=ppc;;
ppc) ARCH=ppc;;
ppc64) ARCH=ppc64;;
- ppc64le) ARCH=ppc64;;
+ ppc64le) ARCH=ppc64le;;
"Power Macintosh") ARCH=ppc;;
armv5b) ARCH=arm;;
armv5teb) ARCH=arm;;
@@ -2836,9 +2836,10 @@ if test X${enable_hipe} = Xyes && test X$ARCH = Xamd64; then
saved_LDFLAGS=$LDFLAGS
LDFLAGS="-no-pie $LDFLAGS"
AC_TRY_LINK(,, [],
- [AC_MSG_WARN([Linked does not accept option -no-pie])
- LDFLAGS=$saved_LDFLAGS])])
-
+ [LDFLAGS="-fno-PIE $saved_LDFLAGS"
+ AC_TRY_LINK(,, [],
+ [AC_MSG_WARN([Linked does not accept option -no-pie nor -fno-PIE])
+ LDFLAGS=$saved_LDFLAGS])])])
fi
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 18fd7f320b..7ea0111e59 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -656,6 +656,10 @@ generate: $(TTF_DIR)/GENERATED $(PRELOAD_SRC)
$(TTF_DIR)/GENERATED: $(GENERATE)
$(gen_verbose)echo $? >$(TTF_DIR)/GENERATED
+
+# Regenerate if Makefile has changed
+$(GENERATE): $(TARGET)/Makefile
+
endif
$(TARGET)/erlang_dtrace.h: beam/erlang_dtrace.d
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 48206a75a8..6eea963016 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -6321,7 +6321,7 @@ erts_make_stub_module(Process* p, Eterm hipe_magic_bin, Eterm Beam, Eterm Info)
*/
magic = erts_alloc_loader_state();
stp = ERTS_MAGIC_BIN_DATA(magic);
- hipe_code = erts_alloc(ERTS_ALC_T_HIPE, sizeof(*hipe_code));
+ hipe_code = erts_alloc(ERTS_ALC_T_HIPE_LL, sizeof(*hipe_code));
if (!is_internal_magic_ref(hipe_magic_bin) ||
!(hipe_magic = erts_magic_ref2bin(hipe_magic_bin),
@@ -6556,7 +6556,7 @@ erts_make_stub_module(Process* p, Eterm hipe_magic_bin, Eterm Beam, Eterm Info)
}
error:
- erts_free(ERTS_ALC_T_HIPE, hipe_code);
+ erts_free(ERTS_ALC_T_HIPE_LL, hipe_code);
erts_free_aligned_binary_bytes(temp_alloc);
free_loader_state(magic);
BIF_ERROR(p, BADARG);
@@ -6583,7 +6583,7 @@ int erts_commit_hipe_patch_load(Eterm hipe_magic_bin)
/*
* Initialise HiPE module
*/
- hipe_code = erts_alloc(ERTS_ALC_T_HIPE, sizeof(*hipe_code));
+ hipe_code = erts_alloc(ERTS_ALC_T_HIPE_LL, sizeof(*hipe_code));
hipe_code->text_segment = hipe_stp->text_segment;
hipe_code->text_segment_size = hipe_stp->text_segment_size;
hipe_code->data_segment = hipe_stp->data_segment;
diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c
index e567eabc82..264ba89e8b 100644
--- a/erts/emulator/beam/copy.c
+++ b/erts/emulator/beam/copy.c
@@ -286,11 +286,6 @@ do { \
(dst) = result; \
} while(0)
-#define BOXED_VISITED_MASK ((Eterm) 3)
-#define BOXED_VISITED ((Eterm) 1)
-#define BOXED_SHARED_UNPROCESSED ((Eterm) 2)
-#define BOXED_SHARED_PROCESSED ((Eterm) 3)
-
#define COUNT_OFF_HEAP (0)
/*
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index 32f84c8593..43f43f9034 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -351,8 +351,9 @@ type SL_MPATHS SHORT_LIVED SYSTEM sl_migration_paths
+if hipe
-# Currently most hipe code use this type.
-type HIPE SYSTEM SYSTEM hipe_data
+type HIPE_LL LONG_LIVED SYSTEM hipe_long_lived
+type HIPE_SL SHORT_LIVED SYSTEM hipe_short_lived
+type HIPE_STK STANDARD SYSTEM hipe_nstack
+if exec_alloc
type HIPE_EXEC EXEC CODE hipe_code
diff --git a/erts/emulator/beam/erl_mtrace.c b/erts/emulator/beam/erl_mtrace.c
index e275867928..bb6f8660f1 100644
--- a/erts/emulator/beam/erl_mtrace.c
+++ b/erts/emulator/beam/erl_mtrace.c
@@ -572,7 +572,7 @@ void erts_mtrace_pre_init(void)
void erts_mtrace_init(char *receiver, char *nodename)
{
- char hostname[MAXHOSTNAMELEN];
+ char hostname[MAXHOSTNAMELEN + 1];
char pid[21]; /* enough for a 64 bit number */
socket_desc = ERTS_SOCK_INVALID_SOCKET;
@@ -613,9 +613,10 @@ void erts_mtrace_init(char *receiver, char *nodename)
}
tracep = trace_buffer;
endp = trace_buffer + TRACE_BUF_SZ;
- if (erts_sock_gethostname(hostname, MAXHOSTNAMELEN) != 0)
+ /* gethostname requires that the len is max(hostname) + 1 */
+ if (erts_sock_gethostname(hostname, MAXHOSTNAMELEN + 1) != 0)
hostname[0] = '\0';
- hostname[MAXHOSTNAMELEN-1] = '\0';
+ hostname[MAXHOSTNAMELEN] = '\0';
sys_get_pid(pid, sizeof(pid));
write_trace_header(nodename ? nodename : "", pid, hostname);
erts_mtrace_update_heap_size();
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index e6da4c1a76..63a4a997da 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -998,16 +998,14 @@ int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
byte* raw_ptr;
}u;
- if (is_boxed(bin_term) && *binary_val(bin_term) == HEADER_SUB_BIN) {
- ErlSubBin* sb = (ErlSubBin*) binary_val(bin_term);
- if (sb->is_writable) {
- ProcBin* pb = (ProcBin*) binary_val(sb->orig);
- ASSERT(pb->thing_word == HEADER_PROC_BIN);
- if (pb->flags) {
- erts_emasculate_writable_binary(pb);
- sb->is_writable = 0;
- }
- }
+ if (is_binary(bin_term)) {
+ ProcBin *pb = (ProcBin*) binary_val(bin_term);
+ if (pb->thing_word == HEADER_SUB_BIN) {
+ ErlSubBin* sb = (ErlSubBin*) pb;
+ pb = (ProcBin*) binary_val(sb->orig);
+ }
+ if (pb->thing_word == HEADER_PROC_BIN && pb->flags)
+ erts_emasculate_writable_binary(pb);
}
u.tmp = NULL;
bin->data = erts_get_aligned_binary_bytes_extra(bin_term, &u.raw_ptr, allocator,
@@ -1024,7 +1022,7 @@ int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
bin->bin_term = bin_term;
bin->size = binary_size(bin_term);
bin->ref_bin = NULL;
- ADD_READONLY_CHECK(env, bin->data, bin->size);
+ ADD_READONLY_CHECK(env, bin->data, bin->size);
return 1;
}
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index a602a8f7c6..097d580d99 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -873,6 +873,12 @@ typedef union {
ErtsORefThing o;
} ErtsRefThing;
+/* for copy sharing */
+#define BOXED_VISITED_MASK ((Eterm) 3)
+#define BOXED_VISITED ((Eterm) 1)
+#define BOXED_SHARED_UNPROCESSED ((Eterm) 2)
+#define BOXED_SHARED_PROCESSED ((Eterm) 3)
+
#define ERTS_REF_THING_SIZE (sizeof(ErtsORefThing)/sizeof(Uint))
#define ERTS_MAGIC_REF_THING_SIZE (sizeof(ErtsMRefThing)/sizeof(Uint))
#define ERTS_MAX_INTERNAL_REF_SIZE (sizeof(ErtsRefThing)/sizeof(Uint))
@@ -888,9 +894,14 @@ typedef union {
# define is_ref_thing_header(x) ((x) == ERTS_REF_THING_HEADER)
-#define is_ordinary_ref_thing(x) \
- (ASSERT(is_ref_thing_header(*((Eterm *)(x)))), \
+#ifdef SHCOPY
+#define is_ordinary_ref_thing(x) \
+ (((ErtsRefThing *) (x))->o.marker == ERTS_ORDINARY_REF_MARKER)
+#else
+#define is_ordinary_ref_thing(x) \
+ (ASSERT(is_ref_thing_header((*((Eterm *)(x))) & ~BOXED_VISITED_MASK)), \
((ErtsRefThing *) (x))->o.marker == ERTS_ORDINARY_REF_MARKER)
+#endif
#define is_magic_ref_thing(x) \
(!is_ordinary_ref_thing((x)))
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 278abe4e00..0fe5183b42 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -8345,10 +8345,10 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)
return (ErlDrvData)desc;
}
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
+/* MAXHOSTNAMELEN could be 64 or 255 depending
+on the platform. Instead, use INET_MAXHOSTNAMELEN
+which is always 255 across all platforms */
+#define INET_MAXHOSTNAMELEN 255
/*
** common TCP/UDP/SCTP control command
@@ -8525,13 +8525,14 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
}
case INET_REQ_GETHOSTNAME: { /* get host name */
- char tbuf[MAXHOSTNAMELEN];
+ char tbuf[INET_MAXHOSTNAMELEN + 1];
DEBUGF(("inet_ctl(%ld): GETHOSTNAME\r\n", (long)desc->port));
if (len != 0)
return ctl_error(EINVAL, rbuf, rsize);
- if (IS_SOCKET_ERROR(sock_hostname(tbuf, MAXHOSTNAMELEN)))
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (IS_SOCKET_ERROR(sock_hostname(tbuf, INET_MAXHOSTNAMELEN + 1)))
return ctl_error(sock_errno(), rbuf, rsize);
return ctl_reply(INET_REP_OK, tbuf, strlen(tbuf), rbuf, rsize);
}
diff --git a/erts/emulator/hipe/elf64ppc.x b/erts/emulator/hipe/elf64ppc.x
index 46d2632970..bb14a6cd29 100644
--- a/erts/emulator/hipe/elf64ppc.x
+++ b/erts/emulator/hipe/elf64ppc.x
@@ -28,7 +28,7 @@ SEARCH_DIR("/mnt/archive/cross-ppc64/ppc64-unknown-linux/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
- PROVIDE (__executable_start = 0x0180000); . = 0x01800000 + SIZEOF_HEADERS;
+ PROVIDE (__executable_start = 0x01800000); . = 0x01800000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index 688c82ab7a..8b420b9e9b 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -447,6 +447,7 @@ BIF_RETTYPE hipe_bifs_alloc_data_3(BIF_ALIST_3)
{
Uint align;
HipeLoaderState *stp;
+ void *aligned_block;
if (is_not_small(BIF_ARG_1) || is_not_small(BIF_ARG_2) ||
(!(stp = get_loader_state(BIF_ARG_3))) ||
@@ -459,18 +460,14 @@ BIF_RETTYPE hipe_bifs_alloc_data_3(BIF_ALIST_3)
stp->data_segment_size = unsigned_val(BIF_ARG_2);
if (stp->data_segment_size == 0)
BIF_RET(make_small(0));
- stp->data_segment = erts_alloc(ERTS_ALC_T_HIPE, stp->data_segment_size);
- if ((unsigned long)stp->data_segment & (align-1)) {
- fprintf(stderr, "%s: erts_alloc(%lu) returned %p which is not %lu-byte "
- "aligned\r\n",
- __FUNCTION__, (unsigned long)stp->data_segment_size,
- stp->data_segment, (unsigned long)align);
- erts_free(ERTS_ALC_T_HIPE, stp->data_segment);
- stp->data_segment = NULL;
- stp->data_segment_size = 0;
- BIF_ERROR(BIF_P, EXC_NOTSUP);
- }
- BIF_RET(address_to_term(stp->data_segment, BIF_P));
+
+ stp->data_segment_size += align-1; /* Make room to align the pointer */
+ stp->data_segment = erts_alloc(ERTS_ALC_T_HIPE_LL, stp->data_segment_size);
+
+ /* Align the pointer */
+ aligned_block = (void*)((UWord)(stp->data_segment + align - 1)
+ & ~(UWord)(align-1));
+ BIF_RET(address_to_term(aligned_block, BIF_P));
}
/*
@@ -545,7 +542,7 @@ static void init_const_term_table(void)
f.meta_alloc = (HMALLOC_FUN) erts_alloc;
f.meta_free = (HMFREE_FUN) erts_free;
f.meta_print = (HMPRINT_FUN) erts_print;
- hash_init(ERTS_ALC_T_HIPE, &const_term_table, "const_term_table", 97, f);
+ hash_init(ERTS_ALC_T_HIPE_LL, &const_term_table, "const_term_table", 97, f);
}
BIF_RETTYPE hipe_bifs_merge_term_1(BIF_ALIST_1)
@@ -859,7 +856,7 @@ static void init_primop_table(void)
f.meta_free = (HMFREE_FUN) erts_free;
f.meta_print = (HMPRINT_FUN) erts_print;
- hash_init(ERTS_ALC_T_HIPE, &primop_table, "primop_table", 50, f);
+ hash_init(ERTS_ALC_T_HIPE_LL, &primop_table, "primop_table", 50, f);
for (i = 0; i < sizeof(primops)/sizeof(primops[0]); ++i)
hash_put(&primop_table, &primops[i]);
@@ -1094,7 +1091,7 @@ static void mod2mfa_tab_init(void)
f.meta_free = (HMFREE_FUN) erts_free;
f.meta_print = (HMPRINT_FUN) erts_print;
- hash_init(ERTS_ALC_T_HIPE, &mod2mfa_tab, "mod2mfa_tab", 50, f);
+ hash_init(ERTS_ALC_T_HIPE_LL, &mod2mfa_tab, "mod2mfa_tab", 50, f);
}
static struct hipe_mfa_info* mod2mfa_get(Module* modp)
@@ -1172,7 +1169,7 @@ struct hipe_mfa_info* mod2mfa_get_safe(Module* modp)
static struct hipe_mfa_info **hipe_mfa_info_table_alloc_bucket(unsigned int size)
{
unsigned long nbytes = size * sizeof(struct hipe_mfa_info*);
- struct hipe_mfa_info **bucket = erts_alloc(ERTS_ALC_T_HIPE, nbytes);
+ struct hipe_mfa_info **bucket = erts_alloc(ERTS_ALC_T_HIPE_LL, nbytes);
sys_memzero(bucket, nbytes);
return bucket;
}
@@ -1201,14 +1198,14 @@ static void hipe_mfa_info_table_grow(void)
b = next;
}
}
- erts_free(ERTS_ALC_T_HIPE, old_bucket);
+ erts_free(ERTS_ALC_T_HIPE_LL, old_bucket);
}
static struct hipe_mfa_info *hipe_mfa_info_table_alloc(Eterm m, Eterm f, unsigned int arity)
{
struct hipe_mfa_info *res;
- res = (struct hipe_mfa_info*)erts_alloc(ERTS_ALC_T_HIPE, sizeof(*res));
+ res = (struct hipe_mfa_info*)erts_alloc(ERTS_ALC_T_HIPE_LL, sizeof(*res));
res->m = m;
res->f = f;
res->a = arity;
@@ -1547,7 +1544,7 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
hipe_mfa_info_table_rwlock();
callee_mfa = hipe_mfa_info_table_put_rwlocked(callee.mod, callee.fun, callee.ari);
- ref = erts_alloc(ERTS_ALC_T_HIPE, sizeof(struct hipe_ref));
+ ref = erts_alloc(ERTS_ALC_T_HIPE_LL, sizeof(struct hipe_ref));
ref->address = address;
#if defined(__arm__) || defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__)
ref->trampoline = trampoline;
@@ -1618,7 +1615,7 @@ static void purge_mfa(struct hipe_mfa_info* p)
ASSERT(p->is_stub);
remove_mfa_info(p);
hipe_free_native_stub(p->remote_address);
- erts_free(ERTS_ALC_T_HIPE, p);
+ erts_free(ERTS_ALC_T_HIPE_LL, p);
}
/* Called by init:restart after unloading all hipe compiled modules
@@ -1643,7 +1640,7 @@ static void hipe_purge_all_refs(void)
bucket[i] = mfa->bucket.next;
hash_erase(&mod2mfa_tab, mfa);
- erts_free(ERTS_ALC_T_HIPE, mfa);
+ erts_free(ERTS_ALC_T_HIPE_LL, mfa);
}
}
hipe_mfa_info_table.used = 0;
@@ -1717,7 +1714,7 @@ void hipe_purge_refs(struct hipe_ref* first_ref, Eterm caller_module,
}
ref = ref->next_from_modi;
- erts_free(ERTS_ALC_T_HIPE, free_ref);
+ erts_free(ERTS_ALC_T_HIPE_LL, free_ref);
}
}
diff --git a/erts/emulator/hipe/hipe_bif1.c b/erts/emulator/hipe/hipe_bif1.c
index 0c66eb6abe..0ba0fa5172 100644
--- a/erts/emulator/hipe/hipe_bif1.c
+++ b/erts/emulator/hipe/hipe_bif1.c
@@ -50,7 +50,7 @@ BIF_RETTYPE hipe_bifs_call_count_on_1(BIF_ALIST_1)
BIF_ERROR(BIF_P, BADARG);
if (pc[0] == BeamOpCode(op_hipe_call_count))
BIF_RET(NIL);
- hcc = erts_alloc(ERTS_ALC_T_HIPE, sizeof(*hcc));
+ hcc = erts_alloc(ERTS_ALC_T_HIPE_SL, sizeof(*hcc));
hcc->count = 0;
hcc->opcode = pc[0];
pc[-4] = (Eterm)hcc;
@@ -74,7 +74,7 @@ BIF_RETTYPE hipe_bifs_call_count_off_1(BIF_ALIST_1)
count = hcc->count;
pc[0] = hcc->opcode;
pc[-4] = (Eterm)NULL;
- erts_free(ERTS_ALC_T_HIPE, hcc);
+ erts_free(ERTS_ALC_T_HIPE_SL, hcc);
BIF_RET(make_small(count));
}
diff --git a/erts/emulator/hipe/hipe_load.c b/erts/emulator/hipe/hipe_load.c
index 87c5004d2b..0b53880628 100644
--- a/erts/emulator/hipe/hipe_load.c
+++ b/erts/emulator/hipe/hipe_load.c
@@ -45,7 +45,7 @@ void hipe_free_loader_state(HipeLoaderState *stp)
stp->text_segment_size = 0;
if (stp->data_segment)
- erts_free(ERTS_ALC_T_HIPE, stp->data_segment);
+ erts_free(ERTS_ALC_T_HIPE_LL, stp->data_segment);
stp->data_segment = NULL;
stp->data_segment_size = 0;
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index f11223d8b0..712f65f629 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -664,7 +664,7 @@ void hipe_inc_nstack(Process *p)
{
unsigned old_size = p->hipe.nstend - p->hipe.nstack;
unsigned new_size = hipe_next_nstack_size(old_size);
- Eterm *new_nstack = erts_alloc(ERTS_ALC_T_HIPE, new_size*sizeof(Eterm));
+ Eterm *new_nstack = erts_alloc(ERTS_ALC_T_HIPE_STK, new_size*sizeof(Eterm));
unsigned used_size = p->hipe.nstend - p->hipe.nsp;
sys_memcpy(new_nstack+new_size-used_size, p->hipe.nsp, used_size*sizeof(Eterm));
@@ -673,7 +673,7 @@ void hipe_inc_nstack(Process *p)
if (p->hipe.nstblacklim)
p->hipe.nstblacklim = new_nstack + new_size - (p->hipe.nstend - p->hipe.nstblacklim);
if (p->hipe.nstack)
- erts_free(ERTS_ALC_T_HIPE, p->hipe.nstack);
+ erts_free(ERTS_ALC_T_HIPE_STK, p->hipe.nstack);
p->hipe.nstack = new_nstack;
p->hipe.nstend = new_nstack + new_size;
p->hipe.nsp = new_nstack + new_size - used_size;
@@ -683,7 +683,7 @@ void hipe_inc_nstack(Process *p)
void hipe_empty_nstack(Process *p)
{
if (p->hipe.nstack) {
- erts_free(ERTS_ALC_T_HIPE, p->hipe.nstack);
+ erts_free(ERTS_ALC_T_HIPE_STK, p->hipe.nstack);
}
p->hipe.nstgraylim = NULL;
p->hipe.nsp = NULL;
diff --git a/erts/emulator/hipe/hipe_module.c b/erts/emulator/hipe/hipe_module.c
index 469f077dd2..2e99a30556 100644
--- a/erts/emulator/hipe/hipe_module.c
+++ b/erts/emulator/hipe/hipe_module.c
@@ -29,7 +29,7 @@ void hipe_free_module(HipeModule *mod)
{
hipe_free_code(mod->text_segment, mod->text_segment_size);
if (mod->data_segment) /* Some modules lack data segments */
- erts_free(ERTS_ALC_T_HIPE, mod->data_segment);
+ erts_free(ERTS_ALC_T_HIPE_LL, mod->data_segment);
- erts_free(ERTS_ALC_T_HIPE, mod);
+ erts_free(ERTS_ALC_T_HIPE_LL, mod);
}
diff --git a/erts/emulator/hipe/hipe_process.h b/erts/emulator/hipe/hipe_process.h
index a8d5972280..36b6ffc021 100644
--- a/erts/emulator/hipe/hipe_process.h
+++ b/erts/emulator/hipe/hipe_process.h
@@ -79,7 +79,7 @@ static __inline__ void hipe_init_process(struct hipe_process_state *p)
static __inline__ void hipe_delete_process(struct hipe_process_state *p)
{
if (p->nstack)
- erts_free(ERTS_ALC_T_HIPE, (void*)p->nstack);
+ erts_free(ERTS_ALC_T_HIPE_STK, (void*)p->nstack);
}
#ifdef ERTS_SMP
diff --git a/erts/emulator/hipe/hipe_stack.c b/erts/emulator/hipe/hipe_stack.c
index b80e44bc37..d0f0407489 100644
--- a/erts/emulator/hipe/hipe_stack.c
+++ b/erts/emulator/hipe/hipe_stack.c
@@ -46,7 +46,7 @@ struct hipe_sdesc_table hipe_sdesc_table;
static struct hipe_sdesc **alloc_bucket(unsigned int size)
{
unsigned long nbytes = size * sizeof(struct hipe_sdesc*);
- struct hipe_sdesc **bucket = erts_alloc(ERTS_ALC_T_HIPE, nbytes);
+ struct hipe_sdesc **bucket = erts_alloc(ERTS_ALC_T_HIPE_LL, nbytes);
sys_memzero(bucket, nbytes);
return bucket;
}
@@ -75,7 +75,7 @@ static void hipe_grow_sdesc_table(void)
b = next;
}
}
- erts_free(ERTS_ALC_T_HIPE, old_bucket);
+ erts_free(ERTS_ALC_T_HIPE_LL, old_bucket);
}
struct hipe_sdesc *hipe_put_sdesc(struct hipe_sdesc *sdesc)
@@ -121,7 +121,7 @@ void hipe_destruct_sdesc(struct hipe_sdesc *sdesc)
free_me = ErtsContainerStruct(sdesc, struct hipe_sdesc_with_exnra, sdesc);
else
free_me = sdesc;
- erts_free(ERTS_ALC_T_HIPE, free_me);
+ erts_free(ERTS_ALC_T_HIPE_LL, free_me);
}
void hipe_init_sdesc_table(struct hipe_sdesc *sdesc)
@@ -199,7 +199,7 @@ struct hipe_sdesc *hipe_decode_sdesc(Eterm arg)
? offsetof(struct hipe_sdesc_with_exnra, sdesc.livebits)
: offsetof(struct hipe_sdesc, livebits))
+ livebitswords * sizeof(int);
- p = erts_alloc(ERTS_ALC_T_HIPE, sdescbytes);
+ p = erts_alloc(ERTS_ALC_T_HIPE_LL, sdescbytes);
/* If we have an exception handler use the
special sdesc_with_exnra structure. */
if (exnra) {
diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c
index 1a34ce786c..b24b9148a2 100644
--- a/erts/emulator/hipe/hipe_x86_signal.c
+++ b/erts/emulator/hipe/hipe_x86_signal.c
@@ -267,7 +267,7 @@ void hipe_thread_signal_init(void)
{
/* Stack don't really need to be cache aligned.
We use it to suppress false leak report from valgrind */
- hipe_sigaltstack(erts_alloc_permanent_cache_aligned(ERTS_ALC_T_HIPE, SIGSTKSZ));
+ hipe_sigaltstack(erts_alloc_permanent_cache_aligned(ERTS_ALC_T_HIPE_LL, SIGSTKSZ));
}
#endif
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 2b2e0e480a..ee59759940 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -1044,7 +1044,7 @@ int main(int argc, char **argv)
start_epmd(epmd_prog);
#if (! defined(__WIN32__)) && defined(DEBUG)
- if (start_detached) {
+ if (start_detached && get_env("ERL_CONSOLE_MODE")) {
/* Start the emulator within an xterm.
* Move up all arguments and insert
* "xterm -e " first.
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index c193fd804a..27b919c093 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -497,7 +497,8 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name,
}
#endif /* _REENTRANT */
- if (gethostname(thishostname, EI_MAXHOSTNAMELEN) == -1) {
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (gethostname(thishostname, EI_MAXHOSTNAMELEN+1) == -1) {
#ifdef __WIN32__
EI_TRACE_ERR1("ei_connect_init","Failed to get host name: %d",
WSAGetLastError());
@@ -613,7 +614,8 @@ int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
hp = ei_gethostbyname_r(hostname,&host,buffer,1024,&ei_h_errno);
if (hp == NULL) {
char thishostname[EI_MAXHOSTNAMELEN+1];
- if (gethostname(thishostname,EI_MAXHOSTNAMELEN) < 0) {
+ /* gethostname requies len to be max(hostname) + 1*/
+ if (gethostname(thishostname,EI_MAXHOSTNAMELEN+1) < 0) {
EI_TRACE_ERR0("ei_connect_tmo",
"Failed to get name of this host");
erl_errno = EHOSTUNREACH;
@@ -636,7 +638,8 @@ int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
#else /* __WIN32__ */
if ((hp = ei_gethostbyname(hostname)) == NULL) {
char thishostname[EI_MAXHOSTNAMELEN+1];
- if (gethostname(thishostname,EI_MAXHOSTNAMELEN) < 0) {
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (gethostname(thishostname,EI_MAXHOSTNAMELEN+1) < 0) {
EI_TRACE_ERR1("ei_connect_tmo",
"Failed to get name of this host: %d",
WSAGetLastError());
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index d233ed26a2..0b09d412db 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -325,7 +325,8 @@ int erl_call(int argc, char **argv)
initWinSock();
#endif
- if (gethostname(h_hostname, EI_MAXHOSTNAMELEN) < 0) {
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (gethostname(h_hostname, EI_MAXHOSTNAMELEN+1) < 0) {
fprintf(stderr,"erl_call: failed to get host name: %d\n", errno);
exit(1);
}
diff --git a/lib/hipe/arm/hipe_arm_assemble.erl b/lib/hipe/arm/hipe_arm_assemble.erl
index 713c148742..9aa730afa9 100644
--- a/lib/hipe/arm/hipe_arm_assemble.erl
+++ b/lib/hipe/arm/hipe_arm_assemble.erl
@@ -31,7 +31,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, 4),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap), Options),
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 8c96e60229..9321750d44 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -2029,17 +2029,14 @@ arith_rem(Min1, Max1, Min2, Max2) ->
Min1_geq_zero = infinity_geq(Min1, 0),
Max1_leq_zero = infinity_geq(0, Max1),
Max_range2 = infinity_max([infinity_abs(Min2), infinity_abs(Max2)]),
- Max_range2_leq_zero = infinity_geq(0, Max_range2),
- New_min =
+ New_min =
if Min1_geq_zero -> 0;
Max_range2 =:= 0 -> 0;
- Max_range2_leq_zero -> infinity_add(Max_range2, 1);
true -> infinity_add(infinity_inv(Max_range2), 1)
end,
New_max =
if Max1_leq_zero -> 0;
Max_range2 =:= 0 -> 0;
- Max_range2_leq_zero -> infinity_add(infinity_inv(Max_range2), -1);
true -> infinity_add(Max_range2, -1)
end,
{New_min, New_max}.
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index b884132327..287b1c80fe 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -392,14 +392,17 @@ widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
-spec analyse_call(#icode_call{}, call_fun()) -> #icode_call{}.
analyse_call(Call, LookupFun) ->
+ Args = hipe_icode:args(Call),
+ Fun = hipe_icode:call_fun(Call),
+ Type = hipe_icode:call_type(Call),
+ %% This call has side-effects (it might call LookupFun which sends messages to
+ %% hipe_icode_coordinator to update the argument ranges of Fun), and must thus
+ %% not be moved into the case statement.
+ DstRanges = analyse_call_or_enter_fun(Fun, Args, Type, LookupFun),
case hipe_icode:call_dstlist(Call) of
[] ->
Call;
Dsts ->
- Args = hipe_icode:args(Call),
- Fun = hipe_icode:call_fun(Call),
- Type = hipe_icode:call_type(Call),
- DstRanges = analyse_call_or_enter_fun(Fun, Args, Type, LookupFun),
NewDefs = [update_info(Var, R) || {Var,R} <- lists:zip(Dsts, DstRanges)],
hipe_icode:subst_defines(lists:zip(Dsts, NewDefs), Call)
end.
@@ -1306,16 +1309,15 @@ range_rem(Range1, Range2) ->
Min1_geq_zero = inf_geq(Min1, 0),
Max1_leq_zero = inf_geq(0, Max1),
Max_range2 = inf_max([inf_abs(Min2), inf_abs(Max2)]),
- Max_range2_leq_zero = inf_geq(0, Max_range2),
New_min =
if Min1_geq_zero -> 0;
- Max_range2_leq_zero -> Max_range2;
- true -> inf_inv(Max_range2)
+ Max_range2 =:= 0 -> 0;
+ true -> inf_add(inf_inv(Max_range2), 1)
end,
New_max =
if Max1_leq_zero -> 0;
- Max_range2_leq_zero -> inf_inv(Max_range2);
- true -> Max_range2
+ Max_range2 =:= 0 -> 0;
+ true -> inf_add(Max_range2, -1)
end,
range_init({New_min, New_max}, false).
diff --git a/lib/hipe/llvm/hipe_llvm_merge.erl b/lib/hipe/llvm/hipe_llvm_merge.erl
index 6e891ac3b0..58d862fbb2 100644
--- a/lib/hipe/llvm/hipe_llvm_merge.erl
+++ b/lib/hipe/llvm/hipe_llvm_merge.erl
@@ -13,7 +13,7 @@ finalize(CompiledCode, Closures, Exports) ->
Code = [{MFA, [], ConstTab}
|| {MFA, _, _ , ConstTab, _, _} <- CompiledCode1],
{ConstAlign, ConstSize, ConstMap, RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, ?ARCH_REGISTERS:alignment()),
+ hipe_pack_constants:pack_constants(Code),
%% Compute total code size separately as a sanity check for alignment
CodeSize = compute_code_size(CompiledCode1, 0),
%% io:format("Code Size (pre-computed): ~w~n", [CodeSize]),
diff --git a/lib/hipe/misc/hipe_consttab.erl b/lib/hipe/misc/hipe_consttab.erl
index 64e3d3ccaa..741bdb2094 100644
--- a/lib/hipe/misc/hipe_consttab.erl
+++ b/lib/hipe/misc/hipe_consttab.erl
@@ -63,9 +63,7 @@
%% A hipe_consttab is a tuple {Data, ReferedLabels, NextConstLabel}
%% @type hipe_constlbl().
%% An abstract datatype for referring to data.
-%% @type element_type() = byte | word | ctab_array()
-%% @type ctab_array() = {ctab_array, Type::element_type(),
-%% NoElements::pos_integer()}
+%% @type element_type() = byte | word
%% @type block() = [integer() | label_ref()]
%% @type label_ref() = {label, Label::code_label()}
%% @type code_label() = hipe_sparc:label_name() | hipe_x86:label_name()
@@ -110,8 +108,7 @@
-type label_ref() :: {'label', code_label()}.
-type block() :: [hipe_constlbl() | label_ref()].
--type ctab_array() :: {'ctab_array', 'byte' | 'word', pos_integer()}.
--type element_type() :: 'byte' | 'word' | ctab_array().
+-type element_type() :: 'byte' | 'word'.
-type sort_order() :: term(). % XXX: FIXME
@@ -187,7 +184,7 @@ insert_block({ConstTab, RefToLabels, NextLabel}, ElementType, InitList) ->
ReferredLabels = get_labels(InitList, []),
NewRefTo = ReferredLabels ++ RefToLabels,
{NewTa, Id} = insert_const({ConstTab, NewRefTo, NextLabel},
- block, word_size(), false,
+ block, size_of(ElementType), false,
{ElementType,InitList}),
{insert_backrefs(NewTa, Id, ReferredLabels), Id}.
@@ -256,13 +253,9 @@ get_labels([], Acc) ->
%% @spec size_of(element_type()) -> pos_integer()
%% @doc Returns the size in bytes of an element_type.
-%% The is_atom/1 guard in the clause handling arrays
-%% constraints the argument to 'byte' | 'word'
-spec size_of(element_type()) -> pos_integer().
size_of(byte) -> 1;
-size_of(word) -> word_size();
-size_of({ctab_array,S,N}) when is_atom(S), is_integer(N), N > 0 ->
- N * size_of(S).
+size_of(word) -> word_size().
%% @spec decompose({element_type(), block()}) -> [byte()]
%% @doc Turns a block into a list of bytes.
diff --git a/lib/hipe/misc/hipe_pack_constants.erl b/lib/hipe/misc/hipe_pack_constants.erl
index 9dd18bce0f..6736d1f503 100644
--- a/lib/hipe/misc/hipe_pack_constants.erl
+++ b/lib/hipe/misc/hipe_pack_constants.erl
@@ -13,7 +13,7 @@
%% limitations under the License.
-module(hipe_pack_constants).
--export([pack_constants/2, slim_refs/1, slim_constmap/1,
+-export([pack_constants/1, slim_refs/1, slim_constmap/1,
find_const/2, mk_data_relocs/2, slim_sorted_exportmap/3]).
-include("hipe_consttab.hrl").
@@ -37,8 +37,8 @@
-record(pcm_entry, {mfa :: mfa(),
label :: hipe_constlbl(),
- const_num :: const_num(),
- start :: addr(),
+ const_num :: const_num(),
+ start :: addr(),
type :: 0 | 1 | 2,
raw_data :: raw_data()}).
-type pcm_entry() :: #pcm_entry{}.
@@ -53,11 +53,11 @@
%%-----------------------------------------------------------------------------
--spec pack_constants([{mfa(),[_],hipe_consttab()}], ct_alignment()) ->
+-spec pack_constants([{mfa(),[_],hipe_consttab()}]) ->
{ct_alignment(), non_neg_integer(), packed_const_map(), mfa_refs_map()}.
-pack_constants(Data, Align) ->
- pack_constants(Data, 0, Align, 0, [], []).
+pack_constants(Data) ->
+ pack_constants(Data, 0, 1, 0, [], []). % 1 = byte alignment
pack_constants([{MFA,_,ConstTab}|Rest], Size, Align, ConstNo, Acc, Refs) ->
Labels = hipe_consttab:labels(ConstTab),
diff --git a/lib/hipe/ppc/hipe_ppc_assemble.erl b/lib/hipe/ppc/hipe_ppc_assemble.erl
index 66817837df..b0f57e5582 100644
--- a/lib/hipe/ppc/hipe_ppc_assemble.erl
+++ b/lib/hipe/ppc/hipe_ppc_assemble.erl
@@ -32,7 +32,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, hipe_rtl_arch:word_size()),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap), Options),
diff --git a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
index e8ccbec9f1..b8f0a1974c 100644
--- a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
@@ -914,7 +914,7 @@ findCheapest([Node|Nodes], IG, Cost, Cheapest, SpillLimit) ->
%% limit are extremely expensive.
getCost(Node, IG, SpillLimit) ->
- case Node > SpillLimit of
+ case Node >= SpillLimit of
true -> inf;
false -> hipe_ig:node_spill_cost(Node, IG)
end.
diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
index 07aa812f4a..f82d3a2cbc 100644
--- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
@@ -209,8 +209,8 @@ color(IG, Spill, PhysRegs, SpillIx, SpillLimit, NumNodes, Target,
%% Any nodes above the spillimit must be colored first...
MustNotSpill =
- if NumNodes > SpillLimit+1 ->
- sort_on_degree(lists:seq(SpillLimit+1,NumNodes-1) -- Low,IG);
+ if NumNodes > SpillLimit ->
+ sort_on_degree(lists:seq(SpillLimit,NumNodes-1) -- Low,IG);
true -> []
end,
@@ -401,7 +401,7 @@ spill_costs([{N,Info}|Ns], IG, Vis, Spill, SpillLimit, Target) ->
true ->
spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target);
false ->
- if N > SpillLimit ->
+ if N >= SpillLimit ->
spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target);
true ->
[{spill_cost_of(N,Spill)/Deg,N} |
diff --git a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
index b96920cbcf..a019c46b90 100644
--- a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
@@ -1933,7 +1933,7 @@ findCheapest([Node|Nodes], IG, Cost, Cheapest, SpillLimit) ->
%% limit are extremely expensive.
getCost(Node, IG, SpillLimit) ->
- case Node > SpillLimit of
+ case Node >= SpillLimit of
true -> inf;
false ->
SpillCost = hipe_ig:node_spill_cost(Node, IG),
diff --git a/lib/hipe/sparc/hipe_sparc_assemble.erl b/lib/hipe/sparc/hipe_sparc_assemble.erl
index 08bd47c4d2..2b82f41d23 100644
--- a/lib/hipe/sparc/hipe_sparc_assemble.erl
+++ b/lib/hipe/sparc/hipe_sparc_assemble.erl
@@ -32,7 +32,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, 4),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap), Options),
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
index caa0e71d0b..430e097b91 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
@@ -18,6 +18,7 @@ test() ->
ok = test_R12B5_seg_fault(),
ok = test_switch_neg_int(),
ok = test_icode_range_anal(),
+ ok = test_icode_range_call(),
ok.
%%-----------------------------------------------------------------------
@@ -461,3 +462,44 @@ g(X, Z) ->
test -> non_zero_test;
other -> other
end.
+
+%%-----------------------------------------------------------------------
+%% From: Rich Neswold
+%% Date: Oct 5, 2016
+%%
+%% The following was a bug in the HiPE compiler's range analysis. The
+%% function range_client/2 below would would not stop when N reached 0,
+%% but keep recursing into the second clause forever.
+%%
+%% The problem turned out to be in hipe_icode_range:analyse_call/2,
+%% which would note update the argument ranges of the callee if the
+%% result of the call was ignored.
+%% -----------------------------------------------------------------------
+-define(TIMEOUT, 42).
+
+test_icode_range_call() ->
+ Self = self(),
+ Client = spawn_link(fun() -> range_client(Self, 4) end),
+ range_server(4, Client).
+
+range_server(0, _Client) ->
+ receive
+ stopping -> ok;
+ {called_with, 0} -> error(failure)
+ after ?TIMEOUT -> error(timeout)
+ end;
+range_server(N, Client) ->
+ receive
+ {called_with, N} ->
+ Client ! proceed
+ after ?TIMEOUT -> error(timeout)
+ end,
+ range_server(N-1, Client). % tailcall (so the bug does not affect it)
+
+range_client(Server, 0) ->
+ Server ! stopping;
+range_client(Server, N) ->
+ Server ! {called_with, N},
+ receive proceed -> ok end,
+ range_client(Server, N - 1), % non-tailrecursive call with ignored result
+ ok.
diff --git a/lib/hipe/x86/hipe_x86_assemble.erl b/lib/hipe/x86/hipe_x86_assemble.erl
index fb0beba293..50919bdf4e 100644
--- a/lib/hipe/x86/hipe_x86_assemble.erl
+++ b/lib/hipe/x86/hipe_x86_assemble.erl
@@ -63,7 +63,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, ?HIPE_X86_REGISTERS:alignment()),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap, Options), Options),
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
index af189a74f7..b3a18e03d4 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
@@ -58,7 +58,7 @@
#include "erl_interface.h"
#include "m_i.h"
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
@@ -295,7 +295,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
index b7609d63e5..40c7328f03 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
@@ -61,7 +61,7 @@
#include "erl_interface.h"
#include "m_i.h"
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
index 23dc089555..33cfe71322 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
@@ -61,7 +61,7 @@
#include "erl_interface.h"
#include "m_i.h"
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
index 53345d561b..f48480e8dc 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
@@ -81,7 +81,7 @@ static void showtime(MyTimeval *start, MyTimeval *stop);
static void usage(void);
static void done(int r);
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
#define OUTBUFSZ 0
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
index a18f0e7ba9..e2ba5bd5b6 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
@@ -81,7 +81,7 @@ static void showtime(MyTimeval *start, MyTimeval *stop);
static void usage(void);
static void done(int r);
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
#define OUTBUFSZ 0
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index e97db20062..bef8096aed 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -140,6 +140,23 @@ do_recv(Sock, Bs) ->
<fsummary>Close a TCP socket.</fsummary>
<desc>
<p>Closes a TCP socket.</p>
+ <p>Note that in most implementations of TCP, doing a <c>close</c> does
+ not guarantee that any data sent is delivered to the recipient before
+ the close is detected at the remote side. If you want to guarantee
+ delivery of the data to the recipient there are two common ways to
+ achieve this.</p>
+ <list type="ordered">
+ <item><p>Use <seealso marker="#shutdown/2">
+ <c>gen_tcp:shutdown(Sock, write)</c></seealso> to signal that
+ no more data is to be sent and wait for the read side of the
+ socket to be closed.</p>
+ </item>
+ <item><p>Use the socket option <seealso marker="inet#packet">
+ <c>{packet, N}</c></seealso> (or something similar) to make
+ it possible for the receiver to close the connection when it
+ knowns it has received all the data.</p>
+ </item>
+ </list>
</desc>
</func>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index d557efb6a8..076e50cd10 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -913,7 +913,7 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
</item>
<tag><c>{packet, PacketType}</c>(TCP/IP sockets)</tag>
<item>
- <p>Defines the type of packets to use for a socket.
+ <p><marker id="packet"/>Defines the type of packets to use for a socket.
Possible values:</p>
<taglist>
<tag><c>raw | 0</c></tag>
diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl
index 59eca242b1..b901da95b8 100644
--- a/lib/kernel/src/kernel.erl
+++ b/lib/kernel/src/kernel.erl
@@ -100,63 +100,112 @@ get_error_logger_type() ->
%%%-----------------------------------------------------------------
init([]) ->
- SupFlags = {one_for_all, 0, 1},
-
- Config = {kernel_config,
- {kernel_config, start_link, []},
- permanent, 2000, worker, [kernel_config]},
- Code = {code_server,
- {code, start_link, []},
- permanent, 2000, worker, [code]},
- File = {file_server_2,
- {file_server, start_link, []},
- permanent, 2000, worker,
- [file, file_server, file_io_server, prim_file]},
- StdError = {standard_error,
- {standard_error, start_link, []},
- temporary, 2000, supervisor, [user_sup]},
- User = {user,
- {user_sup, start, []},
- temporary, 2000, supervisor, [user_sup]},
-
+ SupFlags = #{strategy => one_for_all,
+ intensity => 0,
+ period => 1},
+
+ Config = #{id => kernel_config,
+ start => {kernel_config, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [kernel_config]},
+
+ Code = #{id => code_server,
+ start => {code, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [code]},
+
+ File = #{id => file_server_2,
+ start => {file_server, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modeules => [file, file_server, file_io_server, prim_file]},
+
+ StdError = #{id => standard_error,
+ start => {standard_error, start_link, []},
+ restart => temporary,
+ shutdown => 2000,
+ type => supervisor,
+ modules => [user_sup]},
+
+ User = #{id => user,
+ start => {user_sup, start, []},
+ restart => temporary,
+ shutdown => 2000,
+ type => supervisor,
+ modules => [user_sup]},
+
+ SafeSup = #{id => kernel_safe_sup,
+ start =>{supervisor, start_link, [{local, kernel_safe_sup}, ?MODULE, safe]},
+ restart => permanent,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [?MODULE]},
+
case init:get_argument(mode) of
- {ok, [["minimal"]]} ->
- SafeSupervisor = {kernel_safe_sup,
- {supervisor, start_link,
- [{local, kernel_safe_sup}, ?MODULE, safe]},
- permanent, infinity, supervisor, [?MODULE]},
- {ok, {SupFlags,
- [Code, File, StdError, User,
- Config, SafeSupervisor]}};
- _ ->
- Rpc = {rex, {rpc, start_link, []},
- permanent, 2000, worker, [rpc]},
- Global = {global_name_server, {global, start_link, []},
- permanent, 2000, worker, [global]},
- Glo_grp = {global_group, {global_group,start_link,[]},
- permanent, 2000, worker, [global_group]},
- InetDb = {inet_db, {inet_db, start_link, []},
- permanent, 2000, worker, [inet_db]},
- NetSup = {net_sup, {erl_distribution, start_link, []},
- permanent, infinity, supervisor,[erl_distribution]},
+ {ok, [["minimal"]]} ->
+ {ok, {SupFlags, [Code, File, StdError, User, Config, SafeSup]}};
+ _ ->
+ Rpc = #{id => rex,
+ start => {rpc, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [rpc]},
+
+ Global = #{id => global_name_server,
+ start => {global, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [global]},
+
+ GlGroup = #{id => global_group,
+ start => {global_group,start_link,[]},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [global_group]},
+
+ InetDb = #{id => inet_db,
+ start => {inet_db, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [inet_db]},
+
+ NetSup = #{id => net_sup,
+ start => {erl_distribution, start_link, []},
+ restart => permanent,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [erl_distribution]},
+
SigSrv = #{id => erl_signal_server,
start => {gen_event, start_link, [{local, erl_signal_server}]},
- type => worker, restart => permanent, shutdown => 2000, modules => dynamic},
- DistAC = start_dist_ac(),
-
- Timer = start_timer(),
-
- SafeSupervisor = {kernel_safe_sup,
- {supervisor, start_link,
- [{local, kernel_safe_sup}, ?MODULE, safe]},
- permanent, infinity, supervisor, [?MODULE]},
- {ok, {SupFlags,
- [Code, Rpc, Global, InetDb | DistAC] ++
- [NetSup, Glo_grp, File, SigSrv,
- StdError, User, Config, SafeSupervisor] ++ Timer}}
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => dynamic},
+
+ DistAC = start_dist_ac(),
+
+ Timer = start_timer(),
+
+ {ok, {SupFlags,
+ [Code, Rpc, Global, InetDb | DistAC] ++
+ [NetSup, GlGroup, File, SigSrv,
+ StdError, User, Config, SafeSup] ++ Timer}}
end;
init(safe) ->
- SupFlags = {one_for_one, 4, 3600},
+ SupFlags = #{strategy => one_for_one,
+ intensity => 4,
+ period => 3600},
+
Boot = start_boot_server(),
DiskLog = start_disk_log(),
Pg2 = start_pg2(),
@@ -170,60 +219,85 @@ init(safe) ->
{ok, {SupFlags, Boot ++ DiskLog ++ Pg2}}.
start_dist_ac() ->
- Spec = [{dist_ac,{dist_ac,start_link,[]},permanent,2000,worker,[dist_ac]}],
+ Spec = [#{id => dist_ac,
+ start => {dist_ac,start_link,[]},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [dist_ac]}],
case application:get_env(kernel, start_dist_ac) of
- {ok, true} -> Spec;
- {ok, false} -> [];
- undefined ->
- case application:get_env(kernel, distributed) of
- {ok, _} -> Spec;
- _ -> []
- end
+ {ok, true} -> Spec;
+ {ok, false} -> [];
+ undefined ->
+ case application:get_env(kernel, distributed) of
+ {ok, _} -> Spec;
+ _ -> []
+ end
end.
start_boot_server() ->
case application:get_env(kernel, start_boot_server) of
- {ok, true} ->
- Args = get_boot_args(),
- [{boot_server, {erl_boot_server, start_link, [Args]}, permanent,
- 1000, worker, [erl_boot_server]}];
- _ ->
- []
+ {ok, true} ->
+ Args = get_boot_args(),
+ [#{id => boot_server,
+ start => {erl_boot_server, start_link, [Args]},
+ restart => permanent,
+ shutdown => 1000,
+ type => worker,
+ modules => [erl_boot_server]}];
+ _ ->
+ []
end.
get_boot_args() ->
case application:get_env(kernel, boot_server_slaves) of
- {ok, Slaves} -> Slaves;
- _ -> []
+ {ok, Slaves} -> Slaves;
+ _ -> []
end.
start_disk_log() ->
case application:get_env(kernel, start_disk_log) of
- {ok, true} ->
- [{disk_log_server,
- {disk_log_server, start_link, []},
- permanent, 2000, worker, [disk_log_server]},
- {disk_log_sup, {disk_log_sup, start_link, []}, permanent,
- 1000, supervisor, [disk_log_sup]}];
- _ ->
- []
+ {ok, true} ->
+ [#{id => disk_log_server,
+ start => {disk_log_server, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [disk_log_server]},
+ #{id => disk_log_sup,
+ start => {disk_log_sup, start_link, []},
+ restart => permanent,
+ shutdown => 1000,
+ type => supervisor,
+ modules => [disk_log_sup]}];
+ _ ->
+ []
end.
start_pg2() ->
case application:get_env(kernel, start_pg2) of
- {ok, true} ->
- [{pg2, {pg2, start_link, []}, permanent, 1000, worker, [pg2]}];
- _ ->
- []
+ {ok, true} ->
+ [#{id => pg2,
+ start => {pg2, start_link, []},
+ restart => permanent,
+ shutdown => 1000,
+ type => worker,
+ modules => [pg2]}];
+ _ ->
+ []
end.
start_timer() ->
case application:get_env(kernel, start_timer) of
- {ok, true} ->
- [{timer_server, {timer, start_link, []}, permanent, 1000, worker,
- [timer]}];
- _ ->
- []
+ {ok, true} ->
+ [#{id => timer_server,
+ start => {timer, start_link, []},
+ restart => permanent,
+ shutdown => 1000,
+ type => worker,
+ modules => [timer]}];
+ _ ->
+ []
end.
%%-----------------------------------------------------------------