aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_bif_load.c3
-rw-r--r--erts/emulator/beam/beam_emu.c9
-rw-r--r--erts/emulator/beam/beam_load.c34
-rw-r--r--erts/emulator/beam/bif.c2
-rw-r--r--erts/emulator/beam/dist.c8
-rw-r--r--erts/emulator/beam/erl_bif_info.c10
-rw-r--r--erts/emulator/beam/erl_bits.c6
-rw-r--r--erts/emulator/beam/erl_db_tree.c2
-rw-r--r--erts/emulator/beam/erl_driver.h2
-rw-r--r--erts/emulator/beam/erl_gc.c3
-rw-r--r--erts/emulator/beam/erl_printf_term.c452
-rw-r--r--erts/emulator/beam/erl_process.c36
-rw-r--r--erts/emulator/beam/erl_process.h1
-rw-r--r--erts/emulator/beam/erl_unicode.c2
-rw-r--r--erts/emulator/beam/io.c5
-rw-r--r--erts/emulator/beam/ops.tab2
-rw-r--r--erts/emulator/beam/sys.h4
17 files changed, 307 insertions, 274 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index 6ae9736141..1ca405961f 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -472,9 +472,6 @@ check_process_code(Process* rp, Module* modp)
for (oh = MSO(rp).first; oh; oh = oh->next) {
if (thing_subtag(oh->thing_word) == FUN_SUBTAG) {
ErlFunThing* funp = (ErlFunThing*) oh;
- BeamInstr* fun_code;
-
- fun_code = funp->fe->address;
if (INSIDE((BeamInstr *) funp->fe->address)) {
if (done_gc) {
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 7b2aac0908..32ea8588d2 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3413,13 +3413,15 @@ void process_main(void)
r(0) = nif_bif_result;
CHECK_TERM(r(0));
SET_I(c_p->cp);
+ c_p->cp = 0;
Goto(*I);
} else if (c_p->freason == TRAP) {
SET_I(*((BeamInstr **) (UWord) ((c_p)->def_arg_reg + 3)));
r(0) = c_p->def_arg_reg[0];
x(1) = c_p->def_arg_reg[1];
x(2) = c_p->def_arg_reg[2];
- if (c_p->status == P_WAITING) {
+ if (c_p->flags & F_HIBERNATE_SCHED) {
+ c_p->flags &= ~F_HIBERNATE_SCHED;
goto do_schedule;
}
Dispatch();
@@ -5224,6 +5226,7 @@ void process_main(void)
OpCase(i_hibernate): {
SWAPOUT;
if (erts_hibernate(c_p, r(0), x(1), x(2), reg)) {
+ c_p->flags &= ~F_HIBERNATE_SCHED;
goto do_schedule;
} else {
I = handle_error(c_p, I, reg, hibernate_3);
@@ -6276,15 +6279,17 @@ erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* re
PROCESS_MAIN_CHK_LOCKS(c_p);
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS);
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- c_p->status = P_WAITING;
#ifdef ERTS_SMP
ERTS_SMP_MSGQ_MV_INQ2PRIVQ(c_p);
if (c_p->msg.len > 0)
erts_add_to_runq(c_p);
+ else
#endif
+ c_p->status = P_WAITING;
}
erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS);
c_p->current = bif_export[BIF_hibernate_3]->code;
+ c_p->flags |= F_HIBERNATE_SCHED; /* Needed also when woken! */
return 1;
}
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 788cb4209c..57fe25453d 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -480,8 +480,6 @@ static GenOp* gen_select_literals(LoaderState* stp, GenOpArg S,
GenOpArg* Rest);
static GenOp* const_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
GenOpArg Size, GenOpArg* Rest);
-static GenOp* gen_func_info(LoaderState* stp, GenOpArg mod, GenOpArg Func,
- GenOpArg arity, GenOpArg label);
static int freeze_code(LoaderState* stp);
@@ -1413,7 +1411,6 @@ static int
load_code(LoaderState* stp)
{
int i;
- int tmp;
int ci;
int last_func_start = 0;
char* sign;
@@ -1933,7 +1930,6 @@ load_code(LoaderState* stp)
case 'P': /* Byte offset into tuple or stack */
case 'Q': /* Like 'P', but packable */
VerifyTag(stp, tag, TAG_u);
- tmp = tmp_op->a[arg].val;
code[ci++] = (BeamInstr) ((tmp_op->a[arg].val+1) * sizeof(Eterm));
break;
case 'l': /* Floating point register. */
@@ -3401,36 +3397,6 @@ const_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
return op;
}
-
-static GenOp*
-gen_func_info(LoaderState* stp, GenOpArg mod, GenOpArg func,
- GenOpArg arity, GenOpArg label)
-{
- GenOp* fi;
- GenOp* op;
-
- NEW_GENOP(stp, fi);
- fi->op = genop_i_func_info_4;
- fi->arity = 4;
- fi->a[0].type = TAG_u; /* untagged Zero */
- fi->a[0].val = 0;
- fi->a[1] = mod;
- fi->a[2] = func;
- fi->a[3] = arity;
-
- NEW_GENOP(stp, op);
- op->op = genop_label_1;
- op->arity = 1;
- op->a[0] = label;
-
- fi->next = op;
- op->next = NULL;
-
- return fi;
-}
-
-
-
static GenOp*
gen_make_fun2(LoaderState* stp, GenOpArg idx)
{
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index f01580eb2b..6b1ce823cb 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -368,7 +368,6 @@ static int demonitor(Process *c_p, Eterm ref)
ErtsMonitor *mon = NULL; /* The monitor entry to delete */
Process *rp; /* Local target process */
Eterm to = NIL; /* Monitor link traget */
- Eterm ref_p; /* Pid of this end */
DistEntry *dep = NULL; /* Target's distribution entry */
int deref_de = 0;
int res;
@@ -381,7 +380,6 @@ static int demonitor(Process *c_p, Eterm ref)
res = ERTS_DEMONITOR_BADARG;
goto done; /* Cannot be this monitor's ref */
}
- ref_p = c_p->id;
mon = erts_lookup_monitor(c_p->monitors, ref);
if (!mon) {
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 8b549d254c..b1cdd0660a 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -864,11 +864,15 @@ erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote)
#include <valgrind/valgrind.h>
#include <valgrind/memcheck.h>
+#ifndef HAVE_VALGRIND_PRINTF_XML
+#define VALGRIND_PRINTF_XML VALGRIND_PRINTF
+#endif
+
# define PURIFY_MSG(msg) \
do { \
char buf__[1]; size_t bufsz__ = sizeof(buf__); \
if (erts_sys_getenv("VALGRIND_LOG_XML", buf__, &bufsz__) >= 0) { \
- VALGRIND_PRINTF("<erlang_error_log>" \
+ VALGRIND_PRINTF_XML("<erlang_error_log>" \
"%s, line %d: %s</erlang_error_log>\n", \
__FILE__, __LINE__, msg); \
} else { \
@@ -900,7 +904,6 @@ int erts_net_message(Port *prt,
ErtsDistExternal ede;
byte *t;
Sint ctl_len;
- int orig_ctl_len;
Eterm arg;
Eterm from, to;
Eterm watcher, watched;
@@ -981,7 +984,6 @@ int erts_net_message(Port *prt,
PURIFY_MSG("data error");
goto data_error;
}
- orig_ctl_len = ctl_len;
if (ctl_len > DIST_CTL_DEFAULT_SIZE) {
ctl = erts_alloc(ERTS_ALC_T_DCTRL_BUF, ctl_len * sizeof(Eterm));
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 09fcc7b975..e50fc18e64 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -1723,8 +1723,14 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
} else if (is_list(*tp)) {
#if defined(PURIFY)
#define ERTS_ERROR_CHECKER_PRINTF purify_printf
+#define ERTS_ERROR_CHECKER_PRINTF_XML purify_printf
#elif defined(VALGRIND)
#define ERTS_ERROR_CHECKER_PRINTF VALGRIND_PRINTF
+# ifndef HAVE_VALGRIND_PRINTF_XML
+# define ERTS_ERROR_CHECKER_PRINTF_XML VALGRIND_PRINTF
+# else
+# define ERTS_ERROR_CHECKER_PRINTF_XML VALGRIND_PRINTF_XML
+# endif
#endif
int buf_size = 8*1024; /* Try with 8KB first */
char *buf = erts_alloc(ERTS_ALC_T_TMP, buf_size);
@@ -1741,8 +1747,8 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
}
buf[buf_size - 1 - r] = '\0';
if (check_if_xml()) {
- ERTS_ERROR_CHECKER_PRINTF("<erlang_info_log>"
- "%s</erlang_info_log>\n", buf);
+ ERTS_ERROR_CHECKER_PRINTF_XML("<erlang_info_log>"
+ "%s</erlang_info_log>\n", buf);
} else {
ERTS_ERROR_CHECKER_PRINTF("%s\n", buf);
}
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 6f8a7436d5..0174e5fc43 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -177,7 +177,6 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
byte* LSB;
byte* MSB;
Uint* hp;
- Uint* hp_end;
Uint words_needed;
Uint actual;
Uint v32;
@@ -405,7 +404,6 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
default:
words_needed = 1+WSIZE(bytes);
hp = HeapOnlyAlloc(p, words_needed);
- hp_end = hp + words_needed;
res = bytes_to_big(LSB, bytes, sgn, hp);
if (is_small(res)) {
p->htop = hp;
@@ -425,7 +423,6 @@ Eterm
erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb)
{
ErlSubBin* sb;
- size_t num_bytes; /* Number of bytes in binary. */
if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */
return THE_NON_VALUE;
@@ -435,7 +432,6 @@ erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffe
* From now on, we can't fail.
*/
- num_bytes = NBYTES(num_bits);
sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);
sb->thing_word = HEADER_SUB_BIN;
@@ -1557,7 +1553,6 @@ Uint32
erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
{
Uint bytes;
- Uint bits;
Uint offs;
byte bigbuf[4];
byte* LSB;
@@ -1567,7 +1562,6 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
ASSERT(mb->size - mb->offset >= 32);
bytes = 4;
- bits = 8;
offs = 0;
LSB = bigbuf;
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index 6cdbec3213..a59c0c258d 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -575,7 +575,7 @@ static int db_prev_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
return DB_ERROR_NONE;
}
-static ERTS_INLINE int cmp_key(DbTableTree* tb, Eterm key, Eterm* key_base,
+static ERTS_INLINE Sint cmp_key(DbTableTree* tb, Eterm key, Eterm* key_base,
TreeDbTerm* obj)
{
return cmp_rel(key, key_base,
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 13a73e01bb..3c0eade0d8 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -282,7 +282,7 @@ typedef struct erl_drv_entry {
the port */
void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event);
/* called when we have input from one of
- the driver's handles) */
+ the driver's handles */
void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event);
/* called when output is possible to one of
the driver's handles */
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index d9150d86fe..c30d67ac88 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -455,7 +455,6 @@ erts_garbage_collect_hibernate(Process* p)
Eterm* heap;
Eterm* htop;
Rootset rootset;
- int n;
char* src;
Uint src_size;
Uint actual_size;
@@ -486,7 +485,7 @@ erts_garbage_collect_hibernate(Process* p)
sizeof(Eterm)*heap_size);
htop = heap;
- n = setup_rootset(p, p->arg_reg, p->arity, &rootset);
+ (void) setup_rootset(p, p->arg_reg, p->arity, &rootset);
#if HIPE
hipe_empty_nstack(p);
#endif
diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c
index d9f132f067..b71404fd27 100644
--- a/erts/emulator/beam/erl_printf_term.c
+++ b/erts/emulator/beam/erl_printf_term.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -216,233 +216,289 @@ static int print_atom_name(fmtfn_t fn, void* arg, Eterm atom, long *dcount)
}
+#define PRT_BAR ((Eterm) 0)
+#define PRT_COMMA ((Eterm) 1)
+#define PRT_CLOSE_LIST ((Eterm) 2)
+#define PRT_CLOSE_TUPLE ((Eterm) 3)
+#define PRT_TERM ((Eterm) 4)
+#define PRT_ONE_CONS ((Eterm) 5)
+#define PRT_PATCH_FUN_SIZE ((Eterm) 6)
+#define PRT_LAST_ARRAY_ELEMENT ((Eterm) 7) /* Note! Must be last... */
static int
print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
{
+ DECLARE_WSTACK(s);
int res;
int i;
+ Eterm val;
Uint32 *ref_num;
Eterm* nobj;
+#if HALFWORD_HEAP
+ UWord wobj;
+#endif
res = 0;
- if ((*dcount)-- <= 0)
- return res;
-
-#ifdef HYBRID___NOT_ACTIVE
- /* Color coded output based on memory location */
- if(ptr_val(obj) >= global_heap && ptr_val(obj) < global_hend)
- PRINT_STRING(res, fn, arg, "\033[32m");
-#ifdef INCREMENTAL
- else if(ptr_val(obj) >= inc_fromspc && ptr_val(obj) < inc_fromend)
- PRINT_STRING(res, fn, arg, "\033[33m");
+ goto L_jump_start;
+
+ L_outer_loop:
+ while (!WSTACK_ISEMPTY(s)) {
+ switch (val = WSTACK_POP(s)) {
+ case PRT_COMMA:
+ PRINT_CHAR(res, fn, arg, ',');
+ goto L_outer_loop;
+ case PRT_BAR:
+ PRINT_CHAR(res, fn, arg, '|');
+ goto L_outer_loop;
+ case PRT_CLOSE_LIST:
+ PRINT_CHAR(res, fn, arg, ']');
+ goto L_outer_loop;
+ case PRT_CLOSE_TUPLE:
+ PRINT_CHAR(res, fn, arg, '}');
+ goto L_outer_loop;
+ default:
+#if HALFWORD_HEAP
+ obj = (Eterm) (wobj = WSTACK_POP(s));
+#else
+ obj = WSTACK_POP(s);
#endif
- else if(IS_CONST(obj))
- PRINT_STRING(res, fn, arg, "\033[34m");
- else
- PRINT_STRING(res, fn, arg, "\033[31m");
+ switch (val) {
+ case PRT_TERM:
+ break;
+ case PRT_ONE_CONS:
+ L_print_one_cons:
+ {
+ Eterm* cons = list_val(obj);
+ Eterm tl;
+
+ obj = CAR(cons);
+ tl = CDR(cons);
+ if (is_not_nil(tl)) {
+ if (is_list(tl)) {
+ WSTACK_PUSH(s, tl);
+ WSTACK_PUSH(s, PRT_ONE_CONS);
+ WSTACK_PUSH(s, PRT_COMMA);
+ } else {
+ WSTACK_PUSH(s, tl);
+ WSTACK_PUSH(s, PRT_TERM);
+ WSTACK_PUSH(s, PRT_BAR);
+ }
+ }
+ }
+ break;
+ case PRT_LAST_ARRAY_ELEMENT:
+ {
+#if HALFWORD_HEAP
+ Eterm* ptr = (Eterm *) wobj;
+#else
+ Eterm* ptr = (Eterm *) obj;
#endif
+ obj = *ptr;
+ }
+ break;
+ default: /* PRT_LAST_ARRAY_ELEMENT+1 and upwards */
+ {
+#if HALFWORD_HEAP
+ Eterm* ptr = (Eterm *) wobj;
+#else
+ Eterm* ptr = (Eterm *) obj;
+#endif
+ obj = *ptr++;
+ WSTACK_PUSH(s, (UWord) ptr);
+ WSTACK_PUSH(s, val-1);
+ WSTACK_PUSH(s, PRT_COMMA);
+ }
+ break;
+ }
+ break;
+ }
- if (is_CP(obj)) {
- PRINT_STRING(res, fn, arg, "<cp/header:");
- PRINT_POINTER(res, fn, arg, cp_val(obj));
- PRINT_CHAR(res, fn, arg, '>');
- return res;
- }
+ L_jump_start:
- switch (tag_val_def(obj)) {
- case NIL_DEF:
- PRINT_STRING(res, fn, arg, "[]");
- break;
- case ATOM_DEF: {
- int tres = print_atom_name(fn, arg, obj, dcount);
- if (tres < 0)
- return tres;
- res += tres;
- if (*dcount <= 0)
- return res;
- break;
- }
- case SMALL_DEF:
- PRINT_SLONG(res, fn, arg, 'd', 0, 1, (signed long) signed_val(obj));
- break;
- case BIG_DEF: {
- int print_res;
- char def_buf[64];
- char *buf, *big_str;
- Uint sz = (Uint) big_decimal_estimate(obj);
- sz++;
- if (sz <= 64)
- buf = &def_buf[0];
- else
- buf = erts_alloc(ERTS_ALC_T_TMP, sz);
- big_str = erts_big_to_string(obj, buf, sz);
- print_res = erts_printf_string(fn, arg, big_str);
- if (buf != &def_buf[0])
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- if (print_res < 0)
- return print_res;
- res += print_res;
- break;
- }
- case REF_DEF:
- case EXTERNAL_REF_DEF:
- PRINT_STRING(res, fn, arg, "#Ref<");
- PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) ref_channel_no(obj));
- ref_num = ref_numbers(obj);
- for (i = ref_no_of_numbers(obj)-1; i >= 0; i--) {
- PRINT_CHAR(res, fn, arg, '.');
- PRINT_ULONG(res, fn, arg, 'u', 0, 1, (unsigned long) ref_num[i]);
+ if ((*dcount)-- <= 0)
+ goto L_done;
+
+ if (is_CP(obj)) {
+ PRINT_STRING(res, fn, arg, "<cp/header:");
+ PRINT_POINTER(res, fn, arg, cp_val(obj));
+ PRINT_CHAR(res, fn, arg, '>');
+ goto L_done;
}
- PRINT_CHAR(res, fn, arg, '>');
- break;
- case PID_DEF:
- case EXTERNAL_PID_DEF:
- PRINT_CHAR(res, fn, arg, '<');
- PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) pid_channel_no(obj));
- PRINT_CHAR(res, fn, arg, '.');
- PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) pid_number(obj));
- PRINT_CHAR(res, fn, arg, '.');
- PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) pid_serial(obj));
- PRINT_CHAR(res, fn, arg, '>');
- break;
- case PORT_DEF:
- case EXTERNAL_PORT_DEF:
- PRINT_STRING(res, fn, arg, "#Port<");
- PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) port_channel_no(obj));
- PRINT_CHAR(res, fn, arg, '.');
- PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) port_number(obj));
- PRINT_CHAR(res, fn, arg, '>');
- break;
- case LIST_DEF:
- if (is_printable_string(obj)) {
- int c;
- PRINT_CHAR(res, fn, arg, '"');
- nobj = list_val(obj);
- while (1) {
- if ((*dcount)-- <= 0)
- return res;
- c = signed_val(*nobj++);
- if (c == '\n')
- PRINT_STRING(res, fn, arg, "\\n");
- else {
- if (c == '"')
- PRINT_CHAR(res, fn, arg, '\\');
- PRINT_CHAR(res, fn, arg, (char) c);
- }
- if (is_not_list(*nobj))
- break;
- nobj = list_val(*nobj);
- }
- PRINT_CHAR(res, fn, arg, '"');
- } else {
- PRINT_CHAR(res, fn, arg, '[');
- nobj = list_val(obj);
- while (1) {
- int tres = print_term(fn, arg, *nobj++, dcount);
- if (tres < 0)
- return tres;
- res += tres;
- if (*dcount <= 0)
- return res;
- if (is_not_list(*nobj))
- break;
- PRINT_CHAR(res, fn, arg, ',');
- nobj = list_val(*nobj);
- }
- if (is_not_nil(*nobj)) {
- int tres;
- PRINT_CHAR(res, fn, arg, '|');
- tres = print_term(fn, arg, *nobj, dcount);
- if (tres < 0)
- return tres;
- res += tres;
- if (*dcount <= 0)
- return res;
+
+ switch (tag_val_def(obj)) {
+ case NIL_DEF:
+ PRINT_STRING(res, fn, arg, "[]");
+ break;
+ case ATOM_DEF: {
+ int tres = print_atom_name(fn, arg, obj, dcount);
+ if (tres < 0) {
+ res = tres;
+ goto L_done;
}
- PRINT_CHAR(res, fn, arg, ']');
- }
- break;
- case TUPLE_DEF:
- nobj = tuple_val(obj); /* pointer to arity */
- i = arityval(*nobj); /* arity */
- PRINT_CHAR(res, fn, arg, '{');
- while (i--) {
- int tres = print_term(fn, arg, *++nobj, dcount);
- if (tres < 0)
- return tres;
res += tres;
if (*dcount <= 0)
- return res;
- if (i >= 1)
- PRINT_CHAR(res, fn, arg, ',');
- }
- PRINT_CHAR(res, fn, arg, '}');
- break;
- case FLOAT_DEF: {
- FloatDef ff;
- GET_DOUBLE(obj, ff);
- PRINT_DOUBLE(res, fn, arg, 'e', 6, 0, ff.fd);
+ goto L_done;
+ break;
}
- break;
- case BINARY_DEF:
- {
- ProcBin* pb = (ProcBin *) binary_val(obj);
- if (pb->size == 1)
- PRINT_STRING(res, fn, arg, "<<1 byte>>");
- else {
- PRINT_STRING(res, fn, arg, "<<");
- PRINT_ULONG(res, fn, arg, 'u', 0, 1, (unsigned long) pb->size);
- PRINT_STRING(res, fn, arg, " bytes>>");
+ case SMALL_DEF:
+ PRINT_SLONG(res, fn, arg, 'd', 0, 1, (signed long) signed_val(obj));
+ break;
+ case BIG_DEF: {
+ int print_res;
+ char def_buf[64];
+ char *buf, *big_str;
+ Uint sz = (Uint) big_decimal_estimate(obj);
+ sz++;
+ if (sz <= 64)
+ buf = &def_buf[0];
+ else
+ buf = erts_alloc(ERTS_ALC_T_TMP, sz);
+ big_str = erts_big_to_string(obj, buf, sz);
+ print_res = erts_printf_string(fn, arg, big_str);
+ if (buf != &def_buf[0])
+ erts_free(ERTS_ALC_T_TMP, (void *) buf);
+ if (print_res < 0) {
+ res = print_res;
+ goto L_done;
}
+ res += print_res;
+ break;
}
- break;
- case EXPORT_DEF:
- {
- Export* ep = *((Export **) (export_val(obj) + 1));
- Atom* module = atom_tab(atom_val(ep->code[0]));
- Atom* name = atom_tab(atom_val(ep->code[1]));
-
- PRINT_STRING(res, fn, arg, "#Fun<");
- PRINT_BUF(res, fn, arg, module->name, module->len);
+ case REF_DEF:
+ case EXTERNAL_REF_DEF:
+ PRINT_STRING(res, fn, arg, "#Ref<");
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1,
+ (unsigned long) ref_channel_no(obj));
+ ref_num = ref_numbers(obj);
+ for (i = ref_no_of_numbers(obj)-1; i >= 0; i--) {
+ PRINT_CHAR(res, fn, arg, '.');
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1, (unsigned long) ref_num[i]);
+ }
+ PRINT_CHAR(res, fn, arg, '>');
+ break;
+ case PID_DEF:
+ case EXTERNAL_PID_DEF:
+ PRINT_CHAR(res, fn, arg, '<');
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1,
+ (unsigned long) pid_channel_no(obj));
PRINT_CHAR(res, fn, arg, '.');
- PRINT_BUF(res, fn, arg, name->name, name->len);
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1,
+ (unsigned long) pid_number(obj));
PRINT_CHAR(res, fn, arg, '.');
- PRINT_SLONG(res, fn, arg, 'd', 0, 1,
- (signed long) ep->code[2]);
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1,
+ (unsigned long) pid_serial(obj));
PRINT_CHAR(res, fn, arg, '>');
- }
- break;
- case FUN_DEF:
- {
- ErlFunThing *funp = (ErlFunThing *) fun_val(obj);
- Atom *ap = atom_tab(atom_val(funp->fe->module));
-
- PRINT_STRING(res, fn, arg, "#Fun<");
- PRINT_BUF(res, fn, arg, ap->name, ap->len);
- PRINT_CHAR(res, fn, arg, '.');
- PRINT_SLONG(res, fn, arg, 'd', 0, 1,
- (signed long) funp->fe->old_index);
+ break;
+ case PORT_DEF:
+ case EXTERNAL_PORT_DEF:
+ PRINT_STRING(res, fn, arg, "#Port<");
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1,
+ (unsigned long) port_channel_no(obj));
PRINT_CHAR(res, fn, arg, '.');
- PRINT_SLONG(res, fn, arg, 'd', 0, 1,
- (signed long) funp->fe->old_uniq);
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1,
+ (unsigned long) port_number(obj));
PRINT_CHAR(res, fn, arg, '>');
+ break;
+ case LIST_DEF:
+ if (is_printable_string(obj)) {
+ int c;
+ PRINT_CHAR(res, fn, arg, '"');
+ nobj = list_val(obj);
+ while (1) {
+ if ((*dcount)-- <= 0)
+ goto L_done;
+ c = signed_val(*nobj++);
+ if (c == '\n')
+ PRINT_STRING(res, fn, arg, "\\n");
+ else {
+ if (c == '"')
+ PRINT_CHAR(res, fn, arg, '\\');
+ PRINT_CHAR(res, fn, arg, (char) c);
+ }
+ if (is_not_list(*nobj))
+ break;
+ nobj = list_val(*nobj);
+ }
+ PRINT_CHAR(res, fn, arg, '"');
+ } else {
+ PRINT_CHAR(res, fn, arg, '[');
+ WSTACK_PUSH(s,PRT_CLOSE_LIST);
+ goto L_print_one_cons;
+ }
+ break;
+ case TUPLE_DEF:
+ nobj = tuple_val(obj); /* pointer to arity */
+ i = arityval(*nobj); /* arity */
+ PRINT_CHAR(res, fn, arg, '{');
+ WSTACK_PUSH(s,PRT_CLOSE_TUPLE);
+ ++nobj;
+ if (i > 0) {
+ WSTACK_PUSH(s, (UWord) nobj);
+ WSTACK_PUSH(s, PRT_LAST_ARRAY_ELEMENT+i-1);
+ }
+ break;
+ case FLOAT_DEF: {
+ FloatDef ff;
+ GET_DOUBLE(obj, ff);
+ PRINT_DOUBLE(res, fn, arg, 'e', 6, 0, ff.fd);
+ }
+ break;
+ case BINARY_DEF:
+ {
+ ProcBin* pb = (ProcBin *) binary_val(obj);
+ if (pb->size == 1)
+ PRINT_STRING(res, fn, arg, "<<1 byte>>");
+ else {
+ PRINT_STRING(res, fn, arg, "<<");
+ PRINT_ULONG(res, fn, arg, 'u', 0, 1, (unsigned long) pb->size);
+ PRINT_STRING(res, fn, arg, " bytes>>");
+ }
+ }
+ break;
+ case EXPORT_DEF:
+ {
+ Export* ep = *((Export **) (export_val(obj) + 1));
+ Atom* module = atom_tab(atom_val(ep->code[0]));
+ Atom* name = atom_tab(atom_val(ep->code[1]));
+
+ PRINT_STRING(res, fn, arg, "#Fun<");
+ PRINT_BUF(res, fn, arg, module->name, module->len);
+ PRINT_CHAR(res, fn, arg, '.');
+ PRINT_BUF(res, fn, arg, name->name, name->len);
+ PRINT_CHAR(res, fn, arg, '.');
+ PRINT_SLONG(res, fn, arg, 'd', 0, 1,
+ (signed long) ep->code[2]);
+ PRINT_CHAR(res, fn, arg, '>');
+ }
+ break;
+ case FUN_DEF:
+ {
+ ErlFunThing *funp = (ErlFunThing *) fun_val(obj);
+ Atom *ap = atom_tab(atom_val(funp->fe->module));
+
+ PRINT_STRING(res, fn, arg, "#Fun<");
+ PRINT_BUF(res, fn, arg, ap->name, ap->len);
+ PRINT_CHAR(res, fn, arg, '.');
+ PRINT_SLONG(res, fn, arg, 'd', 0, 1,
+ (signed long) funp->fe->old_index);
+ PRINT_CHAR(res, fn, arg, '.');
+ PRINT_SLONG(res, fn, arg, 'd', 0, 1,
+ (signed long) funp->fe->old_uniq);
+ PRINT_CHAR(res, fn, arg, '>');
+ }
+ break;
+ default:
+ PRINT_STRING(res, fn, arg, "<unknown:");
+ PRINT_POINTER(res, fn, arg, (UWord) obj);
+ PRINT_CHAR(res, fn, arg, '>');
+ break;
}
- break;
- default:
- PRINT_STRING(res, fn, arg, "<unknown:");
- PRINT_POINTER(res, fn, arg, (UWord) obj);
- PRINT_CHAR(res, fn, arg, '>');
- break;
}
+ L_done:
+
+ DESTROY_WSTACK(s);
return res;
}
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 8cf7dee801..31f23d3978 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -1267,7 +1267,6 @@ ssi_flags_set_wake(ErtsSchedulerSleepInfo *ssi)
static void
wake_scheduler(ErtsRunQueue *rq, int incq, int one)
{
- int res;
ErtsSchedulerSleepInfo *ssi;
ErtsSchedulerSleepList *sl;
@@ -1298,7 +1297,6 @@ wake_scheduler(ErtsRunQueue *rq, int incq, int one)
if (ssi->next)
ssi->next->prev = ssi->prev;
- res = sl->list != NULL;
erts_smp_spin_unlock(&sl->lock);
ERTS_THR_MEMORY_BARRIER;
@@ -2857,7 +2855,6 @@ resume_process(Process *p)
return;
switch(p->rstatus) {
case P_RUNABLE:
- *statusp = P_WAITING; /* make erts_add_to_runq work */
erts_add_to_runq(p);
break;
case P_WAITING:
@@ -4653,7 +4650,7 @@ internal_add_to_runq(ErtsRunQueue *runq, Process *p)
if (p->status_flags & ERTS_PROC_SFLG_INRUNQ)
return NULL;
else if (p->runq_flags & ERTS_PROC_RUNQ_FLG_RUNNING) {
- ASSERT(p->status != P_SUSPENDED);
+ ASSERT(p->rcount == 0);
ERTS_DBG_CHK_PROCS_RUNQ_NOPROC(runq, p);
p->status_flags |= ERTS_PROC_SFLG_PENDADD2SCHEDQ;
return NULL;
@@ -4664,9 +4661,8 @@ internal_add_to_runq(ErtsRunQueue *runq, Process *p)
ERTS_DBG_CHK_PROCS_RUNQ_NOPROC(runq, p);
#ifndef ERTS_SMP
/* Never schedule a suspended process (ok in smp case) */
- ASSERT(p->status != P_SUSPENDED);
+ ASSERT(p->rcount == 0);
add_runq = runq;
-
#else
ASSERT(!p->bound_runq || p->bound_runq == p->run_queue);
if (p->bound_runq) {
@@ -5166,7 +5162,7 @@ Process *schedule(Process *p, int calls)
handle_pending_suspend(p,
ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS);
ASSERT(!(p->status_flags & ERTS_PROC_SFLG_PENDADD2SCHEDQ)
- || p->status != P_SUSPENDED);
+ || p->rcount == 0);
}
#endif
erts_smp_runq_lock(rq);
@@ -7611,10 +7607,28 @@ timeout_proc(Process* p)
p->flags |= F_TIMO;
p->flags &= ~F_INSLPQUEUE;
- if (p->status == P_WAITING)
- erts_add_to_runq(p);
- if (p->status == P_SUSPENDED)
+ switch (p->status) {
+ case P_GARBING:
+ switch (p->gcstatus) {
+ case P_SUSPENDED:
+ goto suspended;
+ case P_WAITING:
+ goto waiting;
+ default:
+ break;
+ }
+ break;
+ case P_WAITING:
+ waiting:
+ erts_add_to_runq(p);
+ break;
+ case P_SUSPENDED:
+ suspended:
p->rstatus = P_RUNABLE; /* MUST set resume status to runnable */
+ break;
+ default:
+ break;
+ }
}
@@ -7700,7 +7714,7 @@ erts_program_counter_info(int to, void *to_arg, Process *p)
* only cause problems.
*/
for (i = 0; i < p->arity; i++)
- erts_print(to, to_arg, " %T\n", p->arg_reg[i]);
+ erts_print(to, to_arg, " %.*T\n", INT_MAX, p->arg_reg[i]);
}
}
}
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 8f78a7d76e..334ae5573f 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -895,6 +895,7 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;
#define F_HAVE_BLCKD_MSCHED (1 << 8) /* Process has blocked multi-scheduling */
#define F_P2PNR_RESCHED (1 << 9) /* Process has been rescheduled via erts_pid2proc_not_running() */
#define F_FORCE_GC (1 << 10) /* Force gc at process in-scheduling */
+#define F_HIBERNATE_SCHED (1 << 11) /* Schedule out after hibernate op */
/* process trace_flags */
#define F_SENSITIVE (1 << 0)
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 545b345a71..dacf228e92 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -902,7 +902,6 @@ static BIF_RETTYPE build_utf8_return(Process *p,Eterm bin,int pos,
static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3)
{
Eterm *real_bin;
- Sint need;
byte* bytes;
Eterm rest_term;
int left, sleft;
@@ -918,7 +917,6 @@ static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3)
ASSERT(is_binary(BIF_ARG_1));
real_bin = binary_val(BIF_ARG_1);
ASSERT(*real_bin == HEADER_PROC_BIN);
- need = ((ProcBin *) real_bin)->val->orig_size;
pos = (int) binary_size(BIF_ARG_1);
bytes = binary_bytes(BIF_ARG_1);
sleft = left = allowed_iterations(BIF_P);
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 4a548310be..f619c6f88b 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -1226,7 +1226,6 @@ void init_io(void)
{
int i;
ErlDrvEntry** dp;
- ErlDrvEntry* drv;
char maxports[21]; /* enough for any 64-bit integer */
size_t maxportssize = sizeof(maxports);
Uint ports_bits = ERTS_PORTS_BITS;
@@ -1309,10 +1308,8 @@ void init_io(void)
init_driver(&fd_driver, &fd_driver_entry, NULL);
init_driver(&vanilla_driver, &vanilla_driver_entry, NULL);
init_driver(&spawn_driver, &spawn_driver_entry, NULL);
- for (dp = driver_tab; *dp != NULL; dp++) {
- drv = *dp;
+ for (dp = driver_tab; *dp != NULL; dp++)
erts_add_driver_entry(*dp, NULL, 1);
- }
erts_smp_tsd_set(driver_list_lock_status_key, NULL);
erts_smp_mtx_unlock(&erts_driver_list_lock);
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index e861f97e7a..6caa1e0b2d 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -1066,7 +1066,7 @@ is_function f y
is_function f r
is_function Fail=f c => jump Fail
-func_info M=a F=a A=u | label L => gen_func_info(M, F, A, L)
+func_info M F A => i_func_info u M F A
# ================================================================
# New bit syntax matching (R11B).
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index ff828ae889..e64c43de6e 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -538,8 +538,8 @@ typedef struct preload {
*/
typedef struct _SysDriverOpts {
- int ifd; /* Input file descriptor (fd driver). */
- int ofd; /* Outputfile descriptor (fd driver). */
+ Uint ifd; /* Input file descriptor (fd driver). */
+ Uint ofd; /* Outputfile descriptor (fd driver). */
int packet_bytes; /* Number of bytes in packet header. */
int read_write; /* Read and write bits. */
int use_stdio; /* Use standard I/O: TRUE or FALSE. */