From 5a8e6c4183a30f3b10de22fa5ba80950dfb2adea Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Mon, 7 Dec 2009 15:25:32 +0100 Subject: Fit all heap data into the 32-bit address range This is the first step in the implementation of the half-word emulator, a 64-bit emulator where all pointers to heap data will be stored in 32-bit words. Code specific for this emulator variant is conditionally compiled when the HALFWORD_HEAP define has a non-zero value. First force all pointers to heap data to fall into a single 32-bit range, but still store them in 64-bit words. Temporary term data stored on C stack is moved into scheduler specific storage (allocated as heaps) and macros are added to make this happen only in emulators where this is needed. For a vanilla VM the temporary terms are still stored on the C stack. --- erts/emulator/beam/beam_emu.c | 10 +- erts/emulator/beam/bif.c | 4 +- erts/emulator/beam/dist.c | 155 +++++++++++++++++++------- erts/emulator/beam/dist.h | 1 + erts/emulator/beam/erl_alloc.c | 14 ++- erts/emulator/beam/erl_alloc.types | 3 + erts/emulator/beam/erl_alloc_util.c | 28 +++++ erts/emulator/beam/erl_arith.c | 107 ++++++++++-------- erts/emulator/beam/erl_bif_info.c | 14 ++- erts/emulator/beam/erl_bif_lists.c | 5 +- erts/emulator/beam/erl_bif_port.c | 4 +- erts/emulator/beam/erl_bif_timer.c | 4 +- erts/emulator/beam/erl_bif_trace.c | 15 ++- erts/emulator/beam/erl_bits.h | 2 +- erts/emulator/beam/erl_db.c | 86 +++++++++++---- erts/emulator/beam/erl_db_util.c | 5 +- erts/emulator/beam/erl_debug.c | 24 ++++ erts/emulator/beam/erl_debug.h | 8 +- erts/emulator/beam/erl_lock_check.c | 2 + erts/emulator/beam/erl_node_tables.c | 13 ++- erts/emulator/beam/erl_process.c | 14 ++- erts/emulator/beam/erl_process.h | 7 ++ erts/emulator/beam/erl_term.c | 14 ++- erts/emulator/beam/erl_term.h | 59 ++++++++-- erts/emulator/beam/erl_trace.c | 207 +++++++++++++++++++++++++++++------ erts/emulator/beam/erl_vm.h | 9 ++ erts/emulator/beam/external.c | 11 +- erts/emulator/beam/global.h | 57 ++++++++++ erts/emulator/beam/io.c | 14 ++- erts/emulator/beam/utils.c | 11 +- erts/emulator/sys/common/erl_mseg.c | 56 +++++++++- 31 files changed, 773 insertions(+), 190 deletions(-) diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 2f7f48193d..66c6eb7819 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1090,7 +1090,11 @@ void process_main(void) */ register Eterm tmp_arg1 REG_tmp_arg1 = NIL; register Eterm tmp_arg2 REG_tmp_arg2 = NIL; - Eterm tmp_big[2]; /* Temporary buffer for small bignums. */ +#if HEAP_ON_C_STACK + Eterm tmp_big[2]; /* Temporary buffer for small bignums if HEAP_ON_C_STACK. */ +#else + Eterm *tmp_big; /* Temporary buffer for small bignums if !HEAP_ON_C_STACK. */ +#endif #ifndef ERTS_SMP static Eterm save_reg[ERTS_X_REGS_ALLOCATED]; @@ -1141,7 +1145,6 @@ void process_main(void) * Note: c_p->arity must be set to reflect the number of useful terms in * c_p->arg_reg before calling the scheduler. */ - if (!init_done) { init_done = 1; goto init_emulator; @@ -1167,6 +1170,9 @@ void process_main(void) #ifdef ERTS_SMP reg = c_p->scheduler_data->save_reg; freg = c_p->scheduler_data->freg; +#endif +#if !HEAP_ON_C_STACK + tmp_big = ERTS_PROC_GET_SCHDATA(c_p)->beam_emu_tmp_heap; #endif ERL_BITS_RELOAD_STATEP(c_p); { diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 1b670585a7..0b21cf3afd 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -616,13 +616,15 @@ local_name_monitor(Process *p, Eterm target_name) rp = erts_whereis_process(p, p_locks, target_name, ERTS_PROC_LOCK_LINK, ERTS_P2P_FLG_ALLOW_OTHER_X); if (!rp) { - Eterm lhp[3]; + DeclareTmpHeap(lhp,3,p); Eterm item; + UseTmpHeap(3,p); erts_smp_proc_unlock(p, ERTS_PROC_LOCK_LINK); p_locks &= ~ERTS_PROC_LOCK_LINK; item = TUPLE2(lhp, target_name, erts_this_dist_entry->sysname); erts_queue_monitor_message(p, &p_locks, mon_ref, am_process, item, am_noproc); + UnUseTmpHeap(3,p); } else if (rp != p) { erts_add_monitor(&(p->monitors), MON_ORIGIN, mon_ref, rp->id, diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index e3094404e2..64ab88fc45 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -228,6 +228,7 @@ int is_node_name_atom(Eterm a) typedef struct { DistEntry *dep; + Eterm *lhp; } NetExitsContext; /* @@ -253,8 +254,9 @@ static void doit_monitor_net_exits(ErtsMonitor *mon, void *vnecp) erts_destroy_monitor(rmon); } } else { - Eterm lhp[3]; + DeclareTmpHeapNoproc(lhp,3); Eterm watched; + UseTmpHeapNoproc(3); ASSERT(mon->type == MON_TARGET); rmon = erts_remove_monitor(&(rp->monitors),mon->ref); /* ASSERT(rmon != NULL); can happen during process exit */ @@ -271,6 +273,7 @@ static void doit_monitor_net_exits(ErtsMonitor *mon, void *vnecp) watched, am_noconnection); erts_destroy_monitor(rmon); } + UnUseTmpHeapNoproc(3); } erts_smp_proc_unlock(rp, rp_locks); done: @@ -632,19 +635,27 @@ static void clear_dist_entry(DistEntry *dep) int erts_dsig_send_link(ErtsDSigData *dsdp, Eterm local, Eterm remote) { - Eterm ctl_heap[4]; + DeclareTmpHeapNoproc(ctl_heap,4); Eterm ctl = TUPLE3(&ctl_heap[0], make_small(DOP_LINK), local, remote); + int res; + UseTmpHeapNoproc(4); - return dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + UnUseTmpHeapNoproc(4); + return res; } int erts_dsig_send_unlink(ErtsDSigData *dsdp, Eterm local, Eterm remote) { - Eterm ctl_heap[4]; + DeclareTmpHeapNoproc(ctl_heap,4); Eterm ctl = TUPLE3(&ctl_heap[0], make_small(DOP_UNLINK), local, remote); + int res; - return dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + UseTmpHeapNoproc(4); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + UnUseTmpHeapNoproc(4); + return res; } @@ -656,7 +667,10 @@ erts_dsig_send_m_exit(ErtsDSigData *dsdp, Eterm watcher, Eterm watched, Eterm ref, Eterm reason) { Eterm ctl; - Eterm ctl_heap[6]; + DeclareTmpHeapNoproc(ctl_heap,6); + int res; + + UseTmpHeapNoproc(6); ctl = TUPLE5(&ctl_heap[0], make_small(DOP_MONITOR_P_EXIT), watched, watcher, ref, reason); @@ -667,7 +681,9 @@ erts_dsig_send_m_exit(ErtsDSigData *dsdp, Eterm watcher, Eterm watched, erts_smp_de_links_unlock(dsdp->dep); #endif - return dsig_send(dsdp, ctl, THE_NON_VALUE, 1); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1); + UnUseTmpHeapNoproc(6); + return res; } /* We want to monitor a process (named or unnamed) on another node, we send: @@ -678,13 +694,17 @@ erts_dsig_send_monitor(ErtsDSigData *dsdp, Eterm watcher, Eterm watched, Eterm ref) { Eterm ctl; - Eterm ctl_heap[5]; + DeclareTmpHeapNoproc(ctl_heap,5); + int res; + UseTmpHeapNoproc(5); ctl = TUPLE4(&ctl_heap[0], make_small(DOP_MONITOR_P), watcher, watched, ref); - return dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + UnUseTmpHeapNoproc(5); + return res; } /* A local process monitoring a remote one wants to stop monitoring, either @@ -696,23 +716,29 @@ erts_dsig_send_demonitor(ErtsDSigData *dsdp, Eterm watcher, Eterm watched, Eterm ref, int force) { Eterm ctl; - Eterm ctl_heap[5]; + DeclareTmpHeapNoproc(ctl_heap,5); + int res; + UseTmpHeapNoproc(5); ctl = TUPLE4(&ctl_heap[0], make_small(DOP_DEMONITOR_P), watcher, watched, ref); - return dsig_send(dsdp, ctl, THE_NON_VALUE, force); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, force); + UnUseTmpHeapNoproc(5); + return res; } int erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message) { Eterm ctl; - Eterm ctl_heap[5]; + DeclareTmpHeapNoproc(ctl_heap,5); Eterm token = NIL; Process *sender = dsdp->proc; + int res; + UseTmpHeapNoproc(5); if (SEQ_TRACE_TOKEN(sender) != NIL) { seq_trace_update_send(sender); token = SEQ_TRACE_TOKEN(sender); @@ -724,17 +750,21 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message) make_small(DOP_SEND_TT), am_Cookie, remote, token); else ctl = TUPLE3(&ctl_heap[0], make_small(DOP_SEND), am_Cookie, remote); - return dsig_send(dsdp, ctl, message, 0); + res = dsig_send(dsdp, ctl, message, 0); + UnUseTmpHeapNoproc(5); + return res; } int erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message) { Eterm ctl; - Eterm ctl_heap[6]; + DeclareTmpHeapNoproc(ctl_heap,6); Eterm token = NIL; Process *sender = dsdp->proc; + int res; + UseTmpHeapNoproc(6); if (SEQ_TRACE_TOKEN(sender) != NIL) { seq_trace_update_send(sender); token = SEQ_TRACE_TOKEN(sender); @@ -747,7 +777,9 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message) else ctl = TUPLE4(&ctl_heap[0], make_small(DOP_REG_SEND), sender->id, am_Cookie, remote_name); - return dsig_send(dsdp, ctl, message, 0); + res = dsig_send(dsdp, ctl, message, 0); + UnUseTmpHeapNoproc(6); + return res; } /* local has died, deliver the exit signal to remote */ @@ -756,8 +788,10 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason, Eterm token) { Eterm ctl; - Eterm ctl_heap[6]; + DeclareTmpHeapNoproc(ctl_heap,6); + int res; + UseTmpHeapNoproc(6); if (token != NIL) { seq_trace_update_send(dsdp->proc); seq_trace_output_exit(token, reason, SEQ_TRACE_SEND, remote, local); @@ -767,38 +801,58 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote, ctl = TUPLE4(&ctl_heap[0], make_small(DOP_EXIT), local, remote, reason); } /* forced, i.e ignore busy */ - return dsig_send(dsdp, ctl, THE_NON_VALUE, 1); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1); + UnUseTmpHeapNoproc(6); + return res; } int erts_dsig_send_exit(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason) { - Eterm ctl_heap[5]; - Eterm ctl = TUPLE4(&ctl_heap[0], - make_small(DOP_EXIT), local, remote, reason); + DeclareTmpHeapNoproc(ctl_heap,5); + int res; + Eterm ctl; + + UseTmpHeapNoproc(5); + ctl = TUPLE4(&ctl_heap[0], + make_small(DOP_EXIT), local, remote, reason); /* forced, i.e ignore busy */ - return dsig_send(dsdp, ctl, THE_NON_VALUE, 1); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1); + UnUseTmpHeapNoproc(5); + return res; } int erts_dsig_send_exit2(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason) { - Eterm ctl_heap[5]; - Eterm ctl = TUPLE4(&ctl_heap[0], - make_small(DOP_EXIT2), local, remote, reason); + DeclareTmpHeapNoproc(ctl_heap,5); + int res; + Eterm ctl; + + UseTmpHeapNoproc(5); + ctl = TUPLE4(&ctl_heap[0], + make_small(DOP_EXIT2), local, remote, reason); - return dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + UnUseTmpHeapNoproc(5); + return res; } int erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote) { - Eterm ctl_heap[4]; - Eterm ctl = TUPLE3(&ctl_heap[0], - make_small(DOP_GROUP_LEADER), leader, remote); + DeclareTmpHeapNoproc(ctl_heap,4); + int res; + Eterm ctl; + + UseTmpHeapNoproc(4); + ctl = TUPLE3(&ctl_heap[0], + make_small(DOP_GROUP_LEADER), leader, remote); - return dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0); + UnUseTmpHeapNoproc(4); + return res; } #if defined(PURIFY) @@ -832,6 +886,7 @@ erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote) ** ** assert hlen == 0 !!! */ + int erts_net_message(Port *prt, DistEntry *dep, byte *hbuf, @@ -839,6 +894,7 @@ int erts_net_message(Port *prt, byte *buf, int len) { +#define DIST_CTL_DEFAULT_SIZE 64 ErtsDistExternal ede; byte *t; Sint ctl_len; @@ -850,7 +906,7 @@ int erts_net_message(Port *prt, Eterm *tuple; Eterm reason; Process* rp; - Eterm ctl_default[64]; + DeclareTmpHeapNoproc(ctl_default,DIST_CTL_DEFAULT_SIZE); Eterm* ctl = ctl_default; ErlOffHeap off_heap; Eterm* hp; @@ -864,6 +920,7 @@ int erts_net_message(Port *prt, int orig_len = len; #endif + UseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE); /* Thanks to Luke Gorrie */ off_heap.mso = NULL; #ifndef HYBRID /* FIND ME! */ @@ -876,12 +933,16 @@ int erts_net_message(Port *prt, ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt)); - if (!erts_is_alive) + if (!erts_is_alive) { + UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE); return 0; + } if (hlen > 0) goto data_error; - if (len == 0) /* HANDLE TICK !!! */ + if (len == 0) { /* HANDLE TICK !!! */ + UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE); return 0; + } #ifdef ERTS_RAW_DIST_MSG_DBG erts_fprintf(stderr, "<< "); @@ -922,7 +983,8 @@ int erts_net_message(Port *prt, goto data_error; } orig_ctl_len = ctl_len; - if (ctl_len > sizeof(ctl_default)/sizeof(ctl_default[0])) { + + if (ctl_len > DIST_CTL_DEFAULT_SIZE) { ctl = erts_alloc(ERTS_ALC_T_DCTRL_BUF, ctl_len * sizeof(Eterm)); } hp = ctl; @@ -1202,7 +1264,7 @@ int erts_net_message(Port *prt, {DOP_MONITOR_P_EXIT, Remote pid or name, Local pid, ref, reason} */ - Eterm lhp[3]; + DeclareTmpHeapNoproc(lhp,3); Eterm sysname; ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_MSG_SEND|ERTS_PROC_LOCK_LINK; @@ -1237,6 +1299,7 @@ int erts_net_message(Port *prt, erts_smp_proc_unlock(rp, rp_locks); break; } + UseTmpHeapNoproc(3); watched = (is_not_nil(mon->name) ? TUPLE2(&lhp[0], mon->name, sysname) @@ -1246,6 +1309,7 @@ int erts_net_message(Port *prt, ref, am_process, watched, reason); erts_smp_proc_unlock(rp, rp_locks); erts_destroy_monitor(mon); + UnUseTmpHeapNoproc(3); break; } @@ -1384,6 +1448,7 @@ int erts_net_message(Port *prt, erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl); } #endif + UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE); ERTS_SMP_CHK_NO_PROC_LOCKS; return 0; @@ -1402,6 +1467,7 @@ int erts_net_message(Port *prt, erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl); } #endif + UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE); erts_do_exit_port(prt, dep->cid, am_killed); ERTS_SMP_CHK_NO_PROC_LOCKS; return -1; @@ -2547,12 +2613,15 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1) int visible = 0; int hidden = 0; int this = 0; - Uint buf[2]; /* For one cons-cell */ + DeclareTmpHeap(buf,2,BIF_P); /* For one cons-cell */ DistEntry *dep; Eterm arg_list = BIF_ARG_1; #ifdef DEBUG Eterm* endp; #endif + + UseTmpHeap(2,BIF_P); + if (is_atom(BIF_ARG_1)) arg_list = CONS(buf, BIF_ARG_1, NIL); @@ -2563,13 +2632,14 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1) case am_known: visible = hidden = not_connected = this = 1; break; case am_this: this = 1; break; case am_connected: visible = hidden = 1; break; - default: BIF_ERROR(BIF_P, BADARG); break; + default: goto error; break; } arg_list = CDR(list_val(arg_list)); } - if (is_not_nil(arg_list)) - BIF_ERROR(BIF_P, BADARG); + if (is_not_nil(arg_list)) { + goto error; + } length = 0; @@ -2591,7 +2661,7 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1) if (length == 0) { erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx); - BIF_RET(result); + goto done; } hp = HAlloc(BIF_P, 2*length); @@ -2620,7 +2690,14 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1) } ASSERT(endp == hp); erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx); + +done: + UnUseTmpHeap(2,BIF_P); BIF_RET(result); + +error: + UnUseTmpHeap(2,BIF_P); + BIF_ERROR(BIF_P,BADARG); } /**********************************************************************/ diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index ea1abcaeed..cea575798f 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -287,4 +287,5 @@ extern void erts_kill_dist_connection(DistEntry *dep, Uint32); extern Uint erts_dist_cache_size(void); + #endif diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index b853ec0f01..4403a19f4a 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -1605,12 +1605,13 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg) } else { - Eterm tmp_heap[2]; + DeclareTmpHeapNoproc(tmp_heap,2); Eterm wanted_list; if (is_nil(earg)) return NIL; + UseTmpHeapNoproc(2); if (is_not_atom(earg)) wanted_list = earg; else { @@ -1690,15 +1691,18 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg) atoms[length] = am_maximum; uintps[length++] = &size.maximum; } - } - else + } else { + UnUseTmpHeapNoproc(2); return am_badarg; + } break; default: + UnUseTmpHeapNoproc(2); return am_badarg; } wanted_list = CDR(list_val(wanted_list)); } + UnUseTmpHeapNoproc(2); if (is_not_nil(wanted_list)) return am_badarg; } @@ -2285,8 +2289,8 @@ erts_allocator_info_term(void *proc, Eterm which_alloc, int only_sz) SysAllocStat sas; Eterm opts_am; Eterm opts; - Eterm as[4]; - Eterm ts[4]; + Eterm as[4]; /* Ok even if !HEAP_ON_C_STACK, not really heap data on stack */ + Eterm ts[4]; /* Ok even if !HEAP_ON_C_STACK, not really heap data on stack */ int l; if (only_sz) diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index f701f71c7d..f808d3b66e 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -322,6 +322,9 @@ type SSB SHORT_LIVED PROCESSES ssb # Types used by system specific code # +type TEMP_TERM TEMPORARY SYSTEM temp_term +type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term + type DRV_TAB LONG_LIVED SYSTEM drv_tab type DRV_EV_STATE LONG_LIVED SYSTEM driver_event_state type DRV_EV_D_STATE FIXED_SIZE SYSTEM driver_event_data_state diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index 9b7bc24c1c..8b71b51912 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -630,6 +630,11 @@ mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp) blk = (*allctr->get_free_block)(allctr, *blk_szp, NULL, 0); +#if HALFWORD_HEAP + if (!blk) { + blk = create_carrier(allctr, *blk_szp, CFLG_MBC|CFLG_FORCE_MSEG); + } +#else if (!blk) { blk = create_carrier(allctr, *blk_szp, CFLG_MBC); if (!blk) { @@ -640,6 +645,7 @@ mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp) CFLG_SBC|CFLG_FORCE_SIZE|CFLG_FORCE_SYS_ALLOC); } } +#endif #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG if (IS_MBC_BLK(blk)) { @@ -2522,7 +2528,12 @@ do_erts_alcu_alloc(ErtsAlcType_t type, void *extra, Uint size) INC_CC(allctr->calls.this_alloc); if (size >= allctr->sbc_threshold) { +#if HALFWORD_HEAP + Block_t *blk = create_carrier(allctr, size, + CFLG_SBC | CFLG_FORCE_MSEG); +#else Block_t *blk = create_carrier(allctr, size, CFLG_SBC); +#endif res = blk ? BLK2UMEM(blk) : NULL; } else @@ -2780,13 +2791,21 @@ do_erts_alcu_realloc(ErtsAlcType_t type, Block_t *new_blk; if(IS_SBC_BLK(blk)) { do_carrier_resize: +#if HALFWORD_HEAP + new_blk = resize_carrier(allctr, blk, size, CFLG_SBC | CFLG_FORCE_MSEG); +#else new_blk = resize_carrier(allctr, blk, size, CFLG_SBC); +#endif res = new_blk ? BLK2UMEM(new_blk) : NULL; } else if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE) return NULL; else { +#if HALFWORD_HEAP + new_blk = create_carrier(allctr, size, CFLG_SBC | CFLG_FORCE_MSEG); +#else new_blk = create_carrier(allctr, size, CFLG_SBC); +#endif if (new_blk) { res = BLK2UMEM(new_blk); sys_memcpy((void *) res, @@ -3208,12 +3227,21 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) if (allctr->main_carrier_size) { Block_t *blk; +#if HALFWORD_HEAP + blk = create_carrier(allctr, + allctr->main_carrier_size, + CFLG_MBC + | CFLG_FORCE_SIZE + | CFLG_FORCE_MSEG + | CFLG_MAIN_CARRIER); +#else blk = create_carrier(allctr, allctr->main_carrier_size, CFLG_MBC | CFLG_FORCE_SIZE | CFLG_FORCE_SYS_ALLOC | CFLG_MAIN_CARRIER); +#endif if (!blk) goto error; diff --git a/erts/emulator/beam/erl_arith.c b/erts/emulator/beam/erl_arith.c index 126ec7cc73..64fad9fe0e 100644 --- a/erts/emulator/beam/erl_arith.c +++ b/erts/emulator/beam/erl_arith.c @@ -41,6 +41,16 @@ # define MAX(x, y) (((x) > (y)) ? (x) : (y)) #endif +#if !HEAP_ON_C_STACK +# define DECLARE_TMP(VariableName,N,P) \ + Eterm *VariableName = ((ERTS_PROC_GET_SCHDATA(P)->erl_arith_tmp_heap) + (2 * N)) +#else +# define DECLARE_TMP(VariableName,N,P) \ + Eterm VariableName[2] +#endif +# define ARG_IS_NOT_TMP(Arg,Tmp) ((Arg) != make_big((Tmp))) + + static Eterm shift(Process* p, Eterm arg1, Eterm arg2, int right); static ERTS_INLINE void maybe_shrink(Process* p, Eterm* hp, Eterm res, Uint alloc) @@ -169,7 +179,7 @@ shift(Process* p, Eterm arg1, Eterm arg2, int right) { Sint i; Sint ires; - Eterm tmp_big1[2]; + DECLARE_TMP(tmp_big1,0,p); Eterm* bigp; Uint need; @@ -312,8 +322,8 @@ BIF_RETTYPE bnot_1(BIF_ALIST_1) Eterm erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm res; Eterm hdr; FloatDef f1, f2; @@ -458,8 +468,8 @@ erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2) Eterm erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -602,8 +612,8 @@ erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2) Eterm erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -627,8 +637,8 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) } else if (arg2 == SMALL_ONE) { return(arg1); } else { - Eterm big_res[3]; - + DeclareTmpHeap(big_res,3,p); + UseTmpHeap(3,p); /* * The following code is optimized for the case that * result is small (which should be the most common case @@ -636,6 +646,7 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) */ res = small_times(signed_val(arg1), signed_val(arg2), big_res); if (is_small(res)) { + UnUseTmpHeap(3,p); return res; } else { /* @@ -657,6 +668,7 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) if (arity > 1) { *hp = big_res[2]; } + UnUseTmpHeap(3,p); return res; } } @@ -915,8 +927,8 @@ erts_mixed_div(Process* p, Eterm arg1, Eterm arg2) Eterm erts_int_div(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; switch (NUMBER_CODE(arg1, arg2)) { @@ -967,8 +979,8 @@ erts_int_div(Process* p, Eterm arg1, Eterm arg2) Eterm erts_int_rem(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; switch (NUMBER_CODE(arg1, arg2)) { @@ -979,7 +991,8 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2) if (arg1 != make_small(MIN_SMALL)) { return arg1; } else { - Eterm tmp = small_to_big(signed_val(arg1), tmp_big1); + Eterm tmp; + tmp = small_to_big(signed_val(arg1), tmp_big1); if ((ires = big_ucomp(tmp, arg2)) == 0) { return SMALL_ZERO; } else { @@ -1013,8 +1026,8 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2) Eterm erts_band(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm* hp; int need; @@ -1041,8 +1054,8 @@ Eterm erts_band(Process* p, Eterm arg1, Eterm arg2) Eterm erts_bor(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm* hp; int need; @@ -1069,8 +1082,8 @@ Eterm erts_bor(Process* p, Eterm arg1, Eterm arg2) Eterm erts_bxor(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm* hp; int need; @@ -1148,8 +1161,8 @@ erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm res; Eterm hdr; FloatDef f1, f2; @@ -1237,10 +1250,10 @@ erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live) need_heap = BIG_NEED_SIZE(sz); if (ERTS_NEED_GC(p, need_heap)) { erts_garbage_collect(p, need_heap, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1316,8 +1329,8 @@ erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -1394,10 +1407,10 @@ erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live) need_heap = BIG_NEED_SIZE(sz); if (ERTS_NEED_GC(p, need_heap)) { erts_garbage_collect(p, need_heap, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1482,8 +1495,8 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -1509,7 +1522,8 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) } else if (arg2 == SMALL_ONE) { return(arg1); } else { - Eterm big_res[3]; + DeclareTmpHeap(big_res,3,p); + UseTmpHeap(3,p); /* * The following code is optimized for the case that @@ -1519,6 +1533,7 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) res = small_times(signed_val(arg1), signed_val(arg2), big_res); if (is_small(res)) { + UnUseTmpHeap(3,p); return res; } else { /* @@ -1546,6 +1561,7 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) if (arity > 1) { *hp = big_res[2]; } + UnUseTmpHeap(3,p); return res; } } @@ -1609,17 +1625,17 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) need_heap = BIG_NEED_SIZE(sz); if (ERTS_NEED_GC(p, need_heap)) { erts_garbage_collect(p, need_heap, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } hp = p->htop; p->htop += need_heap; res = big_times(arg1, arg2, hp); - trim_heap(p, hp, res); + trim_heap(p, hp, res); /* * Note that the result must be big in this case, since @@ -1828,8 +1844,8 @@ erts_gc_int_div(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; arg1 = reg[live]; @@ -1866,10 +1882,10 @@ erts_gc_int_div(Process* p, Eterm* reg, Uint live) need = BIG_NEED_SIZE(i-ires+1) + BIG_NEED_SIZE(i); if (ERTS_NEED_GC(p, need)) { erts_garbage_collect(p, need, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1894,8 +1910,8 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; arg1 = reg[live]; @@ -1908,7 +1924,8 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live) if (arg1 != make_small(MIN_SMALL)) { return arg1; } else { - Eterm tmp = small_to_big(signed_val(arg1), tmp_big1); + Eterm tmp; + tmp = small_to_big(signed_val(arg1), tmp_big1); if ((ires = big_ucomp(tmp, arg2)) == 0) { return SMALL_ZERO; } else { @@ -1928,10 +1945,10 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live) if (ERTS_NEED_GC(p, need)) { erts_garbage_collect(p, need, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1956,8 +1973,8 @@ Eterm erts_gc_##func(Process* p, Eterm* reg, Uint live) \ { \ Eterm arg1; \ Eterm arg2; \ - Eterm tmp_big1[2]; \ - Eterm tmp_big2[2]; \ + DECLARE_TMP(tmp_big1,0,p); \ + DECLARE_TMP(tmp_big2,1,p); \ Eterm* hp; \ int need; \ \ diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index a34d400ed8..8d3618393a 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -59,6 +59,12 @@ /* Keep erts_system_version as a global variable for easy access from a core */ static char erts_system_version[] = ("Erlang " ERLANG_OTP_RELEASE " (erts-" ERLANG_VERSION ")" +#if HALFWORD_HEAP + " [halfword]" +#endif +#if !HEAP_ON_C_STACK + " [no-c-stack-objects]" +#endif #ifndef OTP_RELEASE " [source]" #endif @@ -624,12 +630,18 @@ static Eterm pi_1_keys[] = { #define ERTS_PI_1_NO_OF_KEYS (sizeof(pi_1_keys)/sizeof(Eterm)) static Eterm pi_1_keys_list; -static Uint pi_1_keys_list_heap[2*ERTS_PI_1_NO_OF_KEYS]; +#if HEAP_ON_C_STACK +static Eterm pi_1_keys_list_heap[2*ERTS_PI_1_NO_OF_KEYS]; +#endif static void process_info_init(void) { +#if HEAP_ON_C_STACK Eterm *hp = &pi_1_keys_list_heap[0]; +#else + Eterm *hp = erts_alloc(ERTS_ALC_T_LL_TEMP_TERM,sizeof(Eterm)*2*ERTS_PI_1_NO_OF_KEYS); +#endif int i; pi_1_keys_list = NIL; diff --git a/erts/emulator/beam/erl_bif_lists.c b/erts/emulator/beam/erl_bif_lists.c index a9e8dd86f7..5df4783fcb 100644 --- a/erts/emulator/beam/erl_bif_lists.c +++ b/erts/emulator/beam/erl_bif_lists.c @@ -89,13 +89,14 @@ BIF_RETTYPE append_2(BIF_ALIST_2) BIF_RET(copy); } +#define SMALL_VEC_SIZE 10 BIF_RETTYPE subtract_2(BIF_ALIST_2) { Eterm list; Eterm* hp; Uint need; Eterm res; - Eterm small_vec[10]; /* Preallocated memory for small lists */ + Eterm small_vec[SMALL_VEC_SIZE]; /* Preallocated memory for small lists */ Eterm* vec_p; Eterm* vp; int i; @@ -115,7 +116,7 @@ BIF_RETTYPE subtract_2(BIF_ALIST_2) BIF_RET(BIF_ARG_1); /* allocate element vector */ - if (n <= sizeof(small_vec)/sizeof(small_vec[0])) + if (n <= SMALL_VEC_SIZE) vec_p = small_vec; else vec_p = (Eterm*) erts_alloc(ERTS_ALC_T_TMP, n * sizeof(Eterm)); diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c index f454f2e12d..f9d97ee1ab 100644 --- a/erts/emulator/beam/erl_bif_port.c +++ b/erts/emulator/beam/erl_bif_port.c @@ -716,15 +716,17 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) } } else if (option == am_cd) { Eterm iolist; - Eterm heap[4]; + DeclareTmpHeap(heap,4,p); int r; + UseTmpHeap(4,p); heap[0] = *tp; heap[1] = make_list(heap+2); heap[2] = make_small(0); heap[3] = NIL; iolist = make_list(heap); r = io_list_to_buf(iolist, (char*) dir, MAXPATHLEN); + UnUseTmpHeap(4,p); if (r < 0) { goto badarg; } diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c index 172bb37952..1740569b69 100644 --- a/erts/emulator/beam/erl_bif_timer.c +++ b/erts/emulator/beam/erl_bif_timer.c @@ -178,8 +178,8 @@ eq_non_standard_ref_numbers(Uint32 *rn1, Uint32 len1, Uint32 *rn2, Uint32 len2) #else #define MAX_REF_HEAP_SZ (1+ERTS_MAX_REF_NUMBERS) #endif - Uint r1_hp[MAX_REF_HEAP_SZ]; - Uint r2_hp[MAX_REF_HEAP_SZ]; + DeclareTmpHeapNoproc(r1_hp,(MAX_REF_HEAP_SZ * 2)); + Eterm *r2_hp = r1_hp +MAX_REF_HEAP_SZ; return eq(create_ref(r1_hp, rn1, len1), create_ref(r2_hp, rn2, len2)); #undef MAX_REF_HEAP_SZ diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 7dff5e0eeb..6623eea4f3 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -86,7 +86,7 @@ trace_pattern_2(Process* p, Eterm MFA, Eterm Pattern) Eterm trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) { - Eterm mfa[3]; + DeclareTmpHeap(mfa,3,p); /* Not really heap here, but might be when setting pattern */ int i; int matches = 0; int specified = 0; @@ -101,6 +101,7 @@ trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) erts_smp_proc_unlock(p, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); + UseTmpHeap(3,p); /* * Check and compile the match specification. */ @@ -312,7 +313,7 @@ trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) MatchSetUnref(match_prog_set); done: - + UnUseTmpHeap(3,p); erts_smp_release_system(); erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); @@ -322,6 +323,7 @@ trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) MatchSetUnref(match_prog_set); + UnUseTmpHeap(3,p); erts_smp_release_system(); erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); BIF_ERROR(p, BADARG); @@ -1011,7 +1013,7 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key) { Eterm* tp; Eterm* hp; - Eterm mfa[3]; + DeclareTmpHeap(mfa,3,p); /* Not really heap here, but might be when setting pattern */ Binary *ms = NULL, *ms_meta = NULL; Sint count = 0; Eterm traced = am_false; @@ -1020,6 +1022,9 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key) Eterm meta = am_false; int r; + + UseTmpHeap(3,p); + if (!is_tuple(func_spec)) { goto error; } @@ -1037,9 +1042,11 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key) r = function_is_traced(mfa, &ms, &ms_meta, &meta, &count); switch (r) { case FUNC_TRACE_NOEXIST: + UnUseTmpHeap(3,p); hp = HAlloc(p, 3); return TUPLE2(hp, key, am_undefined); case FUNC_TRACE_UNTRACED: + UnUseTmpHeap(3,p); hp = HAlloc(p, 3); return TUPLE2(hp, key, am_false); case FUNC_TRACE_GLOBAL_TRACE: @@ -1120,10 +1127,12 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key) default: goto error; } + UnUseTmpHeap(3,p); hp = HAlloc(p, 3); return TUPLE2(hp, key, retval); error: + UnUseTmpHeap(3,p); BIF_ERROR(p, BADARG); } diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h index e3f8e0b679..d482d325a1 100644 --- a/erts/emulator/beam/erl_bits.h +++ b/erts/emulator/beam/erl_bits.h @@ -63,7 +63,7 @@ typedef struct erl_bin_match_struct{ #define HEADER_NUM_SLOTS(hdr) (header_arity(hdr)-sizeof(ErlBinMatchState)/sizeof(Eterm)+1) #define make_matchstate(_Ms) make_boxed((Eterm*)(_Ms)) -#define ms_matchbuffer(_Ms) &(((ErlBinMatchState*)(_Ms - TAG_PRIMARY_BOXED))->mb) +#define ms_matchbuffer(_Ms) &(((ErlBinMatchState*) boxed_val(_Ms))->mb) #if defined(ERTS_SMP) diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 15b1c6bb56..08c448882f 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -704,12 +704,13 @@ BIF_RETTYPE ets_update_element_3(BIF_ALIST_3) int cret = DB_ERROR_BADITEM; Eterm list; Eterm iter; - Eterm cell[2]; + DeclareTmpHeap(cell,2,BIF_P); DbUpdateHandle handle; if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_WRITE, LCK_WRITE_REC)) == NULL) { BIF_ERROR(BIF_P, BADARG); } + UseTmpHeap(2,BIF_P); if (!(tb->common.status & (DB_SET | DB_ORDERED_SET))) { goto bail_out; } @@ -762,6 +763,7 @@ finalize: tb->common.meth->db_finalize_dbterm(&handle); bail_out: + UnUseTmpHeap(2,BIF_P); db_unlock(tb, LCK_WRITE_REC); switch (cret) { @@ -794,8 +796,8 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3) Eterm* ret_list_currp = NULL; Eterm* ret_list_prevp = NULL; Eterm iter; - Eterm cell[2]; - Eterm tuple[3]; + DeclareTmpHeap(cell,5,BIF_P); + Eterm *tuple = cell+2; DbUpdateHandle handle; Uint halloc_size = 0; /* overestimated heap usage */ Eterm* htop; /* actual heap usage */ @@ -805,6 +807,9 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3) if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_WRITE, LCK_WRITE_REC)) == NULL) { BIF_ERROR(BIF_P, BADARG); } + + UseTmpHeap(5,BIF_P); + if (!(tb->common.status & (DB_SET | DB_ORDERED_SET))) { goto bail_out; } @@ -951,6 +956,7 @@ finalize: tb->common.meth->db_finalize_dbterm(&handle); bail_out: + UnUseTmpHeap(5,BIF_P); db_unlock(tb, LCK_WRITE_REC); switch (cret) { @@ -1185,7 +1191,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) Sint keypos; int is_named, is_fine_locked; int cret; - Eterm meta_tuple[3]; + DeclareTmpHeap(meta_tuple,3,BIF_P); DbTableMethod* meth; if (is_not_atom(BIF_ARG_1)) { @@ -1375,6 +1381,8 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) erts_smp_atomic_read(&meta_pid_to_fixed_tab->common.memory_size)); #endif + UseTmpHeap(3,BIF_P); + db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC); if (db_put_hash(meta_pid_to_tab, TUPLE2(meta_tuple, BIF_P->id, make_small(slot)), @@ -1383,6 +1391,8 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) } db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC); + UnUseTmpHeap(3,BIF_P); + BIF_RET(ret); } @@ -1519,7 +1529,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) } if (tb->common.owner != BIF_P->id) { - Eterm meta_tuple[3]; + DeclareTmpHeap(meta_tuple,3,BIF_P); /* * The table is being deleted by a process other than its owner. @@ -1527,6 +1537,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) * current process will be killed (e.g. by an EXIT signal), we will * now transfer the ownership to the current process. */ + UseTmpHeap(3,BIF_P); db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC); db_erase_bag_exact2(meta_pid_to_tab, tb->common.owner, make_small(tb->common.slot)); @@ -1538,6 +1549,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) TUPLE2(meta_tuple,BIF_P->id,make_small(tb->common.slot)), 0); db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC); + UnUseTmpHeap(3,BIF_P); } /* disable inheritance */ free_heir_data(tb); @@ -1571,7 +1583,7 @@ BIF_RETTYPE ets_give_away_3(BIF_ALIST_3) { Process* to_proc = NULL; ErtsProcLocks to_locks = ERTS_PROC_LOCK_MAIN; - Eterm buf[5]; + DeclareTmpHeap(buf,5,BIF_P); Eterm to_pid = BIF_ARG_2; Eterm from_pid; DbTable* tb = NULL; @@ -1593,6 +1605,7 @@ BIF_RETTYPE ets_give_away_3(BIF_ALIST_3) goto badarg; /* or should we be idempotent? return false maybe */ } + UseTmpHeap(5,BIF_P); db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC); db_erase_bag_exact2(meta_pid_to_tab, tb->common.owner, make_small(tb->common.slot)); @@ -1610,6 +1623,7 @@ BIF_RETTYPE ets_give_away_3(BIF_ALIST_3) TUPLE4(buf, am_ETS_TRANSFER, tb->common.id, from_pid, BIF_ARG_3), 0); erts_smp_proc_unlock(to_proc, to_locks); + UnUseTmpHeap(5,BIF_P); BIF_RET(am_true); badarg: @@ -1626,9 +1640,10 @@ BIF_RETTYPE ets_setopts_2(BIF_ALIST_2) Eterm heir = THE_NON_VALUE; Eterm heir_data = THE_NON_VALUE; Uint32 protection = 0; - Eterm fakelist[2]; + DeclareTmpHeap(fakelist,2,BIF_P); Eterm tail; + UseTmpHeap(2,BIF_P); for (tail = is_tuple(BIF_ARG_2) ? CONS(fakelist, BIF_ARG_2, NIL) : BIF_ARG_2; is_list(tail); tail = CDR(list_val(tail))) { @@ -1681,9 +1696,11 @@ BIF_RETTYPE ets_setopts_2(BIF_ALIST_2) } db_unlock (tb,LCK_WRITE); + UnUseTmpHeap(2,BIF_P); BIF_RET(am_true); badarg: + UnUseTmpHeap(2,BIF_P); if (tb != NULL) { db_unlock(tb,LCK_WRITE); } @@ -1949,29 +1966,37 @@ BIF_RETTYPE ets_match_1(BIF_ALIST_1) BIF_RETTYPE ets_match_2(BIF_ALIST_2) { Eterm ms; - Eterm buff[8]; + DeclareTmpHeap(buff,8,BIF_P); Eterm *hp = buff; - /*hp = HAlloc(BIF_P, 8);*/ + Eterm res; + + UseTmpHeap(8,BIF_P); ms = CONS(hp, am_DollarDollar, NIL); hp += 2; ms = TUPLE3(hp, BIF_ARG_2, NIL, ms); hp += 4; ms = CONS(hp, ms, NIL); - return ets_select_2(BIF_P, BIF_ARG_1, ms); + res = ets_select_2(BIF_P, BIF_ARG_1, ms); + UnUseTmpHeap(8,BIF_P); + return res; } BIF_RETTYPE ets_match_3(BIF_ALIST_3) { Eterm ms; - Eterm buff[8]; + DeclareTmpHeap(buff,8,BIF_P); Eterm *hp = buff; - /*hp = HAlloc(BIF_P, 8);*/ + Eterm res; + + UseTmpHeap(8,BIF_P); ms = CONS(hp, am_DollarDollar, NIL); hp += 2; ms = TUPLE3(hp, BIF_ARG_2, NIL, ms); hp += 4; ms = CONS(hp, ms, NIL); - return ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3); + res = ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3); + UnUseTmpHeap(8,BIF_P); + return res; } @@ -2385,29 +2410,37 @@ BIF_RETTYPE ets_match_object_1(BIF_ALIST_1) BIF_RETTYPE ets_match_object_2(BIF_ALIST_2) { Eterm ms; - Eterm buff[8]; + DeclareTmpHeap(buff,8,BIF_P); Eterm *hp = buff; - /*hp = HAlloc(BIF_P, 8);*/ + Eterm res; + + UseTmpHeap(8,BIF_P); ms = CONS(hp, am_DollarUnderscore, NIL); hp += 2; ms = TUPLE3(hp, BIF_ARG_2, NIL, ms); hp += 4; ms = CONS(hp, ms, NIL); - return ets_select_2(BIF_P, BIF_ARG_1, ms); + res = ets_select_2(BIF_P, BIF_ARG_1, ms); + UnUseTmpHeap(8,BIF_P); + return res; } BIF_RETTYPE ets_match_object_3(BIF_ALIST_3) { Eterm ms; - Eterm buff[8]; + DeclareTmpHeap(buff,8,BIF_P); Eterm *hp = buff; - /*hp = HAlloc(BIF_P, 8);*/ + Eterm res; + + UseTmpHeap(8,BIF_P); ms = CONS(hp, am_DollarUnderscore, NIL); hp += 2; ms = TUPLE3(hp, BIF_ARG_2, NIL, ms); hp += 4; ms = CONS(hp, ms, NIL); - return ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3); + res = ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3); + UnUseTmpHeap(8,BIF_P); + return res; } /* @@ -2843,7 +2876,7 @@ static int give_away_to_heir(Process* p, DbTable* tb) { Process* to_proc; ErtsProcLocks to_locks = ERTS_PROC_LOCK_MAIN; - Eterm buf[5]; + DeclareTmpHeap(buf,5,p); Eterm to_pid; Eterm heir_data; @@ -2888,6 +2921,7 @@ retry: erts_smp_proc_unlock(to_proc, to_locks); return 0; /* heir dead and pid reused, table still mine */ } + UseTmpHeap(5,p); db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC); db_erase_bag_exact2(meta_pid_to_tab, tb->common.owner, make_small(tb->common.slot)); @@ -2899,7 +2933,7 @@ retry: TUPLE2(buf,to_pid,make_small(tb->common.slot)), 0); db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC); - + UnUseTmpHeap(5,p); db_unlock(tb,LCK_WRITE); heir_data = tb->common.heir_data; if (!is_immed(heir_data)) { @@ -3145,7 +3179,7 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) static void fix_table_locked(Process* p, DbTable* tb) { DbFixation *fix; - Eterm meta_tuple[3]; + DeclareTmpHeap(meta_tuple,3,p); #ifdef ERTS_SMP erts_smp_mtx_lock(&tb->common.fixlock); @@ -3179,12 +3213,15 @@ static void fix_table_locked(Process* p, DbTable* tb) erts_smp_mtx_unlock(&tb->common.fixlock); #endif p->flags |= F_USING_DB; + UseTmpHeap(3,p); db_meta_lock(meta_pid_to_fixed_tab, LCK_WRITE_REC); if (db_put_hash(meta_pid_to_fixed_tab, TUPLE2(meta_tuple, p->id, make_small(tb->common.slot)), 0) != DB_ERROR_NONE) { + UnUseTmpHeap(3,p); erl_exit(1,"Could not insert ets metadata in safe_fixtable."); } + UnUseTmpHeap(3,p); db_meta_unlock(meta_pid_to_fixed_tab, LCK_WRITE_REC); } @@ -3285,10 +3322,13 @@ static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data) } if (!is_immed(heir_data)) { - Eterm tmp[2]; + DeclareTmpHeap(tmp,2,me); + + UseTmpHeap(2,me); /* Make a dummy 1-tuple around data to use db_get_term() */ heir_data = (Eterm) db_get_term(&tb->common, NULL, 0, TUPLE1(tmp,heir_data)); + UnUseTmpHeap(2,me); ASSERT(!is_immed(heir_data)); } tb->common.heir_data = heir_data; diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 8c373451fd..de12b9bdbf 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -2300,7 +2300,7 @@ void db_free_dmc_err_info(DMCErrInfo *ei){ */ Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr) { - Eterm big_tmp[2]; + DeclareTmpHeapNoproc(big_tmp,2); Eterm res; Sint ires; Eterm arg1; @@ -2318,6 +2318,7 @@ Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr) } } else { + UseTmpHeapNoproc(2); switch(NUMBER_CODE(counter, incr)) { case SMALL_BIG: arg1 = small_to_big(signed_val(counter), big_tmp); @@ -2332,12 +2333,14 @@ Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr) arg2 = counter; break; default: + UnUseTmpHeapNoproc(2); return THE_NON_VALUE; } res = big_plus(arg1, arg2, *hpp); if (is_big(res)) { *hpp += BIG_NEED_SIZE(big_size(res)); } + UnUseTmpHeapNoproc(2); return res; } } diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c index e5c3c76fdd..99b05fcf26 100644 --- a/erts/emulator/beam/erl_debug.c +++ b/erts/emulator/beam/erl_debug.c @@ -895,5 +895,29 @@ void print_memory_info(Process *p) #endif erts_printf("+-----------------%s-%s-%s-%s-+\n",dashes,dashes,dashes,dashes); } +#if !HEAP_ON_C_STACK && defined(DEBUG) +Eterm *erts_debug_allocate_tmp_heap(int size, Process *p) +{ + ErtsSchedulerData *sd = ((p == NULL) ? erts_get_scheduler_data() : ERTS_PROC_GET_SCHDATA(p)); + int offset = sd->num_tmp_heap_used; + + ASSERT(offset+size <= TMP_HEAP_SIZE); + return (sd->tmp_heap)+offset; +} +void erts_debug_use_tmp_heap(int size, Process *p) +{ + ErtsSchedulerData *sd = ((p == NULL) ? erts_get_scheduler_data() : ERTS_PROC_GET_SCHDATA(p)); + + sd->num_tmp_heap_used += size; + ASSERT(sd->num_tmp_heap_used <= TMP_HEAP_SIZE); +} +void erts_debug_unuse_tmp_heap(int size, Process *p) +{ + ErtsSchedulerData *sd = ((p == NULL) ? erts_get_scheduler_data() : ERTS_PROC_GET_SCHDATA(p)); + + sd->num_tmp_heap_used -= size; + ASSERT(sd->num_tmp_heap_used >= 0); +} +#endif #endif diff --git a/erts/emulator/beam/erl_debug.h b/erts/emulator/beam/erl_debug.h index 74f4a00b63..b69f2c52cd 100644 --- a/erts/emulator/beam/erl_debug.h +++ b/erts/emulator/beam/erl_debug.h @@ -18,9 +18,10 @@ */ #ifndef _ERL_DEBUG_H_ #define _ERL_DEBUG_H_ - #ifdef DEBUG +#include "erl_term.h" + #ifdef HIPE #include "hipe_debug.h" #endif @@ -92,6 +93,11 @@ extern void print_tagged_memory(Eterm *start, Eterm *end); extern void print_untagged_memory(Eterm *start, Eterm *end); extern void print_memory(Process *p); extern void print_memory_info(Process *p); +#if defined(DEBUG) && !HEAP_ON_C_STACK +extern Eterm *erts_debug_allocate_tmp_heap(int, Process *); +extern void erts_debug_use_tmp_heap(int, Process *); +extern void erts_debug_unuse_tmp_heap(int, Process *); +#endif #ifdef HYBRID extern void print_ma_info(void); diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 074b08ea57..4858be1b75 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -1231,6 +1231,8 @@ void erts_lc_init_lock(erts_lc_lock_t *lck, char *name, Uint16 flags) { lck->id = erts_lc_get_lock_order_id(name); + + /* XXX:PaN What to do with the extra information? */ lck->extra = make_boxed(&lck->extra); lck->flags = flags; lck->inited = ERTS_LC_INITITALIZED; diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 42b28d987c..f3f10201b5 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -1109,9 +1109,10 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) break; } if (insert_bin) { - Uint id_heap[BIG_UINT_HEAP_SIZE]; + DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE); Uint *hp = &id_heap[0]; InsertedBin *nib; + UseTmpHeapNoproc(BIG_UINT_HEAP_SIZE); a.id = erts_bld_uint(&hp, NULL, (Uint) pb->val); erts_match_prog_foreach_offheap(pb->val, insert_offheap2, @@ -1120,6 +1121,7 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) nib->bin_val = pb->val; nib->next = inserted_bins; inserted_bins = nib; + UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE); } } } @@ -1190,12 +1192,15 @@ static void insert_bif_timer(Eterm receiver, Eterm msg, ErlHeapFragment *bp, void *arg) { if (bp) { - Eterm heap[3]; + DeclareTmpHeapNoproc(heap,3); + + UseTmpHeapNoproc(3); insert_offheap(&bp->off_heap, TIMER_REF, (is_internal_pid(receiver) ? receiver : TUPLE2(&heap[0], AM_process, receiver))); + UnUseTmpHeapNoproc(3); } } @@ -1230,7 +1235,7 @@ setup_reference_table(void) DistEntry *dep; HashInfo hi; int i; - Eterm heap[3]; + DeclareTmpHeapNoproc(heap,3); inserted_bins = NULL; @@ -1251,6 +1256,7 @@ setup_reference_table(void) /* Go through the hole system, and build a table of all references to ErlNode and DistEntry structures */ + UseTmpHeapNoproc(3); insert_node(erts_this_node, SYSTEM_REF, TUPLE2(&heap[0], AM_system, am_undefined)); @@ -1261,6 +1267,7 @@ setup_reference_table(void) HEAP_REF, TUPLE2(&heap[0], AM_processes, am_undefined)); #endif + UnUseTmpHeapNoproc(3); /* Insert all processes */ for (i = 0; i < erts_max_processes; i++) diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 996806fc75..f5b1308ca4 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -2186,6 +2186,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) erts_bits_init_state(&esdp->erl_bits_state); esdp->match_pseudo_process = NULL; esdp->free_process = NULL; +#endif +#if !HEAP_ON_C_STACK + esdp->num_tmp_heap_used = 0; #endif esdp->no = (Uint) ix+1; esdp->current_process = NULL; @@ -7778,9 +7781,10 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext) erts_port_release(prt); } else if (is_internal_pid(mon->pid)) {/* local by name or pid */ Eterm watched; - Eterm lhp[3]; + DeclareTmpHeapNoproc(lhp,3); ErtsProcLocks rp_locks = (ERTS_PROC_LOCK_LINK | ERTS_PROC_LOCKS_MSG_SEND); + UseTmpHeapNoproc(3); rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks); if (rp == NULL) { goto done; @@ -7795,6 +7799,7 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext) erts_queue_monitor_message(rp, &rp_locks, mon->ref, am_process, watched, pcontext->reason); } + UnUseTmpHeapNoproc(3); /* else: demonitor while we exited, i.e. do nothing... */ erts_smp_proc_unlock(rp, rp_locks); } else { /* external by pid or name */ @@ -8228,11 +8233,12 @@ continue_exit_process(Process *p * Pre-build the EXIT tuple if there are any links. */ if (lnk) { - Eterm tmp_heap[4]; + DeclareTmpHeap(tmp_heap,4,p); Eterm exit_tuple; Uint exit_tuple_sz; Eterm* hp; + UseTmpHeap(4,p); hp = &tmp_heap[0]; exit_tuple = TUPLE3(hp, am_EXIT, p->id, reason); @@ -8243,11 +8249,13 @@ continue_exit_process(Process *p ExitLinkContext context = {p, reason, exit_tuple, exit_tuple_sz}; erts_sweep_links(lnk, &doit_exit_link, &context); } + UnUseTmpHeap(4,p); } { ExitMonitorContext context = {reason, p}; - erts_sweep_monitors(mon,&doit_exit_monitor,&context); + erts_sweep_monitors(mon,&doit_exit_monitor,&context); /* Allocates TmpHeap, but we + have none here */ } if (scb) diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index f58b6932b3..4466442fbc 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -351,6 +351,13 @@ struct ErtsSchedulerData_ { void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */ Process *free_process; #endif +#if !HEAP_ON_C_STACK + Eterm tmp_heap[TMP_HEAP_SIZE]; + int num_tmp_heap_used; + Eterm beam_emu_tmp_heap[BEAM_EMU_TMP_HEAP_SIZE]; + Eterm cmp_tmp_heap[CMP_TMP_HEAP_SIZE]; + Eterm erl_arith_tmp_heap[ERL_ARITH_TMP_HEAP_SIZE]; +#endif Process *current_process; Uint no; /* Scheduler number */ diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c index 2924abbd51..c0ed3cb0a6 100644 --- a/erts/emulator/beam/erl_term.c +++ b/erts/emulator/beam/erl_term.c @@ -68,7 +68,9 @@ unsigned tag_val_def(Eterm x) static char msg[32]; switch (x & _TAG_PRIMARY_MASK) { - case TAG_PRIMARY_LIST: return LIST_DEF; + case TAG_PRIMARY_LIST: + ET_ASSERT(_list_precond(x),file,line); + return LIST_DEF; case TAG_PRIMARY_BOXED: { Eterm hdr = *boxed_val(x); ET_ASSERT(is_header(hdr),file,line); @@ -121,12 +123,12 @@ FUNTY checked_##FUN(ARGTY x, const char *file, unsigned line) \ return _unchecked_##FUN(x); \ } -ET_DEFINE_CHECKED(Eterm,make_boxed,Eterm*,_is_aligned); +ET_DEFINE_CHECKED(Eterm,make_boxed,Eterm*,_is_taggable_pointer); ET_DEFINE_CHECKED(int,is_boxed,Eterm,!is_header); -ET_DEFINE_CHECKED(Eterm*,boxed_val,Eterm,is_boxed); -ET_DEFINE_CHECKED(Eterm,make_list,Eterm*,_is_aligned); +ET_DEFINE_CHECKED(Eterm*,boxed_val,Eterm,_boxed_precond); +ET_DEFINE_CHECKED(Eterm,make_list,Eterm*,_is_taggable_pointer); ET_DEFINE_CHECKED(int,is_not_list,Eterm,!is_header); -ET_DEFINE_CHECKED(Eterm*,list_val,Eterm,is_list); +ET_DEFINE_CHECKED(Eterm*,list_val,Eterm,_list_precond); ET_DEFINE_CHECKED(Uint,unsigned_val,Eterm,is_small); ET_DEFINE_CHECKED(Sint,signed_val,Eterm,is_small); ET_DEFINE_CHECKED(Uint,atom_val,Eterm,is_atom); @@ -163,7 +165,7 @@ ET_DEFINE_CHECKED(Uint32*,external_ref_data,Eterm,is_external_ref); ET_DEFINE_CHECKED(struct erl_node_*,external_ref_node,Eterm,is_external_ref); ET_DEFINE_CHECKED(Eterm*,export_val,Eterm,is_export); -ET_DEFINE_CHECKED(Eterm,make_cp,Uint*,_is_aligned); +ET_DEFINE_CHECKED(Eterm,make_cp,Uint*,_is_taggable_pointer); ET_DEFINE_CHECKED(Uint*,cp_val,Eterm,is_CP); ET_DEFINE_CHECKED(Uint,catch_val,Eterm,is_catch); ET_DEFINE_CHECKED(Uint,x_reg_offset,Uint,_is_xreg); diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index a6596558fa..016d6e66a7 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -20,6 +20,35 @@ #ifndef __ERL_TERM_H #define __ERL_TERM_H +#ifdef ARCH_64 +#define HALFWORD_HEAP 1 +#define HALFWORD_ASSERT 1 +#endif + +#if HALFWORD_HEAP +# define HEAP_ON_C_STACK 0 +# if HALFWORD_ASSERT +# ifdef ET_DEBUG +# undef ET_DEBUG +# endif +# define ET_DEBUG 1 +# endif +# if 1 +# define CHECK_POINTER_MASK 0xFFFFFFFF00000000UL +# define COMPRESS_POINTER(AnUint) (AnUint) +# define EXPAND_POINTER(APointer) (APointer) +# else +# define CHECK_POINTER_MASK 0x0UL +# define COMPRESS_POINTER(AnUint) (AnUint) +# define EXPAND_POINTER(APointer) (APointer) +# endif +#else +# define HEAP_ON_C_STACK 1 +# define CHECK_POINTER_MASK 0x0UL +# define COMPRESS_POINTER(AnUint) (AnUint) +# define EXPAND_POINTER(APointer) (APointer) +#endif + struct erl_node_; /* Declared in erl_node_tables.h */ /* @@ -158,9 +187,16 @@ struct erl_node_; /* Declared in erl_node_tables.h */ /* boxed object access methods */ +#if HALFWORD_HEAP +#define _is_taggable_pointer(x) (((Uint)(x) & (CHECK_POINTER_MASK | 0x3)) == 0) +#define _boxed_precond(x) (is_boxed(x)) +#else +#define _is_taggable_pointer(x) (((Uint)(x) & 0x3) == 0) +#define _boxed_precond(x) (is_boxed(x)) +#endif #define _is_aligned(x) (((Uint)(x) & 0x3) == 0) -#define _unchecked_make_boxed(x) ((Uint)(x) + TAG_PRIMARY_BOXED) -_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*) +#define _unchecked_make_boxed(x) COMPRESS_POINTER((Uint)(x) + TAG_PRIMARY_BOXED) +_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*); #define make_boxed(x) _ET_APPLY(make_boxed,(x)) #if 1 #define _is_not_boxed(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED)) @@ -170,13 +206,13 @@ _ET_DECLARE_CHECKED(int,is_boxed,Eterm) #else #define is_boxed(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED) #endif -#define _unchecked_boxed_val(x) ((Eterm*)((x) - TAG_PRIMARY_BOXED)) -_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm) +#define _unchecked_boxed_val(x) EXPAND_POINTER((Eterm*)((x) - TAG_PRIMARY_BOXED)) +_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm); #define boxed_val(x) _ET_APPLY(boxed_val,(x)) /* cons cell ("list") access methods */ -#define _unchecked_make_list(x) ((Uint)(x) + TAG_PRIMARY_LIST) -_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*) +#define _unchecked_make_list(x) COMPRESS_POINTER((Uint)(x) + TAG_PRIMARY_LIST) +_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*); #define make_list(x) _ET_APPLY(make_list,(x)) #if 1 #define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST)) @@ -187,8 +223,13 @@ _ET_DECLARE_CHECKED(int,is_not_list,Eterm) #define is_list(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_LIST) #define is_not_list(x) (!is_list((x))) #endif -#define _unchecked_list_val(x) ((Eterm*)((x) - TAG_PRIMARY_LIST)) -_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm) +#if HALFWORD_HEAP +#define _list_precond(x) (is_list(x)) +#else +#define _list_precond(x) (is_list(x)) +#endif +#define _unchecked_list_val(x) EXPAND_POINTER((Eterm*)((x) - TAG_PRIMARY_LIST)) +_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm); #define list_val(x) _ET_APPLY(list_val,(x)) #define CONS(hp, car, cdr) \ @@ -198,7 +239,7 @@ _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm) #define CDR(x) ((x)[1]) /* generic tagged pointer (boxed or list) access methods */ -#define _unchecked_ptr_val(x) ((Eterm*)((x) & ~((Uint) 0x3))) +#define _unchecked_ptr_val(x) EXPAND_POINTER((Eterm*)((x) & ~((Uint) 0x3))) #define ptr_val(x) _unchecked_ptr_val((x)) /*XXX*/ #define _unchecked_offset_ptr(x,offs) ((x)+((offs)*sizeof(Eterm))) #define offset_ptr(x,offs) _unchecked_offset_ptr(x,offs) /*XXX*/ diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index 2842c2361a..f98d5ee522 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -397,11 +397,13 @@ WRITE_SYS_MSG_TO_PORT(Eterm unused_to, */ static void do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) { - Eterm local_heap[4+5+5]; +#define LOCAL_HEAP_SIZE (4+5+5) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); Eterm message; Eterm *hp; Eterm mfarity; + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); ASSERT(is_pid(pid)); ASSERT(is_tuple(timestamp)); ASSERT(*tuple_val(timestamp) == make_arityval(3)); @@ -426,6 +428,8 @@ do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) { pid, SYS_MSG_TYPE_UNDEFINED, message); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE } #endif @@ -442,7 +446,9 @@ send_to_port(Process *c_p, Eterm message, Eterm *tracer_pid, Uint *tracee_flags) { Port* trace_port; #ifndef ERTS_SMP - Eterm ts, local_heap[4], *hp; +#define LOCAL_HEAP_SIZE (4) + Eterm ts, *hp; + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); #endif ASSERT(is_internal_port(*tracer_pid)); @@ -486,6 +492,8 @@ send_to_port(Process *c_p, Eterm message, * (e.g. getting_linked) need not be the current process. That other * process might not have timestamps enabled. */ + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + if (*tracee_flags & F_TIMESTAMP) { ASSERT(is_tuple(message)); hp = tuple_val(message); @@ -522,6 +530,8 @@ send_to_port(Process *c_p, Eterm message, */ do_send_schedfix_to_port(trace_port, c_p->id, ts); } + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE #endif } @@ -589,7 +599,10 @@ seq_trace_send_to_port(Process *c_p, { Port* trace_port; #ifndef ERTS_SMP - Eterm ts, local_heap[4], *hp; + Eterm ts, *hp; +#define LOCAL_HEAP_SIZE (4) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); #endif ASSERT(is_internal_port(seq_tracer)); @@ -607,6 +620,9 @@ seq_trace_send_to_port(Process *c_p, if (INVALID_TRACER_PORT(trace_port, seq_tracer)) { invalid_tracer_port: system_seq_tracer = am_false; +#ifndef ERTS_SMP + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#endif return; } @@ -620,6 +636,7 @@ seq_trace_send_to_port(Process *c_p, message); #ifndef ERTS_SMP + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); return; } /* Make a fake schedule only if the current process is traced @@ -660,6 +677,8 @@ seq_trace_send_to_port(Process *c_p, */ do_send_schedfix_to_port(trace_port, c_p->id, ts); } + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE #endif } @@ -719,7 +738,8 @@ send_to_tracer(Process *tracee, static void trace_sched_aux(Process *p, Eterm what, int never_fake_sched) { - Eterm local_heap[5+4+1+TS_HEAP_WORDS]; +#define LOCAL_HEAP_SIZE (5+4+1+TS_HEAP_WORDS) + DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p); Eterm tmp, mess, *hp; ErlHeapFragment *bp = NULL; ErlOffHeap *off_heap; @@ -768,8 +788,10 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched) curr_func = p->current != NULL; } + UseTmpHeap(LOCAL_HEAP_SIZE,p); + if (to_port) - hp = &local_heap[0]; + hp = local_heap; else { Uint size = 5; if (curr_func) @@ -802,6 +824,8 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched) } send_to_tracer(p, tracer_ref, mess, &hp, bp, no_fake_sched); + UnUseTmpHeap(LOCAL_HEAP_SIZE,p); +#undef LOCAL_HEAP_SIZE } /* Send {trace_ts, Pid, What, {Mod, Func, Arity}, Timestamp} @@ -848,7 +872,10 @@ trace_send(Process *p, Eterm to, Eterm msg) } if (is_internal_port(p->tracer_proc)) { - Eterm local_heap[11]; +#define LOCAL_HEAP_SIZE (11) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mess = TUPLE5(hp, am_trace, p->id, operation, msg, to); hp += 6; @@ -857,6 +884,8 @@ trace_send(Process *p, Eterm to, Eterm msg) hp = patch_ts(mess, hp); } send_to_port(p, mess, &p->tracer_proc, &p->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { Uint need; @@ -908,7 +937,10 @@ trace_receive(Process *rp, Eterm msg) Eterm* hp; if (is_internal_port(rp->tracer_proc)) { - Eterm local_heap[10]; +#define LOCAL_HEAP_SIZE (10) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mess = TUPLE4(hp, am_trace, rp->id, am_receive, msg); hp += 5; @@ -917,6 +949,8 @@ trace_receive(Process *rp, Eterm msg) hp = patch_ts(mess, hp); } send_to_port(rp, mess, &rp->tracer_proc, &rp->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { Uint hsz; @@ -1018,7 +1052,10 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type, } if (is_internal_port(seq_tracer)) { - Eterm local_heap[64]; +#define LOCAL_HEAP_SIZE (64) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; label = SEQ_TRACE_T_LABEL(token); lastcnt_serial = TUPLE2(hp, SEQ_TRACE_T_LASTCNT(token), @@ -1043,6 +1080,8 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type, mess = TUPLE4(hp, am_seq_trace, label, mess, ts); seq_trace_send_to_port(process, seq_tracer, mess, ts); } + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { #ifndef ERTS_SMP @@ -1145,13 +1184,17 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type, void erts_trace_return_to(Process *p, Uint *pc) { +#define LOCAL_HEAP_SIZE (4+5+5) Eterm* hp; Eterm mfa; Eterm mess; - Eterm local_heap[4+5+5]; + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); Eterm *code_ptr = find_function_from_pc(pc); + + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; if (!code_ptr) { @@ -1196,6 +1239,8 @@ erts_trace_return_to(Process *p, Uint *pc) mess = copy_struct(mess, size, &hp, off_heap); ERTS_ENQ_TRACE_MSG(p->id, tracer_ref, mess, bp); } + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } @@ -1262,7 +1307,9 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid) arity = fi[2]; if (is_internal_port(*tracer_pid)) { - Eterm local_heap[4+6+5]; +#define LOCAL_HEAP_SIZE (4+6+5) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); hp = local_heap; mfa = TUPLE3(hp, mod, name, make_small(arity)); hp += 4; @@ -1273,6 +1320,8 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid) hp = patch_ts(mess, hp); } send_to_port(p, mess, tracer_pid, tracee_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { ErlHeapFragment *bp; @@ -1385,7 +1434,10 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value, } if (is_internal_port(*tracer_pid)) { - Eterm local_heap[4+3+6+5]; +#define LOCAL_HEAP_SIZE (4+3+6+5) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2])); hp += 4; @@ -1393,13 +1445,15 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value, hp += 3; mess = TUPLE5(hp, am_trace, p->id, am_exception_from, mfa_tuple, cv); hp += 6; - ASSERT((hp - local_heap)*sizeof(*hp) <= sizeof(local_heap)); + ASSERT((hp - local_heap) <= LOCAL_HEAP_SIZE); erts_smp_mtx_lock(&smq_mtx); if (*tracee_flags & F_TIMESTAMP) { hp = patch_ts(mess, hp); /* hp += 5 */ - ASSERT((hp - local_heap)*sizeof(*hp) == sizeof(local_heap)); + ASSERT((hp - local_heap) == LOCAL_HEAP_SIZE); } send_to_port(p, mess, tracer_pid, tracee_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { ErlHeapFragment *bp; @@ -1483,7 +1537,8 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, Eterm tracee; #endif Eterm transformed_args[MAX_ARG]; - ErlSubBin sub_bin_heap; + DeclareTmpHeap(sub_bin_heap_et,ERL_SUB_BIN_SIZE,p); + ErlSubBin *sub_bin_heap = (ErlSubBin *) sub_bin_heap_et; ASSERT(tracer_pid); if (*tracer_pid == am_true) { @@ -1535,18 +1590,19 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, * temporarily convert any match contexts to sub binaries. */ arity = mfa[2]; + UseTmpHeap(ERL_SUB_BIN_SIZE,p); #ifdef DEBUG - sub_bin_heap.thing_word = 0; + sub_bin_heap->thing_word = 0; #endif for (i = 0; i < arity; i++) { Eterm arg = args[i]; if (is_boxed(arg) && header_is_bin_matchstate(*boxed_val(arg))) { ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(arg); ErlBinMatchBuffer* mb = &ms->mb; - ErlSubBin* sb = &sub_bin_heap; + ErlSubBin* sb = sub_bin_heap; Uint bit_size; - ASSERT(sub_bin_heap.thing_word == 0); /* At most one of match context */ + ASSERT(sub_bin_heap->thing_word == 0); /* At most one of match context */ bit_size = mb->size - mb->offset; sb->thing_word = HEADER_SUB_BIN; @@ -1564,7 +1620,12 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, args = transformed_args; if (is_internal_port(*tracer_pid)) { +#if HEAP_ON_C_STACK Eterm local_heap[64+MAX_ARG]; +#else + Eterm *local_heap = erts_alloc(ERTS_ALC_T_TEMP_TERM, + sizeof(Eterm)*(64+MAX_ARG)); +#endif hp = local_heap; if (!erts_is_valid_tracer_port(*tracer_pid)) { @@ -1579,6 +1640,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, if (is_not_nil(tracee)) erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR); #endif +#if !HEAP_ON_C_STACK + erts_free(ERTS_ALC_T_TEMP_TERM,local_heap); +#endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return 0; } @@ -1605,6 +1670,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, &return_flags); if (is_non_value(pam_result)) { erts_match_set_release_result(p); +#if !HEAP_ON_C_STACK + erts_free(ERTS_ALC_T_TEMP_TERM,local_heap); +#endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return 0; } } @@ -1612,16 +1681,28 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, /* Meta trace */ if (pam_result == am_false) { erts_match_set_release_result(p); +#if !HEAP_ON_C_STACK + erts_free(ERTS_ALC_T_TEMP_TERM,local_heap); +#endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return return_flags; } } else { /* Non-meta trace */ if (*tracee_flags & F_TRACE_SILENT) { erts_match_set_release_result(p); +#if !HEAP_ON_C_STACK + erts_free(ERTS_ALC_T_TEMP_TERM,local_heap); +#endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return 0; } if (pam_result == am_false) { erts_match_set_release_result(p); +#if !HEAP_ON_C_STACK + erts_free(ERTS_ALC_T_TEMP_TERM,local_heap); +#endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return return_flags; } if (local && (*tracee_flags & F_TRACE_RETURN_TO)) { @@ -1664,6 +1745,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, send_to_port(p, mess, tracer_pid, tracee_flags); erts_smp_mtx_unlock(&smq_mtx); erts_match_set_release_result(p); +#if !HEAP_ON_C_STACK + erts_free(ERTS_ALC_T_TEMP_TERM,local_heap); +#endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return *tracer_pid == NIL ? 0 : return_flags; } else { @@ -1706,6 +1791,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, if (is_not_nil(tracee)) erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR); #endif + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return 0; } @@ -1731,6 +1817,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, &return_flags); if (is_non_value(pam_result)) { erts_match_set_release_result(p); + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return 0; } } @@ -1738,16 +1825,19 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, /* Meta trace */ if (pam_result == am_false) { erts_match_set_release_result(p); + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return return_flags; } } else { /* Non-meta trace */ if (*tracee_flags & F_TRACE_SILENT) { erts_match_set_release_result(p); + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return 0; } if (pam_result == am_false) { erts_match_set_release_result(p); + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return return_flags; } if (local && (*tracee_flags & F_TRACE_RETURN_TO)) { @@ -1831,6 +1921,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, ASSERT(hp == limit); ERTS_ENQ_TRACE_MSG(tracee, tracer_ref, mess, bp); erts_smp_mtx_unlock(&smq_mtx); + UnUseTmpHeap(ERL_SUB_BIN_SIZE,p); return return_flags; } } @@ -1851,7 +1942,10 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data) int need; if (is_internal_port(t_p->tracer_proc)) { - Eterm local_heap[5+5]; +#define LOCAL_HEAP_SIZE (5+5) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mess = TUPLE4(hp, am_trace, t_p->id, what, data); hp += 5; @@ -1868,6 +1962,8 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data) c_p, #endif mess, &t_p->tracer_proc, &t_p->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { Eterm tmp; @@ -1919,7 +2015,10 @@ trace_proc_spawn(Process *p, Eterm pid, Eterm* hp; if (is_internal_port(p->tracer_proc)) { - Eterm local_heap[4+6+5]; +#define LOCAL_HEAP_SIZE (4+6+5) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mfa = TUPLE3(hp, mod, func, args); hp += 4; @@ -1930,6 +2029,8 @@ trace_proc_spawn(Process *p, Eterm pid, hp = patch_ts(mess, hp); } send_to_port(p, mess, &p->tracer_proc, &p->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { Eterm tmp; @@ -2078,7 +2179,8 @@ erts_bif_trace(int bif_index, Process* p, if (reason != TRAP) { Eterm class; Eterm value = p->fvalue; - Eterm nocatch[3]; + DeclareTmpHeapNoproc(nocatch,3); + UseTmpHeapNoproc(3); /* Expand error value like in handle_error() */ if (reason & EXF_ARGLIST) { Eterm *tp; @@ -2126,6 +2228,7 @@ erts_bif_trace(int bif_index, Process* p, } } } + UnUseTmpHeapNoproc(3); if ((flags_meta|flags) & MATCH_SET_EXCEPTION_TRACE) { erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR); p->trace_flags |= F_EXCEPTION_TRACE; @@ -2213,15 +2316,19 @@ trace_gc(Process *p, Eterm what) BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p) }; - Eterm local_heap[(sizeof(values)/sizeof(Uint)) - *(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) - + 5/*4-tuple */ + TS_HEAP_WORDS]; +#define LOCAL_HEAP_SIZE \ + (sizeof(values)/sizeof(Eterm)) * \ + (2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) + \ + 5/*4-tuple */ + TS_HEAP_WORDS + DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p); #ifdef DEBUG Eterm* limit; #endif ASSERT(sizeof(values)/sizeof(Uint) == sizeof(tags)/sizeof(Eterm)); + UseTmpHeap(LOCAL_HEAP_SIZE,p); + if (is_internal_port(p->tracer_proc)) { hp = local_heap; #ifdef DEBUG @@ -2252,7 +2359,7 @@ trace_gc(Process *p, Eterm what) #ifdef DEBUG limit = hp + size; - ASSERT(size <= sizeof(local_heap)/sizeof(Eterm)); + ASSERT(size <= LOCAL_HEAP_SIZE); #endif msg = erts_bld_atom_uint_2tup_list(&hp, @@ -2275,6 +2382,8 @@ trace_gc(Process *p, Eterm what) else ERTS_ENQ_TRACE_MSG(p->id, tracer_ref, msg, bp); erts_smp_mtx_unlock(&smq_mtx); + UnUseTmpHeap(LOCAL_HEAP_SIZE,p); +#undef LOCAL_HEAP_SIZE } @@ -2465,7 +2574,9 @@ profile_scheduler(Eterm scheduler_id, Eterm state) { Uint Ms, s, us; #ifndef ERTS_SMP - Eterm local_heap[4 + 7]; +#define LOCAL_HEAP_SIZE (4 + 7) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); hp = local_heap; #else ErlHeapFragment *bp; @@ -2498,6 +2609,8 @@ profile_scheduler(Eterm scheduler_id, Eterm state) { #ifndef ERTS_SMP profile_send(msg); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE #else enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp); #endif @@ -2510,7 +2623,10 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M Eterm *hp, msg, timestamp; #ifndef ERTS_SMP - Eterm local_heap[4 + 7]; +#define LOCAL_HEAP_SIZE (4 + 7) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; #else ErlHeapFragment *bp; @@ -2528,6 +2644,8 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M msg = TUPLE6(hp, am_profile, am_scheduler, scheduler_id, state, no_schedulers, timestamp); hp += 7; #ifndef ERTS_SMP profile_send(msg); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE #else enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp); #endif @@ -2558,7 +2676,10 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) { Eterm* hp; if (is_internal_port(p->tracer_proc)) { - Eterm local_heap[5+6]; +#define LOCAL_HEAP_SIZE (5+6) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mess = TUPLE5(hp, am_trace, calling_pid, am_open, p->id, drv_name); @@ -2569,6 +2690,8 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) { } /* No fake schedule */ send_to_port(NULL, mess, &p->tracer_proc, &p->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { ErlHeapFragment *bp; @@ -2613,7 +2736,10 @@ trace_port(Port *t_p, Eterm what, Eterm data) { Eterm* hp; if (is_internal_port(t_p->tracer_proc)) { - Eterm local_heap[5+5]; +#define LOCAL_HEAP_SIZE (5+5) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; mess = TUPLE4(hp, am_trace, t_p->id, what, data); hp += 5; @@ -2623,6 +2749,8 @@ trace_port(Port *t_p, Eterm what, Eterm data) { } /* No fake schedule */ send_to_port(NULL, mess, &t_p->tracer_proc, &t_p->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { ErlHeapFragment *bp; @@ -2674,7 +2802,10 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) { Eterm sched_id = am_undefined; if (is_internal_port(p->tracer_proc)) { - Eterm local_heap[5+6]; +#define LOCAL_HEAP_SIZE (5+6) + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; if (IS_TRACED_FL(p, F_TRACE_SCHED_NO)) { @@ -2700,6 +2831,8 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) { /* No fake scheduling */ send_to_port(NULL, mess, &p->tracer_proc, &p->trace_flags); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE erts_smp_mtx_unlock(&smq_mtx); } else { ErlHeapFragment *bp; @@ -2750,7 +2883,11 @@ profile_runnable_port(Port *p, Eterm status) { Eterm count = make_small(0); #ifndef ERTS_SMP - Eterm local_heap[4 + 6]; +#define LOCAL_HEAP_SIZE (4 + 6) + + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; #else @@ -2771,6 +2908,8 @@ profile_runnable_port(Port *p, Eterm status) { #ifndef ERTS_SMP profile_send(msg); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE #else enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp); #endif @@ -2785,7 +2924,11 @@ profile_runnable_proc(Process *p, Eterm status){ Eterm where = am_undefined; #ifndef ERTS_SMP - Eterm local_heap[4 + 6 + 4]; +#define LOCAL_HEAP_SIZE (4 + 6 + 4) + + DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); + UseTmpHeapNoproc(LOCAL_HEAP_SIZE); + hp = local_heap; #else ErlHeapFragment *bp; @@ -2818,6 +2961,8 @@ profile_runnable_proc(Process *p, Eterm status){ msg = TUPLE5(hp, am_profile, p->id, status, where, timestamp); hp += 6; #ifndef ERTS_SMP profile_send(msg); + UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); +#undef LOCAL_HEAP_SIZE #else enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp); #endif diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h index 50b3e5b61c..1b61bca440 100644 --- a/erts/emulator/beam/erl_vm.h +++ b/erts/emulator/beam/erl_vm.h @@ -50,6 +50,15 @@ #define MAX_ARG 256 /* Max number of arguments allowed */ #define MAX_REG 1024 /* Max number of x(N) registers used */ +/* Scheduler stores data for temporary heaps if + !HEAP_ON_C_STACK. Macros (*TmpHeap*) in global.h selects if we put temporary + heap data on the C stack or if we use the buffers in the scheduler data. */ +#define TMP_HEAP_SIZE 128 /* Number of Eterm in the schedulers + small heap for transient heap data */ +#define CMP_TMP_HEAP_SIZE 2 /* cmp wants its own tmp-heap... */ +#define ERL_ARITH_TMP_HEAP_SIZE 4 /* as does erl_arith... */ +#define BEAM_EMU_TMP_HEAP_SIZE 2 /* and beam_emu... */ + /* * The new arithmetic operations need some extra X registers in the register array. */ diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 099eddd195..f7b498e414 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -1563,8 +1563,10 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) put_int32(val, ep); ep += 4; } else { - Eterm tmp_big[2]; - Eterm big = small_to_big(val, tmp_big); + DeclareTmpHeapNoproc(tmp_big,2); + Eterm big; + UseTmpHeapNoproc(2); + big = small_to_big(val, tmp_big); *ep++ = SMALL_BIG_EXT; n = big_bytes(big); ASSERT(n < 256); @@ -1572,6 +1574,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) ep += 1; *ep++ = big_sign(big); ep = big_to_bytes(big, ep); + UnUseTmpHeapNoproc(2); } } break; @@ -2650,9 +2653,11 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) else if (sizeof(Sint) == 4 || IS_SSMALL28(val)) result += 1 + 4; /* INTEGER_EXT */ else { - Eterm tmp_big[2]; + DeclareTmpHeapNoproc(tmp_big,2); + UseTmpHeapNoproc(2); i = big_bytes(small_to_big(val, tmp_big)); result += 1 + 1 + 1 + i; /* SMALL_BIG_EXT */ + UnUseTmpHeapNoproc(2); } } break; diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index cab249a53f..03e97a0ce4 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1839,4 +1839,61 @@ erts_alloc_message_heap(Uint size, #endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */ +#if !HEAP_ON_C_STACK +# if defined(DEBUG) +# define DeclareTmpHeap(VariableName,Size,Process) \ + Eterm *VariableName = erts_debug_allocate_tmp_heap(Size,Process) +# define DeclareTmpHeapNoproc(VariableName,Size) \ + Eterm *VariableName = erts_debug_allocate_tmp_heap(Size,NULL) +# define UseTmpHeap(Size,Proc) \ + do { \ + erts_debug_use_tmp_heap((Size),(Proc)); \ + } while (0) +# define UnUseTmpHeap(Size,Proc) \ + do { \ + erts_debug_unuse_tmp_heap((Size),(Proc)); \ + } while (0) +# define UseTmpHeapNoproc(Size) \ + do { \ + erts_debug_use_tmp_heap(Size,NULL); \ + } while (0) +# define UnUseTmpHeapNoproc(Size) \ + do { \ + erts_debug_unuse_tmp_heap(Size,NULL); \ + } while (0) +# else +# define DeclareTmpHeap(VariableName,Size,Process) \ + Eterm *VariableName = (ERTS_PROC_GET_SCHDATA(Process)->tmp_heap)+(ERTS_PROC_GET_SCHDATA(Process)->num_tmp_heap_used) +# define DeclareTmpHeapNoproc(VariableName,Size) \ + Eterm *VariableName = (erts_get_scheduler_data()->tmp_heap)+(erts_get_scheduler_data()->num_tmp_heap_used) +# define UseTmpHeap(Size,Proc) \ + do { \ + ERTS_PROC_GET_SCHDATA(Proc)->num_tmp_heap_used += (Size); \ + } while (0) +# define UnUseTmpHeap(Size,Proc) \ + do { \ + ERTS_PROC_GET_SCHDATA(Proc)->num_tmp_heap_used -= (Size); \ + } while (0) +# define UseTmpHeapNoproc(Size) \ + do { \ + erts_get_scheduler_data()->num_tmp_heap_used += (Size); \ + } while (0) +# define UnUseTmpHeapNoproc(Size) \ + do { \ + erts_get_scheduler_data()->num_tmp_heap_used -= (Size); \ + } while (0) + + +# endif + +#else +# define DeclareTmpHeap(VariableName,Size,Process) \ + Eterm VariableName[Size] +# define DeclareTmpHeapNoproc(VariableName,Size) \ + Eterm VariableName[Size] +# define UseTmpHeap(Size,Proc) /* Nothing */ +# define UnUseTmpHeap(Size,Proc) /* Nothing */ +# define UseTmpHeapNoproc(Size) /* Nothing */ +# define UnUseTmpHeapNoproc(Size) /* Nothing */ +#endif #endif diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 3309b77086..ac25eb9d5c 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -4079,7 +4079,8 @@ int driver_monitor_process(ErlDrvPort port, Port *prt = erts_drvport2port(port); Process *rp; Eterm ref; - Eterm buf[REF_THING_SIZE]; + DeclareTmpHeapNoproc(buf,REF_THING_SIZE); + if (prt->drv_ptr->process_exit == NULL) { return -1; } @@ -4089,12 +4090,14 @@ int driver_monitor_process(ErlDrvPort port, if (!rp) { return 1; } + UseTmpHeapNoproc(REF_THING_SIZE); ref = erts_make_ref_in_buffer(buf); erts_add_monitor(&(prt->monitors), MON_ORIGIN, ref, rp->id, NIL); erts_add_monitor(&(rp->monitors), MON_TARGET, ref, prt->id, NIL); erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK); ref_to_driver_monitor(ref,monitor); + UnUseTmpHeapNoproc(REF_THING_SIZE); return 0; } @@ -4104,10 +4107,12 @@ int driver_demonitor_process(ErlDrvPort port, Port *prt = erts_drvport2port(port); Process *rp; Eterm ref; - Eterm buf[REF_THING_SIZE]; + DeclareTmpHeapNoproc(buf,REF_THING_SIZE); ErtsMonitor *mon; Eterm to; + + UseTmpHeapNoproc(REF_THING_SIZE); memcpy(buf,monitor,sizeof(Eterm)*REF_THING_SIZE); ref = make_internal_ref(buf); mon = erts_lookup_monitor(prt->monitors, ref); @@ -4134,6 +4139,7 @@ int driver_demonitor_process(ErlDrvPort port, erts_destroy_monitor(rmon); } } + UnUseTmpHeapNoproc(REF_THING_SIZE); return 0; } @@ -4142,10 +4148,11 @@ ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, { Port *prt = erts_drvport2port(port); Eterm ref; - Eterm buf[REF_THING_SIZE]; + DeclareTmpHeapNoproc(buf,REF_THING_SIZE); ErtsMonitor *mon; Eterm to; + UseTmpHeapNoproc(REF_THING_SIZE); memcpy(buf,monitor,sizeof(Eterm)*REF_THING_SIZE); ref = make_internal_ref(buf); mon = erts_lookup_monitor(prt->monitors, ref); @@ -4155,6 +4162,7 @@ ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, ASSERT(mon->type == MON_ORIGIN); to = mon->pid; ASSERT(is_internal_pid(to)); + UnUseTmpHeapNoproc(REF_THING_SIZE); return (ErlDrvTermData) to; } diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 31efddc0f2..f59fbbee33 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -1002,7 +1002,7 @@ Uint32 make_hash2(Eterm term) { Uint32 hash; - Eterm tmp_big[2]; + DeclareTmpHeapNoproc(tmp_big,2); /* (HCONST * {2, ..., 14}) mod 2^32 */ #define HCONST_2 0x3c6ef372UL @@ -1041,7 +1041,6 @@ make_hash2(Eterm term) } while(0) #define IS_SSMALL28(x) (((Uint) (((x) >> (28-1)) + 1)) < 2) - /* Optimization. Simple cases before declaration of estack. */ if (primary_tag(term) == TAG_PRIMARY_IMMED1) { switch (term & _TAG_IMMED1_MASK) { @@ -1070,6 +1069,7 @@ make_hash2(Eterm term) Eterm tmp; DECLARE_ESTACK(s); + UseTmpHeapNoproc(2); hash = 0; for (;;) { switch (primary_tag(term)) { @@ -1314,6 +1314,7 @@ make_hash2(Eterm term) hash2_common: if (ESTACK_ISEMPTY(s)) { DESTROY_ESTACK(s); + UnUseTmpHeapNoproc(2); return hash; } term = ESTACK_POP(s); @@ -2581,7 +2582,11 @@ tailrecur_ne: { FloatDef f1, f2; Eterm big; - Eterm big_buf[2]; +#if HEAP_ON_C_STACK + Eterm big_buf[2]; /* If HEAP_ON_C_STACK */ +#else + Eterm *big_buf = erts_get_scheduler_data()->cmp_tmp_heap; +#endif switch(_NUMBER_CODE(a_tag, b_tag)) { case SMALL_BIG: diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c index f4e21bc05f..c859b192f7 100644 --- a/erts/emulator/sys/common/erl_mseg.c +++ b/erts/emulator/sys/common/erl_mseg.c @@ -87,11 +87,22 @@ static int is_cache_check_requested; /* Mmap ... */ #define MMAP_PROT (PROT_READ|PROT_WRITE) + +#if HALFWORD_HEAP +# ifdef MAP_32BIT +# define RANGE_FLAG (MAP_32BIT) +# else +# error "Cannot have halfword heap if unable to restrict mmap areas +# endif +#else +# define RANGE_FLAG (0) +#endif + #ifdef MAP_ANON -# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE) +# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE|RANGE_FLAG) # define MMAP_FD (-1) #else -# define MMAP_FLAGS (MAP_PRIVATE) +# define MMAP_FLAGS (MAP_PRIVATE|RANGE_FLAG) # define MMAP_FD mmap_fd static int mmap_fd; #endif @@ -310,6 +321,12 @@ mseg_create(Uint size) MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0); if (seg == (void *) MAP_FAILED) seg = NULL; +#if HALFWORD_HEAP + if ((unsigned long) seg & CHECK_POINTER_MASK) { + erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg); + return NULL; + } +#endif #else #error "Missing mseg_create() implementation" #endif @@ -1300,6 +1317,37 @@ erts_mseg_unit_size(void) { return page_size; } +#if HAVE_MMAP && HALFWORD_HEAP +#ifdef MAP_NORESERVE +#define RESERVE_FLAGS (MMAP_FLAGS | MAP_NORESERVE) +#else +#define RESERVE_FLAGS (MMAP_FLAGS) +#endif +static void halfword_reserve(void) +{ +#if 0 + void *ptr, *understack; + unsigned long x = 0x80000000; + long i = 0; + + understack = mmap(NULL,GET_PAGE_SIZE, PROT_NONE, RESERVE_FLAGS, + MMAP_FD, 0); + while (x < (unsigned long) understack) { + ptr = mmap((void *) x, GET_PAGE_SIZE, PROT_NONE, RESERVE_FLAGS, + MMAP_FD, 0); + if ((unsigned long) ptr < 0x80000000) { + munmap(ptr, GET_PAGE_SIZE); + } else { + ++i; + } + x += GET_PAGE_SIZE; + } + erts_fprintf(stderr,"Reserved %ld pages [%d MB]...\n",i, (i*GET_PAGE_SIZE)/1024/1024); +#else + return; +#endif +} +#endif void erts_mseg_init(ErtsMsegInit_t *init) @@ -1328,6 +1376,10 @@ erts_mseg_init(ErtsMsegInit_t *init) erl_exit(ERTS_ABORT_EXIT, "erts_mseg: unable to open /dev/zero\n"); #endif +#if HAVE_MMAP && HALFWORD_HEAP + halfword_reserve(); +#endif + page_size = GET_PAGE_SIZE; page_shift = 1; -- cgit v1.2.3 From 775191a1e033b4b93a4615c629d90fdb82f39a98 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Tue, 19 Jan 2010 16:11:14 +0100 Subject: Add a custom mmap wrapper to force heaps into the lower address range The free list is still rudimentary for the mmap wrapper and a better implementation will be needed for production quality. --- erts/emulator/beam/erl_lock_check.c | 3 + erts/emulator/sys/common/erl_mseg.c | 470 ++++++++++++++++++++++++++++++++++-- 2 files changed, 451 insertions(+), 22 deletions(-) diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 4858be1b75..6ff5c1b9da 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -155,6 +155,9 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "fix_alloc", "index" }, { "alcu_allocator", "index" }, { "mseg", NULL }, +#ifdef HALFWORD_HEAP + { "pmmap", NULL }, +#endif #ifdef ERTS_SMP { "port_task_pre_alloc_lock", "address" }, { "port_taskq_pre_alloc_lock", "address" }, diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c index c859b192f7..747c2e2a80 100644 --- a/erts/emulator/sys/common/erl_mseg.c +++ b/erts/emulator/sys/common/erl_mseg.c @@ -83,6 +83,14 @@ static int is_cache_check_scheduled; static int is_cache_check_requested; #endif +#if HALFWORD_HEAP +static int initialize_pmmap(void); +static void *pmmap(size_t size); +static int pmunmap(void *p, size_t size); +static void *pmremap(void *old_address, size_t old_size, + size_t new_size); +#endif + #if HAVE_MMAP /* Mmap ... */ @@ -113,7 +121,11 @@ static int mmap_fd; # define HAVE_MSEG_RECREATE 0 #endif +#if HALFWORD_HEAP +#define CAN_PARTLY_DESTROY 0 +#else #define CAN_PARTLY_DESTROY 1 +#endif #else /* #if HAVE_MMAP */ #define CAN_PARTLY_DESTROY 0 #error "Not supported" @@ -243,6 +255,7 @@ static void thread_safe_init(void) { erts_mtx_init(&init_atoms_mutex, "mseg_init_atoms"); erts_mtx_init(&mseg_mutex, "mseg"); + #ifdef ERTS_THREADS_NO_SMP main_tid = erts_thr_self(); #endif @@ -317,10 +330,14 @@ mseg_create(Uint size) #if defined(ERTS_MSEG_FAKE_SEGMENTS) seg = erts_sys_alloc(ERTS_ALC_N_INVALID, NULL, size); #elif HAVE_MMAP +#if HALFWORD_HEAP + seg = pmmap(size); +#else seg = (void *) mmap((void *) 0, (size_t) size, MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0); if (seg == (void *) MAP_FAILED) seg = NULL; +#endif #if HALFWORD_HEAP if ((unsigned long) seg & CHECK_POINTER_MASK) { erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg); @@ -346,9 +363,11 @@ mseg_destroy(void *seg, Uint size) #ifdef DEBUG int res = #endif - +#if HALFWORD_HEAP + pmunmap((void *) seg, size); +#else munmap((void *) seg, size); - +#endif ASSERT(size % page_size == 0); ASSERT(res == 0); #else @@ -372,12 +391,18 @@ mseg_recreate(void *old_seg, Uint old_size, Uint new_size) #if defined(ERTS_MSEG_FAKE_SEGMENTS) new_seg = erts_sys_realloc(ERTS_ALC_N_INVALID, NULL, old_seg, new_size); #elif HAVE_MREMAP +#if HALFWORD_HEAP + new_seg = (void *) pmremap((void *) old_seg, + (size_t) old_size, + (size_t) new_size); +#else new_seg = (void *) mremap((void *) old_seg, (size_t) old_size, (size_t) new_size, MREMAP_MAYMOVE); if (new_seg == (void *) MAP_FAILED) new_seg = NULL; +#endif #else #error "Missing mseg_recreate() implementation" #endif @@ -1325,27 +1350,10 @@ erts_mseg_unit_size(void) #endif static void halfword_reserve(void) { -#if 0 - void *ptr, *understack; - unsigned long x = 0x80000000; - long i = 0; - - understack = mmap(NULL,GET_PAGE_SIZE, PROT_NONE, RESERVE_FLAGS, - MMAP_FD, 0); - while (x < (unsigned long) understack) { - ptr = mmap((void *) x, GET_PAGE_SIZE, PROT_NONE, RESERVE_FLAGS, - MMAP_FD, 0); - if ((unsigned long) ptr < 0x80000000) { - munmap(ptr, GET_PAGE_SIZE); - } else { - ++i; - } - x += GET_PAGE_SIZE; - } - erts_fprintf(stderr,"Reserved %ld pages [%d MB]...\n",i, (i*GET_PAGE_SIZE)/1024/1024); -#else - return; +#if HALFWORD_HEAP + initialize_pmmap(); #endif + return; } #endif @@ -1502,3 +1510,421 @@ erts_mseg_test(unsigned long op, } +#if HALFWORD_HEAP +/* + * Very simple page oriented mmap replacer. Works in the lower + * 32 bit address range of a 64bit program. + * Implements anonymous mmap mremap and munmap with address order first fit. + * The free list is expected to be very short... + * To be used for compressed pointers in Erlang halfword emulator + * implementation. The MacOS X version is more of a toy, it's not really + * for production as the halfword erlang VM relies on Linux specific memory + * mapping tricks. + */ + +/*#define HARDDEBUG 1*/ + +#ifdef __APPLE__ +#define MAP_ANONYMOUS MAP_ANON +#endif + +#define INIT_LOCK() do {erts_mtx_init(&pmmap_mutex, "pmmap");} while(0) + +#define TAKE_LOCK() do {erts_mtx_lock(&pmmap_mutex);} while(0) + +#define RELEASE_LOCK() do {erts_mtx_unlock(&pmmap_mutex);} while(0) + +static erts_mtx_t pmmap_mutex; /* Also needed when !USE_THREADS */ + +typedef struct _free_block { + unsigned long num; /*pages*/ + struct _free_block *next; +} FreeBlock; + +/* Assigned once and for all */ +static size_t pagsz; + +/* Protect with lock */ +static FreeBlock *first; + +static size_t round_up_to_pagesize(size_t size) +{ + size_t x = size / pagsz; + + if ((size % pagsz)) { + ++x; + } + + return pagsz * x; +} + +static size_t round_down_to_pagesize(size_t size) +{ + size_t x = size / pagsz; + + return pagsz * x; +} + +static void *do_map(void *ptr, size_t sz) +{ + void *res; + + if (round_up_to_pagesize(sz) != sz) { +#ifdef HARDDEBUG + fprintf(stderr,"Mapping of address %p with size %ld " + "does not map complete pages\r\n", + (void *) ptr, (unsigned long) sz); +#endif + return NULL; + } + + if (((unsigned long) ptr) % pagsz) { +#ifdef HARDDEBUG + fprintf(stderr,"Mapping of address %p with size %ld " + "is not page aligned\r\n", + (void *) ptr, (unsigned long) sz); +#endif + return NULL; + } + + + res = mmap(ptr, sz, + PROT_READ | PROT_WRITE, MAP_PRIVATE | + MAP_ANONYMOUS | MAP_FIXED, + -1 , 0); + + if (res == MAP_FAILED) { +#ifdef HARDDEBUG + fprintf(stderr,"Mapping of address %p with size %ld failed!\r\n", + (void *) ptr, (unsigned long) sz); +#endif + return NULL; + } + + return res; +} + +static int do_unmap(void *ptr, size_t sz) +{ + void *res; + + if (round_up_to_pagesize(sz) != sz) { +#ifdef HARDDEBUG + fprintf(stderr,"Mapping of address %p with size %ld " + "does not map complete pages\r\n", + (void *) ptr, (unsigned long) sz); +#endif + return 1; + } + + if (((unsigned long) ptr) % pagsz) { +#ifdef HARDDEBUG + fprintf(stderr,"Mapping of address %p with size %ld " + "is not page aligned\r\n", + (void *) ptr, (unsigned long) sz); +#endif + return 1; + } + + + res = mmap(ptr, sz, + PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE + | MAP_FIXED, + -1 , 0); + + if (res == MAP_FAILED) { +#ifdef HARDDEBUG + fprintf(stderr,"Mapping of address %p with size %ld failed!\r\n", + (void *) ptr, (unsigned long) sz); +#endif + return 1; + } + + return 0; +} + +#ifdef __APPLE__ +/* + * The first 4 gig's are protected on Macos X for 64bit processes :( + * The range 0x1000000000 - 0x10FFFFFFFF is selected as an arbitrary + * value of a normally unused range... Real MMAP's will avoid + * it and all 32bit compressed pointers can be in that range... + * More expensive than on Linux where expansion of compressed + * poiters involves no masking (as they are in the first 4 gig's). + * It's also very uncertain if the MAP_NORESERVE flag really has + * any effect in MacOS X. Swap space may always be allocated... + */ +#define SET_RANGE_MIN() /* nothing */ +#define RANGE_MIN 0x1000000000UL +#define RANGE_MAX 0x1100000000UL +#define RANGE_MASK (RANGE_MIN) +#define EXTRA_MAP_FLAGS (MAP_FIXED) +#else +static size_t range_min; +#define SET_RANGE_MIN() do { range_min = (size_t) sbrk(0); } while (0) +#define RANGE_MIN range_min +#define RANGE_MAX 0x100000000UL +#define RANGE_MASK 0UL +#define EXTRA_MAP_FLAGS (0) +#endif + +static int initialize_pmmap(void) +{ + char *p,*q,*rptr; + size_t rsz; + FreeBlock *initial; + + + pagsz = getpagesize(); + SET_RANGE_MIN(); + if (sizeof(void *) != 8) { + erl_exit(1,"Halfword emulator cannot be run in 32bit mode"); + } + + p = (char *) RANGE_MIN; + q = (char *) RANGE_MAX; + + rsz = round_down_to_pagesize(q - p); + + rptr = mmap((void *) p, rsz, + PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | + MAP_NORESERVE | EXTRA_MAP_FLAGS, + -1 , 0); +#ifdef HARDDEBUG + printf("rsz = %ld, pages = %ld, rptr = %p\r\n", + (unsigned long) rsz, (unsigned long) (rsz / pagsz), + (void *) rptr); +#endif + if (!do_map(rptr,pagsz)) { + erl_exit(1,"Could not actually mmap first page for halfword emulator...\n"); + } + initial = (FreeBlock *) rptr; + initial->num = (rsz / pagsz); + initial->next = NULL; + first = initial; + INIT_LOCK(); + return 0; +} + +#ifdef HARDDEBUG +static void dump_freelist(void) +{ + FreeBlock *p = first; + + while (p) { + printf("p = %p\r\np->num = %ld\r\np->next = %p\r\n\r\n", + (void *) p, (unsigned long) p->num, (void *) p->next); + p = p->next; + } +} +#endif + + +static void *pmmap(size_t size) +{ + size_t real_size = round_up_to_pagesize(size); + size_t num_pages = real_size / pagsz; + FreeBlock **block; + FreeBlock *tail; + FreeBlock *res; + TAKE_LOCK(); + for (block = &first; + *block != NULL && (*block)->num < num_pages; + block = &((*block)->next)) + ; + if (!(*block)) { + RELEASE_LOCK(); + return NULL; + } + if ((*block)->num == num_pages) { + /* nice, perfect fit */ + res = *block; + *block = (*block)->next; + //fprintf(stderr,"***** %p,%p,%ld,%p\n",res,*block,num_pages,first); + //dump_freelist(); + } else { + tail = (FreeBlock *) (((char *) ((void *) (*block))) + real_size); + if (!do_map(tail,pagsz)) { +#ifdef HARDDEBUG + fprintf(stderr, "Could not actually allocate page at %p...\r\n", + (void *) tail); +#endif + RELEASE_LOCK(); + return NULL; + } + tail->num = (*block)->num - num_pages; + tail->next = (*block)->next; + res = *block; + *block = tail; + } + RELEASE_LOCK(); + if (!do_map(res,real_size)) { +#ifdef HARDDEBUG + fprintf(stderr, "Could not actually allocate %ld at %p...\r\n", + (unsigned long) real_size, (void *) res); +#endif + return NULL; + } + + return (void *) res; +} + +static int pmunmap(void *p, size_t size) +{ + size_t real_size = round_up_to_pagesize(size); + size_t num_pages = real_size / pagsz; + FreeBlock *block; + FreeBlock *last; + FreeBlock *nb = (FreeBlock *) p; + + if (real_size > pagsz) { + if (do_unmap(((char *) p) + pagsz,real_size - pagsz)) { + return 1; + } + } + + TAKE_LOCK(); + + last = NULL; + block = first; + while(block != NULL && ((void *) block) < p) { + last = block; + block = block->next; + } + + if (block != NULL && + ((void *) block) == ((void *) (((char *) p) + real_size))) { + /* Merge new free block with following */ + nb->num = block->num + num_pages; + nb->next = block->next; + if (do_unmap(block,pagsz)) { + RELEASE_LOCK(); + return 1; + } + } else { + /* just link in */ + nb->num = num_pages; + nb->next = block; + } + if (last != NULL) { + if (p == ((void *) (((char *) last) + (last->num * pagsz)))) { + /* Merge with previous */ + last->num += nb->num; + last->next = nb->next; + if (do_unmap(nb,pagsz)) { + RELEASE_LOCK(); + return 1; + } + } else { + last->next = nb; + } + } else { + first = nb; + } + RELEASE_LOCK(); + return 0; +} + +static void *pmremap(void *old_address, size_t old_size, + size_t new_size) +{ + size_t new_real_size = round_up_to_pagesize(new_size); + size_t new_num_pages = new_real_size / pagsz; + size_t old_real_size = round_up_to_pagesize(old_size); + size_t old_num_pages = old_real_size / pagsz; + if (new_num_pages == old_num_pages) { + return old_address; + } else if (new_num_pages < old_num_pages) { /* Shrink */ + size_t nfb_pages = old_num_pages - new_num_pages; + size_t nfb_real_size = old_real_size - new_real_size; + void *vnfb = (void *) (((char *)old_address) + new_real_size); + FreeBlock *nfb = (FreeBlock *) vnfb; + FreeBlock **block; + TAKE_LOCK(); + for (block = &first; + *block != NULL && (*block) < nfb; + block = &((*block)->next)) + ; + if (!(*block) || + (*block) > ((FreeBlock *)(((char *) vnfb) + nfb_real_size))) { + /* Normal link in */ + if (nfb_pages > 1) { + if (do_unmap((void *)(((char *) vnfb) + pagsz), + (nfb_pages - 1)*pagsz)) { + return NULL; + } + } + nfb->next = (*block); + nfb->num = nfb_pages; + (*block) = nfb; + } else { /* block merge */ + nfb->next = (*block)->next; + nfb->num = nfb_pages + (*block)->num; + /* unmap also the first page of the next freeblock */ + (*block) = nfb; + if (do_unmap((void *)(((char *) vnfb) + pagsz), + nfb_pages*pagsz)) { + return NULL; + } + } + RELEASE_LOCK(); + return old_address; + } else { /* Enlarge */ + FreeBlock **block; + void *old_end = (void *) (((char *)old_address) + old_real_size); + TAKE_LOCK(); + for (block = &first; + *block != NULL && (*block) < (FreeBlock *) old_address; + block = &((*block)->next)) + ; + if ((*block) == NULL || old_end > ((void *) RANGE_MAX) || + (*block) != old_end || + (*block)->num < (new_num_pages - old_num_pages)) { + /* cannot extend */ + void *result; + RELEASE_LOCK(); + result = pmmap(new_size); + if (result == NULL) { + return NULL; + } + memcpy(result,old_address,old_size); + if (pmunmap(old_address,old_size)) { + /* Oups... */ + pmunmap(result,new_size); + return NULL; + } + return result; + } else { /* extend */ + size_t remaining_pages = (*block)->num - + (new_num_pages - old_num_pages); + if (!remaining_pages) { + void *p = (void *) (((char *) (*block)) + pagsz); + void *n = (*block)->next; + size_t x = ((*block)->num - 1) * pagsz; + if (x > 0) { + if (do_map(p,x) == NULL) { + RELEASE_LOCK(); + return NULL; + } + } + (*block) = n; + } else { + FreeBlock *nfb = (FreeBlock *) ((void *) + (((char *) old_address) + + new_real_size)); + void *p = (void *) (((char *) (*block)) + pagsz); + if (do_map(p,new_real_size - old_real_size) == NULL) { + RELEASE_LOCK(); + return NULL; + } + nfb->num = remaining_pages; + nfb->next = (*block)->next; + (*block) = nfb; + } + RELEASE_LOCK(); + return old_address; + } + } +} + +#endif /* HALFWORD_HEAP */ -- cgit v1.2.3 From fb94cd974dc03baf149264ca4f4d50c6d1f80f21 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Wed, 20 Jan 2010 16:26:14 +0100 Subject: Store pointers to heap data in 32-bit words Store Erlang terms in 32-bit entities on the heap, expanding the pointers to 64-bit when needed. This works because all terms are stored on addresses in the 32-bit address range (the 32 most significant bits of pointers to term data are always 0). Introduce a new datatype called UWord (along with its companion SWord), which is an integer having the exact same size as the machine word (a void *), but might be larger than Eterm/Uint. Store code as machine words, as the instructions are pointers to executable code which might reside outside the 32-bit address range. Continuation pointers are stored on the 32-bit stack and hence must point to addresses in the low range, which means that loaded beam code much be placed in the low 32-bit address range (but, as said earlier, the instructions themselves are full words). No Erlang term data can be stored on C stacks (enforced by an earlier commit). This version gives a prompt, but test cases still fail (and dump core). The loader (and emulator loop) has instruction packing disabled. The main issues has been in rewriting loader and actual virtual machine. Subsystems (like distribution) does not work yet. --- configure.in | 4 + erts/configure.in | 27 ++ erts/emulator/beam/beam_bif_load.c | 38 +- erts/emulator/beam/beam_bp.c | 6 +- erts/emulator/beam/beam_bp.h | 16 +- erts/emulator/beam/beam_catches.c | 8 +- erts/emulator/beam/beam_catches.h | 6 +- erts/emulator/beam/beam_debug.c | 2 +- erts/emulator/beam/beam_emu.c | 479 ++++++++++++++------------ erts/emulator/beam/beam_load.c | 371 ++++++++++++-------- erts/emulator/beam/beam_load.h | 12 +- erts/emulator/beam/bif.c | 13 +- erts/emulator/beam/bif.h | 21 +- erts/emulator/beam/big.c | 24 ++ erts/emulator/beam/big.h | 11 +- erts/emulator/beam/break.c | 2 +- erts/emulator/beam/dist.c | 8 +- erts/emulator/beam/erl_alloc.c | 72 +++- erts/emulator/beam/erl_alloc.h | 2 +- erts/emulator/beam/erl_alloc.types | 1 + erts/emulator/beam/erl_alloc_util.c | 137 ++++---- erts/emulator/beam/erl_alloc_util.h | 52 +-- erts/emulator/beam/erl_async.c | 2 +- erts/emulator/beam/erl_bif_chksum.c | 4 +- erts/emulator/beam/erl_bif_info.c | 12 +- erts/emulator/beam/erl_bif_op.c | 2 +- erts/emulator/beam/erl_bif_re.c | 8 +- erts/emulator/beam/erl_bif_timer.c | 6 +- erts/emulator/beam/erl_bif_trace.c | 24 +- erts/emulator/beam/erl_binary.h | 2 +- erts/emulator/beam/erl_bits.c | 4 +- erts/emulator/beam/erl_db.c | 42 ++- erts/emulator/beam/erl_db_tree.c | 4 +- erts/emulator/beam/erl_db_util.c | 136 ++++---- erts/emulator/beam/erl_db_util.h | 6 +- erts/emulator/beam/erl_debug.c | 4 +- erts/emulator/beam/erl_driver.h | 2 +- erts/emulator/beam/erl_fun.c | 8 +- erts/emulator/beam/erl_fun.h | 8 +- erts/emulator/beam/erl_gc.c | 6 +- erts/emulator/beam/erl_goodfit_alloc.c | 48 +-- erts/emulator/beam/erl_goodfit_alloc.h | 20 +- erts/emulator/beam/erl_instrument.c | 74 ++-- erts/emulator/beam/erl_message.h | 2 +- erts/emulator/beam/erl_mtrace.c | 26 +- erts/emulator/beam/erl_nif.c | 62 ++-- erts/emulator/beam/erl_node_container_utils.h | 2 +- erts/emulator/beam/erl_node_tables.c | 14 + erts/emulator/beam/erl_node_tables.h | 2 +- erts/emulator/beam/erl_printf_term.c | 6 +- erts/emulator/beam/erl_process.c | 42 ++- erts/emulator/beam/erl_process.h | 26 +- erts/emulator/beam/erl_process_dump.c | 22 +- erts/emulator/beam/erl_term.c | 6 +- erts/emulator/beam/erl_term.h | 45 +-- erts/emulator/beam/erl_trace.c | 40 +-- erts/emulator/beam/erl_unicode.c | 20 +- erts/emulator/beam/erl_vm.h | 4 + erts/emulator/beam/error.h | 6 +- erts/emulator/beam/export.c | 10 +- erts/emulator/beam/export.h | 6 +- erts/emulator/beam/external.c | 127 ++++--- erts/emulator/beam/external.h | 2 +- erts/emulator/beam/global.h | 73 +++- erts/emulator/beam/io.c | 8 +- erts/emulator/beam/module.h | 4 +- erts/emulator/beam/sys.h | 42 +++ erts/emulator/beam/utils.c | 165 +++++---- erts/emulator/drivers/common/efile_drv.c | 16 +- erts/emulator/drivers/unix/ttsl_drv.c | 6 +- erts/emulator/sys/common/erl_mseg.h | 4 +- erts/emulator/utils/beam_makeops | 9 +- erts/emulator/utils/make_tables | 10 +- 73 files changed, 1492 insertions(+), 1049 deletions(-) diff --git a/configure.in b/configure.in index 21f9a640ff..643a7cecfa 100644 --- a/configure.in +++ b/configure.in @@ -195,6 +195,10 @@ AC_ARG_ENABLE(threads, [ --enable-threads enable async thread support --disable-threads disable async thread support]) +AC_ARG_ENABLE(halfword-emulator, +[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds) + --disable-halfword-emulator disable halfword emulator (only for 64bit builds)]) + AC_ARG_ENABLE(smp-support, [ --enable-smp-support enable smp support --disable-smp-support disable smp support]) diff --git a/erts/configure.in b/erts/configure.in index 5fa1245b13..6823133936 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -123,6 +123,14 @@ AC_ARG_ENABLE(threads, *) enable_threads=yes ;; esac ], enable_threads=unknown) +AC_ARG_ENABLE(halfword-emulator, +[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds) + --disable-halfword-emulator disable halfword emulator (only for 64bit builds)], +[ case "$enableval" in + no) enable_halfword_emualtor=no ;; + *) enable_halfword_emulator=yes ;; + esac ], enable_halfword_emulator=unknown) + AC_ARG_ENABLE(smp-support, [ --enable-smp-support enable smp support --disable-smp-support disable smp support], @@ -749,6 +757,25 @@ esac AC_SUBST(LIBCARBON) +dnl Check if we should/can build a halfword emulator + +AC_MSG_CHECKING(if we are building a halfword emulator (32bit heap on 64bit machine)) +if test "$enable_halfword_emulator" = "yes"; then + if test "$ARCH" = "amd64"; then + AC_DEFINE(HALFWORD_HEAP_EMULATOR, [1], + [Define if building a halfword-heap 64bit emulator]) + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR(no; halfword emulator not supported on this architecture) + fi +else + AC_MSG_RESULT([no]) +fi + + + + + dnl some tests below will call this if we haven't already - and autoconf dnl can't handle those tests being done conditionally at runtime AC_PROG_CPP diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index b1feec7074..db557c27a5 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -39,10 +39,10 @@ static Eterm check_process_code(Process* rp, Module* modp); static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp); static void delete_export_references(Eterm module); static int purge_module(int module); -static int is_native(Eterm* code); +static int is_native(UWord* code); static int any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size); static int any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size); -static void remove_from_address_table(Eterm* code); +static void remove_from_address_table(UWord* code); Eterm load_module_2(BIF_ALIST_2) @@ -344,8 +344,8 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) modp->code[MI_ON_LOAD_FUNCTION_PTR] = 0; set_default_trace_pattern(BIF_ARG_1); } else if (BIF_ARG_2 == am_false) { - Eterm* code; - Eterm* end; + UWord* code; + UWord* end; /* * The on_load function failed. Remove the loaded code. @@ -354,7 +354,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) */ erts_total_code_size -= modp->code_length; code = modp->code; - end = (Eterm *)((char *)code + modp->code_length); + end = (UWord *)((char *)code + modp->code_length); erts_cleanup_funs_on_purge(code, end); beam_catches_delmod(modp->catches, code, modp->code_length); erts_free(ERTS_ALC_T_CODE, (void *) code); @@ -397,10 +397,10 @@ set_default_trace_pattern(Eterm module) static Eterm check_process_code(Process* rp, Module* modp) { - Eterm* start; + UWord* start; char* mod_start; Uint mod_size; - Eterm* end; + UWord* end; Eterm* sp; #ifndef HYBRID /* FIND ME! */ ErlFunThing* funp; @@ -418,7 +418,7 @@ check_process_code(Process* rp, Module* modp) * Pick up limits for the module. */ start = modp->old_code; - end = (Eterm *)((char *)start + modp->old_code_length); + end = (UWord *)((char *)start + modp->old_code_length); mod_start = (char *) start; mod_size = modp->old_code_length; @@ -472,11 +472,11 @@ check_process_code(Process* rp, Module* modp) #ifndef HYBRID /* FIND ME! */ rescan: for (funp = MSO(rp).funs; funp; funp = funp->next) { - Eterm* fun_code; + UWord* fun_code; fun_code = funp->fe->address; - if (INSIDE((Eterm *) funp->fe->address)) { + if (INSIDE((UWord *) funp->fe->address)) { if (done_gc) { return am_true; } else { @@ -576,7 +576,7 @@ any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size) switch (primary_tag(val)) { case TAG_PRIMARY_BOXED: case TAG_PRIMARY_LIST: - if (in_area(val, mod_start, mod_size)) { + if (in_area(EXPAND_POINTER(val), mod_start, mod_size)) { return 1; } break; @@ -596,7 +596,7 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size) switch (primary_tag(val)) { case TAG_PRIMARY_BOXED: case TAG_PRIMARY_LIST: - if (in_area(val, mod_start, mod_size)) { + if (in_area(EXPAND_POINTER(val), mod_start, mod_size)) { return 1; } break; @@ -617,8 +617,8 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size) static int purge_module(int module) { - Eterm* code; - Eterm* end; + UWord* code; + UWord* end; Module* modp; /* @@ -653,7 +653,7 @@ purge_module(int module) ASSERT(erts_total_code_size >= modp->old_code_length); erts_total_code_size -= modp->old_code_length; code = modp->old_code; - end = (Eterm *)((char *)code + modp->old_code_length); + end = (UWord *)((char *)code + modp->old_code_length); erts_cleanup_funs_on_purge(code, end); beam_catches_delmod(modp->old_catches, code, modp->old_code_length); erts_free(ERTS_ALC_T_CODE, (void *) code); @@ -665,7 +665,7 @@ purge_module(int module) } static void -remove_from_address_table(Eterm* code) +remove_from_address_table(UWord* code) { int i; @@ -738,11 +738,11 @@ delete_export_references(Eterm module) Export *ep = export_list(i); if (ep != NULL && (ep->code[0] == module)) { if (ep->address == ep->code+3 && - (ep->code[3] == (Eterm) em_apply_bif)) { + (ep->code[3] == (UWord) em_apply_bif)) { continue; } ep->address = ep->code+3; - ep->code[3] = (Uint) em_call_error_handler; + ep->code[3] = (UWord) em_call_error_handler; ep->code[4] = 0; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; @@ -774,7 +774,7 @@ beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks, Eterm module) } static int -is_native(Eterm* code) +is_native(UWord* code) { return ((Eterm *)code[MI_FUNCTIONS])[1] != 0; } diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c index 1abf1dc10c..0cdc2116ba 100644 --- a/erts/emulator/beam/beam_bp.c +++ b/erts/emulator/beam/beam_bp.c @@ -262,7 +262,7 @@ erts_clear_function_break(Module *modp, Uint *pc) { * SMP NOTE: Process p may have become exiting on return! */ Uint -erts_trace_break(Process *p, Uint *pc, Eterm *args, +erts_trace_break(Process *p, UWord *pc, Eterm *args, Uint32 *ret_flags, Eterm *tracer_pid) { Eterm tpid1, tpid2; BpDataTrace *bdt = (BpDataTrace *) pc[-4]; @@ -296,7 +296,7 @@ erts_trace_break(Process *p, Uint *pc, Eterm *args, * SMP NOTE: Process p may have become exiting on return! */ Uint32 -erts_bif_mtrace(Process *p, Uint *pc, Eterm *args, int local, +erts_bif_mtrace(Process *p, UWord *pc, Eterm *args, int local, Eterm *tracer_pid) { BpDataTrace *bdt = (BpDataTrace *) pc[-4]; @@ -364,7 +364,7 @@ erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { } int -erts_is_mtrace_bif(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { +erts_is_mtrace_bif(UWord *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { BpDataTrace *bdt = (BpDataTrace *) pc[-4]; if (bdt) { diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h index 44e6b294d8..44b463d39c 100644 --- a/erts/emulator/beam/beam_bp.h +++ b/erts/emulator/beam/beam_bp.h @@ -89,11 +89,11 @@ extern erts_smp_spinlock_t erts_bp_lock; do { \ BpDataCount *bdc = (BpDataCount *) (pc)[-4]; \ \ - ASSERT((pc)[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); \ + ASSERT((pc)[-5] == (UWord) BeamOp(op_i_func_info_IaaI)); \ ASSERT(bdc); \ bdc = (BpDataCount *) bdc->next; \ ASSERT(bdc); \ - (pc)[-4] = (Uint) bdc; \ + (pc)[-4] = (UWord) bdc; \ ErtsSmpBPLock(bdc); \ if (bdc->count >= 0) bdc->count++; \ ErtsSmpBPUnlock(bdc); \ @@ -104,11 +104,11 @@ do { \ do { \ BpData *bd = (BpData *) (pc)[-4]; \ \ - ASSERT((pc)[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); \ + ASSERT((pc)[-5] == (UWord) BeamOp(op_i_func_info_IaaI)); \ ASSERT(bd); \ bd = bd->next; \ ASSERT(bd); \ - (pc)[-4] = (Uint) bd; \ + (pc)[-4] = (UWord) bd; \ *(instr_result) = bd->orig_instr; \ } while (0) @@ -146,16 +146,16 @@ int erts_clear_break(Eterm mfa[3], int specified); int erts_clear_module_break(Module *modp); int erts_clear_function_break(Module *modp, Uint *pc); -Uint erts_trace_break(Process *p, Uint *pc, Eterm *args, +Uint erts_trace_break(Process *p, UWord *pc, Eterm *args, Uint32 *ret_flags, Eterm *tracer_pid); -Uint32 erts_bif_mtrace(Process *p, Uint *pc, Eterm *args, +Uint32 erts_bif_mtrace(Process *p, UWord *pc, Eterm *args, int local, Eterm *tracer_pid); -int erts_is_trace_break(Uint *pc, Binary **match_spec_ret, +int erts_is_trace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret); int erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_rte); -int erts_is_mtrace_bif(Uint *pc, Binary **match_spec_ret, +int erts_is_mtrace_bif(UWord *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret); int erts_is_native_break(Uint *pc); int erts_is_count_break(Uint *pc, Sint *count_ret); diff --git a/erts/emulator/beam/beam_catches.c b/erts/emulator/beam/beam_catches.c index d5cef1cad2..af99b0499a 100644 --- a/erts/emulator/beam/beam_catches.c +++ b/erts/emulator/beam/beam_catches.c @@ -26,7 +26,7 @@ /* XXX: should use dynamic reallocation */ #define TABSIZ (16*1024) static struct { - Eterm *cp; + UWord *cp; unsigned cdr; } beam_catches[TABSIZ]; @@ -39,7 +39,7 @@ void beam_catches_init(void) high_mark = 0; } -unsigned beam_catches_cons(Eterm *cp, unsigned cdr) +unsigned beam_catches_cons(UWord *cp, unsigned cdr) { int i; @@ -65,7 +65,7 @@ unsigned beam_catches_cons(Eterm *cp, unsigned cdr) return i; } -Eterm *beam_catches_car(unsigned i) +UWord *beam_catches_car(unsigned i) { if( i >= TABSIZ ) { fprintf(stderr, @@ -75,7 +75,7 @@ Eterm *beam_catches_car(unsigned i) return beam_catches[i].cp; } -void beam_catches_delmod(unsigned head, Eterm *code, unsigned code_bytes) +void beam_catches_delmod(unsigned head, UWord *code, unsigned code_bytes) { unsigned i, cdr; diff --git a/erts/emulator/beam/beam_catches.h b/erts/emulator/beam/beam_catches.h index ccf33d5e86..0769d47263 100644 --- a/erts/emulator/beam/beam_catches.h +++ b/erts/emulator/beam/beam_catches.h @@ -23,9 +23,9 @@ #define BEAM_CATCHES_NIL (-1) void beam_catches_init(void); -unsigned beam_catches_cons(Eterm* cp, unsigned cdr); -Eterm *beam_catches_car(unsigned i); -void beam_catches_delmod(unsigned head, Eterm* code, unsigned code_bytes); +unsigned beam_catches_cons(UWord* cp, unsigned cdr); +UWord *beam_catches_car(unsigned i); +void beam_catches_delmod(unsigned head, UWord* code, unsigned code_bytes); #define catch_pc(x) beam_catches_car(catch_val((x))) diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 4242a4161e..b381d4e546 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -38,7 +38,7 @@ #include "beam_bp.h" #include "erl_binary.h" -#ifdef ARCH_64 +#ifdef ARCH_64 /* XXX:PaN Halfword? */ # define HEXF "%016bpX" #else # define HEXF "%08bpX" diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 66c6eb7819..d542c56e28 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -117,6 +117,7 @@ do { \ #endif #define GET_BIF_ADDRESS(p) ((BifFunction) (((Export *) p)->code[4])) +#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) /* @@ -138,8 +139,8 @@ do { \ #define VALID_INSTR(IP) (0 <= (int)(IP) && ((int)(IP) < (NUMBER_OF_OPCODES*2+10))) #else #define VALID_INSTR(IP) \ - ((Sint)LabelAddr(emulator_loop) <= (Sint)(IP) && \ - (Sint)(IP) < (Sint)LabelAddr(end_emulator_loop)) + ((SWord)LabelAddr(emulator_loop) <= (SWord)(IP) && \ + (SWord)(IP) < (SWord)LabelAddr(end_emulator_loop)) #endif /* NO_JUMP_TABLE */ #define SET_CP(p, ip) \ @@ -181,11 +182,11 @@ do { \ #define StoreBifResult(Dst, Result) \ do { \ - Eterm* stb_next; \ + UWord* stb_next; \ Eterm stb_reg; \ stb_reg = Arg(Dst); \ I += (Dst) + 2; \ - stb_next = (Eterm *) *I; \ + stb_next = (UWord *) *I; \ CHECK_TERM(Result); \ switch (beam_reg_tag(stb_reg)) { \ case R_REG_DEF: \ @@ -205,7 +206,7 @@ do { \ c_p->cp = 0; \ } while(0) -#define RESTORE_CP(X) SET_CP(c_p, cp_val(*(X))) +#define RESTORE_CP(X) SET_CP(c_p, (UWord *) cp_val(*(X))) #define ISCATCHEND(instr) ((Eterm *) *(instr) == OpCode(catch_end_y)) @@ -213,13 +214,13 @@ do { \ * Special Beam instructions. */ -Eterm beam_apply[2]; -Eterm beam_exit[1]; -Eterm beam_continue_exit[1]; +UWord beam_apply[2]; +UWord beam_exit[1]; +UWord beam_continue_exit[1]; -Eterm* em_call_error_handler; -Eterm* em_apply_bif; -Eterm* em_call_traced_function; +UWord* em_call_error_handler; +UWord* em_apply_bif; +UWord* em_call_traced_function; /* NOTE These should be the only variables containing trace instructions. @@ -227,9 +228,9 @@ Eterm* em_call_traced_function; ** for the refering variable (one of these), and rouge references ** will most likely cause chaos. */ -Eterm beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */ -Eterm beam_return_trace[1]; /* OpCode(i_return_trace) */ -Eterm beam_exception_trace[1]; /* UGLY also OpCode(i_return_trace) */ +UWord beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */ +UWord beam_return_trace[1]; /* OpCode(i_return_trace) */ +UWord beam_exception_trace[1]; /* UGLY also OpCode(i_return_trace) */ /* * All Beam instructions in numerical order. @@ -522,8 +523,8 @@ extern int count_instructions; #define DispatchMacro() \ do { \ - Eterm* dis_next; \ - dis_next = (Eterm *) *I; \ + UWord* dis_next; \ + dis_next = (UWord *) *I; \ CHECK_ARGS(I); \ if (FCALLS > 0 || FCALLS > neg_o_reds) { \ FCALLS--; \ @@ -535,8 +536,8 @@ extern int count_instructions; #define DispatchMacroFun() \ do { \ - Eterm* dis_next; \ - dis_next = (Eterm *) *I; \ + UWord* dis_next; \ + dis_next = (UWord *) *I; \ CHECK_ARGS(I); \ if (FCALLS > 0 || FCALLS > neg_o_reds) { \ FCALLS--; \ @@ -590,7 +591,7 @@ extern int count_instructions; ASSERT(VALID_INSTR(*I)); \ Goto(*I) -#define PreFetch(N, Dst) do { Dst = (Eterm *) *(I + N + 1); } while (0) +#define PreFetch(N, Dst) do { Dst = (UWord *) *(I + N + 1); } while (0) #define NextPF(N, Dst) \ I += N + 1; \ ASSERT(VALID_INSTR(Dst)); \ @@ -644,7 +645,7 @@ extern int count_instructions; #define DeallocateReturn(Deallocate) \ do { \ int words_to_pop = (Deallocate); \ - SET_I(cp_val(*E)); \ + SET_I((UWord *) cp_val(*E)); \ E = ADD_BYTE_OFFSET(E, words_to_pop); \ CHECK_TERM(r(0)); \ Goto(*I); \ @@ -657,19 +658,19 @@ extern int count_instructions; #define MoveCall(Src, Dest, CallDest, Size) \ (Dest) = (Src); \ SET_CP(c_p, I+Size+1); \ - SET_I((Eterm *) CallDest); \ + SET_I((UWord *) CallDest); \ Dispatch(); #define MoveCallLast(Src, Dest, CallDest, Deallocate) \ (Dest) = (Src); \ RESTORE_CP(E); \ E = ADD_BYTE_OFFSET(E, (Deallocate)); \ - SET_I((Eterm *) CallDest); \ + SET_I((UWord *) CallDest); \ Dispatch(); #define MoveCallOnly(Src, Dest, CallDest) \ (Dest) = (Src); \ - SET_I((Eterm *) CallDest); \ + SET_I((UWord *) CallDest); \ Dispatch(); #define GetList(Src, H, T) do { \ @@ -677,47 +678,48 @@ extern int count_instructions; H = CAR(tmp_ptr); \ T = CDR(tmp_ptr); } while (0) -#define GetTupleElement(Src, Element, Dest) \ - do { \ - tmp_arg1 = (Eterm) (((unsigned char *) tuple_val(Src)) + (Element)); \ - (Dest) = (*(Eterm *)tmp_arg1); \ +#define GetTupleElement(Src, Element, Dest) \ + do { \ + tmp_arg1 = (Eterm) COMPRESS_POINTER(((unsigned char *) tuple_val(Src)) + \ + (Element)); \ + (Dest) = (*(Eterm *) EXPAND_POINTER(tmp_arg1)); \ } while (0) -#define ExtractNextElement(Dest) \ - tmp_arg1 += sizeof(Eterm); \ - (Dest) = (* (Eterm *) (((unsigned char *) tmp_arg1))) +#define ExtractNextElement(Dest) \ + tmp_arg1 += sizeof(Eterm); \ + (Dest) = (* (Eterm *) (((unsigned char *) EXPAND_POINTER(tmp_arg1)))) -#define ExtractNextElement2(Dest) \ - do { \ - Eterm* ene_dstp = &(Dest); \ - ene_dstp[0] = ((Eterm *) tmp_arg1)[1]; \ - ene_dstp[1] = ((Eterm *) tmp_arg1)[2]; \ - tmp_arg1 += sizeof(Eterm) + sizeof(Eterm); \ +#define ExtractNextElement2(Dest) \ + do { \ + Eterm* ene_dstp = &(Dest); \ + ene_dstp[0] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[1]; \ + ene_dstp[1] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[2]; \ + tmp_arg1 += sizeof(Eterm) + sizeof(Eterm); \ } while (0) #define ExtractNextElement3(Dest) \ do { \ Eterm* ene_dstp = &(Dest); \ - ene_dstp[0] = ((Eterm *) tmp_arg1)[1]; \ - ene_dstp[1] = ((Eterm *) tmp_arg1)[2]; \ - ene_dstp[2] = ((Eterm *) tmp_arg1)[3]; \ + ene_dstp[0] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[1]; \ + ene_dstp[1] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[2]; \ + ene_dstp[2] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[3]; \ tmp_arg1 += 3*sizeof(Eterm); \ } while (0) #define ExtractNextElement4(Dest) \ do { \ Eterm* ene_dstp = &(Dest); \ - ene_dstp[0] = ((Eterm *) tmp_arg1)[1]; \ - ene_dstp[1] = ((Eterm *) tmp_arg1)[2]; \ - ene_dstp[2] = ((Eterm *) tmp_arg1)[3]; \ - ene_dstp[3] = ((Eterm *) tmp_arg1)[4]; \ + ene_dstp[0] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[1]; \ + ene_dstp[1] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[2]; \ + ene_dstp[2] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[3]; \ + ene_dstp[3] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[4]; \ tmp_arg1 += 4*sizeof(Eterm); \ } while (0) #define ExtractElement(Element, Dest) \ do { \ tmp_arg1 += (Element); \ - (Dest) = (* (Eterm *) tmp_arg1); \ + (Dest) = (* (Eterm *) EXPAND_POINTER(tmp_arg1)); \ } while (0) #define PutTuple(Arity, Src, Dest) \ @@ -759,8 +761,13 @@ extern int count_instructions; #define IsTuple(X, Action) if (is_not_tuple(X)) Action -#define IsArity(Pointer, Arity, Fail) \ - if (*(Eterm *)(tmp_arg1 = (Eterm)tuple_val(Pointer)) != (Arity)) { Fail; } +#define IsArity(Pointer, Arity, Fail) \ + if (*(Eterm *) \ + EXPAND_POINTER(tmp_arg1 = (Eterm) \ + COMPRESS_POINTER(tuple_val(Pointer))) != (Arity)) \ + { \ + Fail; \ + } #define IsFunction(X, Action) \ do { \ @@ -776,11 +783,14 @@ extern int count_instructions; } \ } while (0) -#define IsTupleOfArity(Src, Arity, Fail) \ - do { \ - if (is_not_tuple(Src) || *(Eterm *)(tmp_arg1 = (Eterm) tuple_val(Src)) != Arity) { \ - Fail; \ - } \ +#define IsTupleOfArity(Src, Arity, Fail) \ + do { \ + if (is_not_tuple(Src) || \ + *(Eterm *) \ + EXPAND_POINTER(tmp_arg1 = \ + (Eterm) COMPRESS_POINTER(tuple_val(Src))) != Arity) { \ + Fail; \ + } \ } while (0) #define IsBoolean(X, Fail) if ((X) != am_true && (X) != am_false) { Fail; } @@ -791,7 +801,7 @@ extern int count_instructions; #define IsBitstring(Src, Fail) \ if (is_not_binary(Src)) { Fail; } -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP #define BsSafeMul(A, B, Fail, Target) \ do { Uint64 _res = (A) * (B); \ if (_res / B != A) { Fail; } \ @@ -974,23 +984,23 @@ extern int count_instructions; #define IsRef(Src, Fail) if (is_not_ref(Src)) { Fail; } static BifFunction translate_gc_bif(void* gcf); -static Eterm* handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf); -static Eterm* next_catch(Process* c_p, Eterm *reg); +static UWord* handle_error(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf); +static UWord* next_catch(Process* c_p, Eterm *reg); static void terminate_proc(Process* c_p, Eterm Value); static Eterm add_stacktrace(Process* c_p, Eterm Value, Eterm exc); -static void save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, +static void save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, Eterm args); static struct StackTrace * get_trace_from_exc(Eterm exc); static Eterm make_arglist(Process* c_p, Eterm* reg, int a); -static Eterm call_error_handler(Process* p, Eterm* ip, Eterm* reg); -static Eterm call_breakpoint_handler(Process* p, Eterm* fi, Eterm* reg); -static Uint* fixed_apply(Process* p, Eterm* reg, Uint arity); -static Eterm* apply(Process* p, Eterm module, Eterm function, +static Eterm call_error_handler(Process* p, UWord* ip, Eterm* reg); +static Eterm call_breakpoint_handler(Process* p, UWord* fi, Eterm* reg); +static UWord* fixed_apply(Process* p, Eterm* reg, Uint arity); +static UWord* apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg); static int hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg); -static Eterm* call_fun(Process* p, int arity, Eterm* reg, Eterm args); -static Eterm* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg); +static UWord* call_fun(Process* p, int arity, Eterm* reg, Eterm args); +static UWord* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg); static Eterm new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free); #if defined(_OSE_) || defined(VXWORKS) @@ -1078,7 +1088,7 @@ void process_main(void) /* * Pointer to next threaded instruction. */ - register Eterm *I REG_I = NULL; + register UWord *I REG_I = NULL; /* Number of reductions left. This function * returns to the scheduler when FCALLS reaches zero. @@ -1097,6 +1107,7 @@ void process_main(void) #endif #ifndef ERTS_SMP +#if !HALFWORD_HEAP static Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers -- not used directly, but * through 'reg', because using it directly @@ -1104,7 +1115,7 @@ void process_main(void) * while using it through reg needs only * one. */ - +#endif /* * Floating point registers. */ @@ -1150,7 +1161,12 @@ void process_main(void) goto init_emulator; } #ifndef ERTS_SMP +#if !HALFWORD_HEAP reg = save_reg; /* XXX: probably wastes a register on x86 */ +#else + /* Registers need to be heap allocated (correct memory range) for tracing to work */ + reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm)); +#endif #endif c_p = NULL; reds_used = 0; @@ -1178,7 +1194,7 @@ void process_main(void) { int reds; Eterm* argp; - Eterm* next; + UWord *next; int i; argp = c_p->arg_reg; @@ -1205,7 +1221,7 @@ void process_main(void) FCALLS = REDS_IN(c_p) = reds; } - next = (Eterm *) *I; + next = (UWord *) *I; r(0) = c_p->arg_reg[0]; #ifdef HARDDEBUG if (c_p->arity > 0) { @@ -1297,7 +1313,7 @@ void process_main(void) } /* FALL THROUGH */ OpCase(i_call_only_f): { - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Dispatch(); } @@ -1308,7 +1324,7 @@ void process_main(void) OpCase(i_call_last_fP): { RESTORE_CP(E); E = ADD_BYTE_OFFSET(E, Arg(1)); - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Dispatch(); } @@ -1319,7 +1335,7 @@ void process_main(void) /* FALL THROUGH */ OpCase(i_call_f): { SET_CP(c_p, I+2); - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Dispatch(); } @@ -1355,7 +1371,7 @@ void process_main(void) Dispatchx(); OpCase(init_y): { - Eterm* next; + UWord *next; PreFetch(1, next); make_blank(yb(Arg(0))); @@ -1363,7 +1379,7 @@ void process_main(void) } OpCase(i_trim_I): { - Eterm* next; + UWord *next; Uint words; Uint cp; @@ -1389,7 +1405,7 @@ void process_main(void) } OpCase(test_heap_1_put_list_Iy): { - Eterm* next; + UWord *next; PreFetch(2, next); TestHeap(Arg(0), 1); @@ -1420,7 +1436,7 @@ void process_main(void) */ OpCase(send): { - Eterm* next; + UWord *next; Eterm result; PRE_BIF_SWAPOUT(c_p); @@ -1435,7 +1451,7 @@ void process_main(void) NextPF(0, next); } else if (c_p->freason == TRAP) { SET_CP(c_p, I+1); - SET_I((Eterm *) c_p->def_arg_reg[3]); + SET_I(*((UWord **) (UWord) ((c_p)->def_arg_reg + 3))); SWAPIN; r(0) = c_p->def_arg_reg[0]; x(1) = c_p->def_arg_reg[1]; @@ -1561,7 +1577,7 @@ void process_main(void) */ OpCase(i_loop_rec_fr): { - Eterm* next; + UWord *next; ErlMessage* msgp; loop_rec__: @@ -1585,7 +1601,7 @@ void process_main(void) erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE); else { #endif - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Goto(*I); /* Jump to a wait or wait_timeout instruction */ #ifdef ERTS_SMP } @@ -1621,7 +1637,7 @@ void process_main(void) * Remove a (matched) message from the message queue. */ OpCase(remove_message): { - Eterm* next; + UWord *next; ErlMessage* msgp; PROCESS_MAIN_CHK_LOCKS(c_p); @@ -1666,7 +1682,7 @@ void process_main(void) * message didn't match), then jump to the loop_rec instruction. */ OpCase(loop_rec_end_f): { - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); SAVE_MESSAGE(c_p); goto loop_rec__; } @@ -1696,12 +1712,12 @@ void process_main(void) } GetArg1(1, timeout_value); if (timeout_value != make_small(0)) { -#if !defined(ARCH_64) +#if !defined(ARCH_64) || HALFWORD_HEAP Uint time_val; #endif if (is_small(timeout_value) && signed_val(timeout_value) > 0 && -#if defined(ARCH_64) +#if defined(ARCH_64) && !HALFWORD_HEAP ((unsigned_val(timeout_value) >> 32) == 0) #else 1 @@ -1712,14 +1728,16 @@ void process_main(void) * c_p->def_arg_reg[0]. Note that it is safe to use this * location because there are no living x registers in * a receive statement. + * Note that for the halfword emulator, the two first elements + * of the array are used. */ - c_p->def_arg_reg[0] = (Eterm) (I+3); + *((UWord **) (UWord) c_p->def_arg_reg) = I+3; set_timer(c_p, unsigned_val(timeout_value)); } else if (timeout_value == am_infinity) { c_p->flags |= F_TIMO; -#if !defined(ARCH_64) +#if !defined(ARCH_64) || HALFWORD_HEAP } else if (term_to_Uint(timeout_value, &time_val)) { - c_p->def_arg_reg[0] = (Eterm) (I+3); + *((UWord **) (UWord) c_p->def_arg_reg) = I+3; set_timer(c_p, time_val); #endif } else { /* Wrong time */ @@ -1748,7 +1766,7 @@ void process_main(void) wait2: { ASSERT(!ERTS_PROC_IS_EXITING(c_p)); - c_p->i = (Eterm *) Arg(0); /* L1 */ + c_p->i = (UWord *) Arg(0); /* L1 */ SWAPOUT; c_p->arity = 0; c_p->status = P_WAITING; @@ -1776,7 +1794,7 @@ void process_main(void) * we must test the F_INSLPQUEUE flag as well as the F_TIMO flag. */ if ((c_p->flags & (F_INSLPQUEUE | F_TIMO)) == 0) { - c_p->def_arg_reg[0] = (Eterm) (I+3); + *((UWord **) (UWord) c_p->def_arg_reg) = I+3; set_timer(c_p, Arg(1)); } goto wait2; @@ -1791,7 +1809,7 @@ void process_main(void) } OpCase(timeout): { - Eterm* next; + UWord *next; PreFetch(0, next); if (IS_TRACED_FL(c_p, F_TRACE_RECEIVE)) { @@ -1811,8 +1829,8 @@ void process_main(void) do_binary_search: { struct Pairs { - Eterm val; - Eterm* addr; + UWord val; + UWord* addr; }; struct Pairs* low; struct Pairs* high; @@ -1852,7 +1870,7 @@ void process_main(void) Goto(*I); } } - SET_I((Eterm *) Arg(1)); + SET_I((UWord *) Arg(1)); Goto(*I); } @@ -1864,11 +1882,11 @@ void process_main(void) if (is_small(index)) { index = signed_val(index); if (index < Arg(2)) { - SET_I((Eterm *) (&Arg(3))[index]); + SET_I((UWord *) (&Arg(3))[index]); Goto(*I); } } - SET_I((Eterm *) Arg(1)); + SET_I((UWord *) Arg(1)); Goto(*I); } @@ -1880,11 +1898,11 @@ void process_main(void) if (is_small(index)) { index = (Uint) (signed_val(index) - Arg(3)); if (index < Arg(2)) { - SET_I((Eterm *) (&Arg(4))[index]); + SET_I((UWord *) (&Arg(4))[index]); Goto(*I); } } - SET_I((Eterm *) Arg(1)); + SET_I((UWord *) Arg(1)); Goto(*I); } @@ -1921,7 +1939,7 @@ void process_main(void) if (is_value(result)) { StoreBifResult(3, result); } - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Goto(*I); } @@ -1982,7 +2000,7 @@ void process_main(void) StoreBifResult(4, result); } if (Arg(0) != 0) { - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Goto(*I); } reg[0] = arg; @@ -2010,7 +2028,7 @@ void process_main(void) if (is_value(result)) { StoreBifResult(2, result); } - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Goto(*I); } @@ -2046,7 +2064,7 @@ void process_main(void) */ OpCase(call_bif0_e): { - Eterm (*bf)(Process*, Uint*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, UWord*) = GET_BIF_ADDRESS(Arg(0)); PRE_BIF_SWAPOUT(c_p); c_p->fcalls = FCALLS - 1; @@ -2079,9 +2097,9 @@ void process_main(void) OpCase(call_bif1_e): { - Eterm (*bf)(Process*, Eterm, Uint*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, Eterm, UWord*) = GET_BIF_ADDRESS(Arg(0)); Eterm result; - Eterm* next; + UWord *next; c_p->fcalls = FCALLS - 1; if (FCALLS <= 0) { @@ -2114,9 +2132,9 @@ void process_main(void) OpCase(call_bif2_e): { - Eterm (*bf)(Process*, Eterm, Eterm, Uint*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, Eterm, Eterm, UWord*) = GET_BIF_ADDRESS(Arg(0)); Eterm result; - Eterm* next; + UWord *next; PRE_BIF_SWAPOUT(c_p); c_p->fcalls = FCALLS - 1; @@ -2151,9 +2169,9 @@ void process_main(void) OpCase(call_bif3_e): { - Eterm (*bf)(Process*, Eterm, Eterm, Eterm, Uint*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, Eterm, Eterm, Eterm, UWord*) = GET_BIF_ADDRESS(Arg(0)); Eterm result; - Eterm* next; + UWord *next; PRE_BIF_SWAPOUT(c_p); c_p->fcalls = FCALLS - 1; @@ -2174,7 +2192,7 @@ void process_main(void) } else if (c_p->freason == TRAP) { call_bif_trap3: SET_CP(c_p, I+2); - SET_I((Eterm *)c_p->def_arg_reg[3]); + SET_I(*((UWord **) (UWord) ((c_p)->def_arg_reg + 3))); SWAPIN; r(0) = c_p->def_arg_reg[0]; x(1) = c_p->def_arg_reg[1]; @@ -2282,7 +2300,7 @@ void process_main(void) lb_Cl_error: { if (Arg(0) != 0) { OpCase(jump_f): { - SET_I((Eterm *) Arg(0)); + SET_I((UWord *) Arg(0)); Goto(*I); } } @@ -2474,7 +2492,7 @@ void process_main(void) goto lb_Cl_error; OpCase(i_apply): { - Eterm* next; + UWord *next; SWAPOUT; next = apply(c_p, r(0), x(1), x(2), reg); SWAPIN; @@ -2489,13 +2507,13 @@ void process_main(void) } OpCase(i_apply_last_P): { - Eterm* next; + UWord *next; SWAPOUT; next = apply(c_p, r(0), x(1), x(2), reg); SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (Eterm *) E[0]); + SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(0)); SET_I(next); Dispatch(); @@ -2505,7 +2523,7 @@ void process_main(void) } OpCase(i_apply_only): { - Eterm* next; + UWord *next; SWAPOUT; next = apply(c_p, r(0), x(1), x(2), reg); SWAPIN; @@ -2519,7 +2537,7 @@ void process_main(void) } OpCase(apply_I): { - Eterm* next; + UWord *next; reg[0] = r(0); SWAPOUT; @@ -2536,7 +2554,7 @@ void process_main(void) } OpCase(apply_last_IP): { - Eterm* next; + UWord *next; reg[0] = r(0); SWAPOUT; @@ -2544,7 +2562,7 @@ void process_main(void) SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (Eterm *) E[0]); + SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(1)); SET_I(next); Dispatch(); @@ -2554,7 +2572,7 @@ void process_main(void) } OpCase(i_apply_fun): { - Eterm* next; + UWord *next; SWAPOUT; next = apply_fun(c_p, r(0), x(1), reg); @@ -2569,14 +2587,14 @@ void process_main(void) } OpCase(i_apply_fun_last_P): { - Eterm* next; + UWord *next; SWAPOUT; next = apply_fun(c_p, r(0), x(1), reg); SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (Eterm *) E[0]); + SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(0)); SET_I(next); Dispatchfun(); @@ -2585,7 +2603,7 @@ void process_main(void) } OpCase(i_apply_fun_only): { - Eterm* next; + UWord *next; SWAPOUT; next = apply_fun(c_p, r(0), x(1), reg); @@ -2599,7 +2617,7 @@ void process_main(void) } OpCase(i_call_fun_I): { - Eterm* next; + UWord *next; SWAPOUT; reg[0] = r(0); @@ -2615,7 +2633,7 @@ void process_main(void) } OpCase(i_call_fun_last_IP): { - Eterm* next; + UWord *next; SWAPOUT; reg[0] = r(0); @@ -2623,7 +2641,7 @@ void process_main(void) SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (Eterm *) E[0]); + SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(1)); SET_I(next); Dispatchfun(); @@ -2728,7 +2746,7 @@ void process_main(void) tmp_arg1 = *tuple_val(tmp_arg1); goto do_binary_search; } - SET_I((Eterm *) Arg(1)); + SET_I((UWord *) Arg(1)); Goto(*I); } @@ -2754,13 +2772,15 @@ void process_main(void) given = big_val(tmp_arg1); given_arity = given[0]; given_size = thing_arityval(given_arity); - bigp = &Arg(2); + bigp = (Eterm *) &Arg(2); while ((arity = bigp[0]) > given_arity) { bigp += thing_arityval(arity) + 2; } while (bigp[0] == given_arity) { if (memcmp(bigp+1, given+1, sizeof(Eterm)*given_size) == 0) { - SET_I((Eterm *) bigp[given_size+1]); + UWord *tmp = + ((UWord *) (UWord) bigp) + TermWords(given_size + 1); + SET_I((UWord *) *tmp); Goto(*I); } bigp += thing_arityval(arity) + 2; @@ -2771,18 +2791,18 @@ void process_main(void) * Failed. */ - SET_I((Eterm *) Arg(1)); + SET_I((UWord *) Arg(1)); Goto(*I); } -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP OpCase(i_select_float_sfI): { Uint f; int n; struct ValLabel { Uint f; - Eterm* addr; + UWord* addr; }; struct ValLabel* ptr; @@ -2810,7 +2830,7 @@ void process_main(void) struct ValLabel { Uint fpart1; Uint fpart2; - Eterm* addr; + UWord* addr; }; struct ValLabel* ptr; @@ -2828,7 +2848,7 @@ void process_main(void) } ptr++; } - SET_I((Eterm *) Arg(1)); + SET_I((UWord *) Arg(1)); Goto(*I); } #endif @@ -2836,7 +2856,7 @@ void process_main(void) OpCase(set_tuple_element_sdP): { Eterm element; Eterm tuple; - Eterm* next; + UWord *next; Eterm* p; PreFetch(3, next); @@ -3031,7 +3051,7 @@ void process_main(void) switch (tmp_arg2) { case 3: { - Eterm (*bf)(Process*, Eterm, Eterm, Eterm, Uint*) = vbf; + Eterm (*bf)(Process*, Eterm, Eterm, Eterm, UWord*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, r(0), x(1), x(2), I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3040,7 +3060,7 @@ void process_main(void) break; case 2: { - Eterm (*bf)(Process*, Eterm, Eterm, Uint*) = vbf; + Eterm (*bf)(Process*, Eterm, Eterm, UWord*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, r(0), x(1), I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3049,7 +3069,7 @@ void process_main(void) break; case 1: { - Eterm (*bf)(Process*, Eterm, Uint*) = vbf; + Eterm (*bf)(Process*, Eterm, UWord*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, r(0), I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3058,7 +3078,7 @@ void process_main(void) break; case 0: { - Eterm (*bf)(Process*, Uint*) = vbf; + Eterm (*bf)(Process*, UWord*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3082,7 +3102,7 @@ apply_bif_or_nif_epilogue: SET_I(c_p->cp); Goto(*I); } else if (c_p->freason == TRAP) { - SET_I((Eterm *)c_p->def_arg_reg[3]); + SET_I(*((UWord **) (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]; @@ -3540,7 +3560,7 @@ apply_bif_or_nif_epilogue: OpCase(bs_put_string_II): { - Eterm* next; + UWord *next; PreFetch(2, next); erts_new_bs_put_string(ERL_BITS_ARGS_2((byte *) Arg(1), Arg(0))); NextPF(2, next); @@ -3711,7 +3731,7 @@ apply_bif_or_nif_epilogue: { Eterm header; - Eterm* next; + UWord *next; Uint slots; OpCase(i_bs_start_match2_rfIId): { @@ -3777,7 +3797,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_zero_tail2_fr): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(1, next); @@ -3789,7 +3809,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_zero_tail2_fx): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); @@ -3801,7 +3821,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_tail_imm2_frI): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); _mb = ms_matchbuffer(r(0)); @@ -3811,7 +3831,7 @@ apply_bif_or_nif_epilogue: NextPF(2, next); } OpCase(bs_test_tail_imm2_fxI): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(3, next); _mb = ms_matchbuffer(xb(Arg(1))); @@ -3822,7 +3842,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_unit_frI): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); _mb = ms_matchbuffer(r(0)); @@ -3832,7 +3852,7 @@ apply_bif_or_nif_epilogue: NextPF(2, next); } OpCase(bs_test_unit_fxI): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(3, next); _mb = ms_matchbuffer(xb(Arg(1))); @@ -3843,7 +3863,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_unit8_fr): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(1, next); _mb = ms_matchbuffer(r(0)); @@ -3853,7 +3873,7 @@ apply_bif_or_nif_epilogue: NextPF(1, next); } OpCase(bs_test_unit8_fx): { - Eterm* next; + UWord *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); _mb = ms_matchbuffer(xb(Arg(1))); @@ -3937,11 +3957,11 @@ apply_bif_or_nif_epilogue: _integer = get_int32(_mb->base + _mb->offset/8); } _mb->offset += 32; -#ifndef ARCH_64 +#if !defined(ARCH_64) || HALFWORD_HEAP if (IS_USMALL(0, _integer)) { #endif _result = make_small(_integer); -#ifndef ARCH_64 +#if !defined(ARCH_64) || HALFWORD_HEAP } else { TestHeap(BIG_UINT_HEAP_SIZE, Arg(1)); _result = uint_to_big((Uint) _integer, HTOP); @@ -4178,7 +4198,7 @@ apply_bif_or_nif_epilogue: do_bs_match_string: { - Eterm* next; + UWord *next; byte* bytes; Uint bits; ErlBinMatchBuffer* mb; @@ -4205,7 +4225,7 @@ apply_bif_or_nif_epilogue: } OpCase(i_bs_save2_rI): { - Eterm* next; + UWord *next; ErlBinMatchState *_ms; PreFetch(1, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) r(0)); @@ -4213,7 +4233,7 @@ apply_bif_or_nif_epilogue: NextPF(1, next); } OpCase(i_bs_save2_xI): { - Eterm* next; + UWord *next; ErlBinMatchState *_ms; PreFetch(2, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) xb(Arg(0))); @@ -4222,7 +4242,7 @@ apply_bif_or_nif_epilogue: } OpCase(i_bs_restore2_rI): { - Eterm* next; + UWord *next; ErlBinMatchState *_ms; PreFetch(1, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) r(0)); @@ -4230,7 +4250,7 @@ apply_bif_or_nif_epilogue: NextPF(1, next); } OpCase(i_bs_restore2_xI): { - Eterm* next; + UWord *next; ErlBinMatchState *_ms; PreFetch(2, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) xb(Arg(0))); @@ -4247,7 +4267,7 @@ apply_bif_or_nif_epilogue: * deallocate not followed by a return, and that should work. */ OpCase(deallocate_I): { - Eterm* next; + UWord *next; PreFetch(1, next); D(Arg(0)); @@ -4297,26 +4317,25 @@ apply_bif_or_nif_epilogue: } E -= 3; ASSERT(c_p->htop <= E && E <= c_p->hend); - ASSERT(is_CP((Eterm)(ep->code))); + ASSERT(is_CP((UWord)(ep->code))); ASSERT(is_internal_pid(c_p->tracer_proc) || is_internal_port(c_p->tracer_proc)); - E[2] = make_cp(c_p->cp); + E[2] = make_cp(c_p->cp); /* XXX:PaN - code in lower range on halfword */ E[1] = am_true; /* Process tracer */ E[0] = make_cp(ep->code); - c_p->cp = (Eterm*) - make_cp(flags & MATCH_SET_EXCEPTION_TRACE - ? beam_exception_trace : beam_return_trace); + c_p->cp = (flags & MATCH_SET_EXCEPTION_TRACE) + ? beam_exception_trace : beam_return_trace; erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_ALL_MINOR); c_p->trace_flags |= F_EXCEPTION_TRACE; erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_ALL_MINOR); } } - SET_I((Uint *) Arg(0)); + SET_I((UWord *)Arg(0)); Dispatch(); } OpCase(return_trace): { - Uint* code = (Uint *) E[0]; + UWord* code = (UWord *) (UWord) E[0]; SWAPOUT; /* Needed for shared heap */ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p); @@ -4324,24 +4343,24 @@ apply_bif_or_nif_epilogue: ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p); SWAPIN; c_p->cp = NULL; - SET_I((Eterm *) E[2]); + SET_I((UWord *) cp_val(E[2])); E += 3; Goto(*I); } OpCase(i_count_breakpoint): { - Uint real_I; + UWord real_I; - ErtsCountBreak((Uint *) I, &real_I); + ErtsCountBreak((UWord *) I, &real_I); ASSERT(VALID_INSTR(real_I)); Goto(real_I); } OpCase(i_trace_breakpoint): if (! IS_TRACED_FL(c_p, F_TRACE_CALLS)) { - Uint real_I; + UWord real_I; - ErtsBreakSkip((Uint *) I, &real_I); + ErtsBreakSkip((UWord *) I, &real_I); Goto(real_I); } /* Fall through to next case */ @@ -4355,11 +4374,10 @@ apply_bif_or_nif_epilogue: SWAPOUT; reg[0] = r(0); - if (*cp_val((Eterm)c_p->cp) - == (Uint) OpCode(return_trace)) { + if (*(c_p->cp) == (UWord) OpCode(return_trace)) { cpp = (Uint*)&E[2]; - } else if (*cp_val((Eterm)c_p->cp) - == (Uint) OpCode(i_return_to_trace)) { + } else if (*(c_p->cp) + == (UWord) OpCode(i_return_to_trace)) { return_to_trace = !0; cpp = (Uint*)&E[0]; } else { @@ -4370,19 +4388,19 @@ apply_bif_or_nif_epilogue: * return_trace and/or i_return_to_trace stackframes * on the stack, they are not intermixed with y registers */ - Eterm *cp_save = c_p->cp; + UWord *cp_save = c_p->cp; for (;;) { ASSERT(is_CP(*cpp)); - if (*cp_val(*cpp) == (Uint) OpCode(return_trace)) { + if (*cp_val(*cpp) == (UWord) OpCode(return_trace)) { cpp += 3; - } else if (*cp_val(*cpp) == (Uint) OpCode(i_return_to_trace)) { + } else if (*cp_val(*cpp) == (UWord) OpCode(i_return_to_trace)) { return_to_trace = !0; cpp += 1; } else break; } - c_p->cp = (Eterm *) *cpp; - ASSERT(is_CP((Eterm)c_p->cp)); + c_p->cp = (UWord *) cp_val(*cpp); + ASSERT(is_CP(*cpp)); ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p); real_I = erts_trace_break(c_p, I, reg, &flags, &tracer_pid); ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p); @@ -4418,12 +4436,12 @@ apply_bif_or_nif_epilogue: E -= 1; ASSERT(c_p->htop <= E && E <= c_p->hend); E[0] = make_cp(c_p->cp); - c_p->cp = (Eterm *) make_cp(beam_return_to_trace); + c_p->cp = (UWord *) beam_return_to_trace; } if (flags & MATCH_SET_RX_TRACE) { E -= 3; ASSERT(c_p->htop <= E && E <= c_p->hend); - ASSERT(is_CP((Eterm) (I - 3))); + ASSERT(is_CP((Eterm) (UWord) (I - 3))); ASSERT(am_true == tracer_pid || is_internal_pid(tracer_pid) || is_internal_port(tracer_pid)); E[2] = make_cp(c_p->cp); @@ -4431,9 +4449,9 @@ apply_bif_or_nif_epilogue: E[0] = make_cp(I - 3); /* We ARE at the beginning of an instruction, the funcinfo is above i. */ - c_p->cp = (Eterm*) - make_cp(flags & MATCH_SET_EXCEPTION_TRACE - ? beam_exception_trace : beam_return_trace); + c_p->cp = + (flags & MATCH_SET_EXCEPTION_TRACE) + ? beam_exception_trace : beam_return_trace; erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_ALL_MINOR); c_p->trace_flags |= F_EXCEPTION_TRACE; erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_ALL_MINOR); @@ -4446,10 +4464,10 @@ apply_bif_or_nif_epilogue: Uint *cpp = (Uint*) E; for(;;) { ASSERT(is_CP(*cpp)); - if (*cp_val(*cpp) == (Uint) OpCode(return_trace)) { + if (*cp_val(*cpp) == (UWord) OpCode(return_trace)) { do ++cpp; while(is_not_CP(*cpp)); cpp += 2; - } else if (*cp_val(*cpp) == (Uint) OpCode(i_return_to_trace)) { + } else if (*cp_val(*cpp) == (UWord) OpCode(i_return_to_trace)) { do ++cpp; while(is_not_CP(*cpp)); } else break; } @@ -4460,7 +4478,7 @@ apply_bif_or_nif_epilogue: SWAPIN; } c_p->cp = NULL; - SET_I((Eterm *) E[0]); + SET_I((UWord *) cp_val(E[0])); E += 1; Goto(*I); } @@ -4471,7 +4489,7 @@ apply_bif_or_nif_epilogue: OpCase(i_global_cons): { - Eterm *next; + UWord *next; #ifdef HYBRID Eterm *hp; @@ -4493,7 +4511,7 @@ apply_bif_or_nif_epilogue: OpCase(i_global_tuple): { - Eterm *next; + UWord *next; int len; #ifdef HYBRID Eterm list; @@ -4528,7 +4546,7 @@ apply_bif_or_nif_epilogue: OpCase(i_global_copy): { - Eterm *next; + UWord *next; PreFetch(0,next); #ifdef HYBRID if (!IS_CONST(r(0))) @@ -4557,7 +4575,7 @@ apply_bif_or_nif_epilogue: OpCase(fmove_ql): { Eterm fr = Arg(1); - Eterm* next; + UWord *next; PreFetch(2, next); GET_DOUBLE(Arg(0), *(FloatDef*)ADD_BYTE_OFFSET(freg, fr)); @@ -4567,7 +4585,7 @@ apply_bif_or_nif_epilogue: OpCase(fmove_dl): { Eterm targ1; Eterm fr = Arg(1); - Eterm* next; + UWord *next; PreFetch(2, next); GetR(0, targ1); @@ -4588,7 +4606,7 @@ apply_bif_or_nif_epilogue: OpCase(fconv_dl): { Eterm targ1; Eterm fr = Arg(1); - Eterm* next; + UWord *next; GetR(0, targ1); PreFetch(2, next); @@ -4617,7 +4635,7 @@ apply_bif_or_nif_epilogue: erl_exit(1, "fclearerror/i_fcheckerror without fpe signals (beam_emu)"); #else OpCase(fclearerror): { - Eterm* next; + UWord *next; PreFetch(0, next); ERTS_FP_CHECK_INIT(c_p); @@ -4625,7 +4643,7 @@ apply_bif_or_nif_epilogue: } OpCase(i_fcheckerror): { - Eterm* next; + UWord *next; PreFetch(0, next); ERTS_FP_ERROR(c_p, freg[0].fd, goto fbadarith); @@ -4639,7 +4657,7 @@ apply_bif_or_nif_epilogue: OpCase(i_fadd_lll): { - Eterm* next; + UWord *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4648,7 +4666,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fsub_lll): { - Eterm* next; + UWord *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4657,7 +4675,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fmul_lll): { - Eterm* next; + UWord *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4666,7 +4684,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fdiv_lll): { - Eterm* next; + UWord *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4675,7 +4693,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fnegate_ll): { - Eterm* next; + UWord *next; PreFetch(2, next); ERTS_FP_CHECK_INIT(c_p); @@ -4742,7 +4760,7 @@ apply_bif_or_nif_epilogue: neg_o_reds = -c_p->def_arg_reg[4]; FCALLS = c_p->fcalls; SWAPIN; - switch( c_p->def_arg_reg[3] ) { + switch( c_p->def_arg_reg[3] ) { /* XXX:PaN - Halfword wont work with hipe yet... */ case HIPE_MODE_SWITCH_RES_RETURN: ASSERT(is_value(reg[0])); MoveReturn(reg[0], r(0)); @@ -4754,7 +4772,7 @@ apply_bif_or_nif_epilogue: /* This can be used to call any function value, but currently it's only used to call closures referring to unloaded modules. */ { - Eterm *next; + UWord *next; next = call_fun(c_p, c_p->arity - 1, reg, THE_NON_VALUE); SWAPIN; @@ -4903,8 +4921,8 @@ apply_bif_or_nif_epilogue: bif_table[i].name, bif_table[i].arity); bif_export[i] = ep; - ep->code[3] = (Eterm) OpCode(apply_bif); - ep->code[4] = (Eterm) bif_table[i].f; + ep->code[3] = (UWord) OpCode(apply_bif); + ep->code[4] = (UWord) bif_table[i].f; } return; @@ -5007,8 +5025,8 @@ Eterm error_atom[NUMBER_EXIT_CODES] = { * at the point of the original exception. */ -static Eterm* -handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf) +static UWord* +handle_error(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf) { Eterm* hp; Eterm Value = c_p->fvalue; @@ -5062,7 +5080,7 @@ handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf) /* Find a handler or die */ if ((c_p->catches > 0 || IS_TRACED_FL(c_p, F_EXCEPTION_TRACE)) && !(c_p->freason & EXF_PANIC)) { - Eterm *new_pc; + UWord *new_pc; /* The Beam handler code (catch_end or try_end) checks reg[0] for THE_NON_VALUE to see if the previous code finished abnormally. If so, reg[1], reg[2] and reg[3] should hold the @@ -5088,13 +5106,13 @@ handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf) /* * Find the nearest catch handler */ -static Eterm* +static UWord* next_catch(Process* c_p, Eterm *reg) { int active_catches = c_p->catches > 0; int have_return_to_trace = 0; Eterm *ptr, *prev, *return_to_trace_ptr = NULL; - Uint i_return_trace = beam_return_trace[0]; - Uint i_return_to_trace = beam_return_to_trace[0]; + UWord i_return_trace = beam_return_trace[0]; + UWord i_return_to_trace = beam_return_to_trace[0]; ptr = prev = c_p->stop; ASSERT(is_CP(*ptr)); ASSERT(ptr <= STACK_START(c_p)); @@ -5103,9 +5121,9 @@ next_catch(Process* c_p, Eterm *reg) { *cp_val(*ptr) != i_return_to_trace)) && c_p->cp) { /* Can not follow cp here - code may be unloaded */ - Uint *cpp = cp_val((Eterm) c_p->cp); + UWord *cpp = c_p->cp; if (cpp == beam_exception_trace) { - erts_trace_exception(c_p, (Eterm*) ptr[0], + erts_trace_exception(c_p, cp_val(ptr[0]), reg[1], reg[2], ptr+1); /* Skip return_trace parameters */ ptr += 2; @@ -5129,7 +5147,7 @@ next_catch(Process* c_p, Eterm *reg) { if (is_catch(*ptr) && active_catches) goto found_catch; } if (cp_val(*prev) == beam_exception_trace) { - erts_trace_exception(c_p, (Eterm*) ptr[0], + erts_trace_exception(c_p, cp_val(ptr[0]), reg[1], reg[2], ptr+1); } /* Skip return_trace parameters */ @@ -5258,7 +5276,7 @@ expand_error_value(Process* c_p, Uint freason, Eterm Value) { */ static void -save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf, +save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, Eterm args) { struct StackTrace* s; int sz; @@ -5269,7 +5287,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf, } /* Create a container for the exception data */ - sz = (offsetof(struct StackTrace, trace) + sizeof(Eterm)*depth + sz = (offsetof(struct StackTrace, trace) + sizeof(UWord *)*depth + sizeof(Eterm) - 1) / sizeof(Eterm); s = (struct StackTrace *) HAlloc(c_p, 1 + sz); /* The following fields are inside the bignum */ @@ -5356,9 +5374,10 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf, /* Save the actual stack trace */ if (depth > 0) { - Eterm *ptr, *prev = s->depth ? s->trace[s->depth-1] : NULL; - Uint i_return_trace = beam_return_trace[0]; - Uint i_return_to_trace = beam_return_to_trace[0]; + Eterm *ptr; + UWord *prev = s->depth ? s->trace[s->depth-1] : NULL; + UWord i_return_trace = beam_return_trace[0]; + UWord i_return_to_trace = beam_return_to_trace[0]; /* * Traverse the stack backwards and add all unique continuation * pointers to the buffer, up to the maximum stack trace size. @@ -5371,7 +5390,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf, *cp_val(*ptr) != i_return_to_trace)) && c_p->cp) { /* Can not follow cp here - code may be unloaded */ - Uint *cpp = cp_val((Eterm) c_p->cp); + UWord *cpp = c_p->cp; if (cpp == beam_exception_trace || cpp == beam_return_trace) { /* Skip return_trace parameters */ ptr += 2; @@ -5391,7 +5410,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf, /* Skip stack frame variables */ do ++ptr; while (is_not_CP(*ptr)); } else { - Eterm *cp = (Eterm *)(*ptr); + UWord *cp = cp_val(*ptr); if (cp != prev) { /* Record non-duplicates only */ prev = cp; @@ -5463,9 +5482,12 @@ build_stacktrace(Process* c_p, Eterm exc) { struct StackTrace* s; Eterm args; int depth; - Eterm* current; + UWord* current; +#if HALFWORD_HEAP + UWord current_buff[3]; +#endif Eterm Where = NIL; - Eterm* next_p = &Where; + Eterm *next_p = &Where; if (! (s = get_trace_from_exc(exc))) { return NIL; @@ -5493,7 +5515,14 @@ build_stacktrace(Process* c_p, Eterm exc) { * (e.g. spawn_link(erlang, abs, [1])). */ if (current == NULL) { +#if HALFWORD_HEAP + current = current_buff; + current[0] = (UWord) c_p->initial[0]; + current[1] = (UWord) c_p->initial[1]; + current[2] = (UWord) c_p->initial[2]; +#else current = c_p->initial; +#endif args = am_true; /* Just in case */ } else { args = get_args_from_exc(exc); @@ -5529,7 +5558,7 @@ build_stacktrace(Process* c_p, Eterm exc) { * Finally, we go through the saved continuation pointers. */ for (i = 0; i < depth; i++) { - Eterm *fi = find_function_from_pc((Eterm *) s->trace[i]); + UWord *fi = find_function_from_pc((UWord *) s->trace[i]); if (fi == NULL) continue; mfa = TUPLE3(hp, fi[0], fi[1], make_small(fi[2])); hp += 4; @@ -5546,7 +5575,7 @@ build_stacktrace(Process* c_p, Eterm exc) { static Eterm -call_error_handler(Process* p, Eterm* fi, Eterm* reg) +call_error_handler(Process* p, UWord* fi, Eterm* reg) { Eterm* hp; Export* ep; @@ -5594,7 +5623,7 @@ call_error_handler(Process* p, Eterm* fi, Eterm* reg) } static Eterm -call_breakpoint_handler(Process* p, Eterm* fi, Eterm* reg) +call_breakpoint_handler(Process* p, UWord* fi, Eterm* reg) { Eterm* hp; Export* ep; @@ -5687,7 +5716,7 @@ apply_setup_error_handler(Process* p, Eterm module, Eterm function, Uint arity, return ep; } -static Uint* +static UWord* apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg) { int arity; @@ -5769,7 +5798,7 @@ apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg) return ep->address; } -static Uint* +static UWord* fixed_apply(Process* p, Eterm* reg, Uint arity) { Export* ep; @@ -5875,7 +5904,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg) c_p->stop = STACK_START(c_p); c_p->catches = 0; c_p->i = beam_apply; - c_p->cp = (Eterm *) beam_apply+1; + c_p->cp = (UWord *) beam_apply+1; /* * If there are no waiting messages, garbage collect and @@ -5905,7 +5934,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg) return 1; } -static Uint* +static UWord* call_fun(Process* p, /* Current process. */ int arity, /* Number of arguments for Fun. */ Eterm* reg, /* Contents of registers. */ @@ -5925,7 +5954,7 @@ call_fun(Process* p, /* Current process. */ if (is_fun_header(hdr)) { ErlFunThing* funp = (ErlFunThing *) fun_val(fun); ErlFunEntry* fe; - Eterm* code_ptr; + UWord* code_ptr; Eterm* var_ptr; int actual_arity; unsigned num_free; @@ -6020,7 +6049,7 @@ call_fun(Process* p, /* Current process. */ } } } else if (is_export_header(hdr)) { - Export* ep = (Export *) (export_val(fun))[1]; + Export* ep = *((Export **) (export_val(fun) + 1)); int actual_arity = (int) ep->code[2]; if (arity == actual_arity) { return ep->address; @@ -6088,7 +6117,7 @@ call_fun(Process* p, /* Current process. */ } } -static Eterm* +static UWord* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg) { int arity; @@ -6182,7 +6211,7 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity) if ((ep = export_get(&e)) == NULL) { return 0; } - return ep->address == ep->code+3 && (ep->code[3] == (Uint) em_apply_bif); + return ep->address == ep->code+3 && (ep->code[3] == (UWord) em_apply_bif); } diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 99fab28dce..b928b04210 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -51,9 +51,9 @@ ErlDrvBinary* erts_gzinflate_buffer(char*, int); #define EXPORTED 2 #ifdef NO_JUMP_TABLE -# define BeamOpCode(Op) ((Uint)(Op)) +# define BeamOpCode(Op) ((UWord)(Op)) #else -# define BeamOpCode(Op) ((Eterm)beam_ops[Op]) +# define BeamOpCode(Op) ((UWord)beam_ops[Op]) #endif #if defined(WORDS_BIGENDIAN) @@ -94,7 +94,7 @@ typedef struct { typedef struct { unsigned type; /* Type of operand. */ - Uint val; /* Value of operand. */ + UWord val; /* Value of operand. */ Uint bigarity; /* Arity for bignumbers (only). */ } GenOpArg; @@ -142,7 +142,7 @@ typedef struct { typedef struct { Eterm function; /* Tagged atom for function. */ int arity; /* Arity. */ - Eterm* address; /* Address to function in code. */ + UWord* address; /* Address to function in code. */ } ExportEntry; #define MakeIffId(a, b, c, d) \ @@ -274,13 +274,13 @@ typedef struct { int num_functions; /* Number of functions in module. */ int num_labels; /* Number of labels. */ int code_buffer_size; /* Size of code buffer in words. */ - Eterm* code; /* Loaded code. */ + UWord* code; /* Loaded code. */ int ci; /* Current index into loaded code. */ Label* labels; - Uint put_strings; /* Linked list of put_string instructions. */ - Uint new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */ + UWord put_strings; /* Linked list of put_string instructions. */ + UWord new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */ StringPatch* string_patches; /* Linked list of position into string table to patch. */ - Uint catches; /* Linked list of catch_yf instructions. */ + UWord catches; /* Linked list of catch_yf instructions. */ unsigned loaded_size; /* Final size of code when loaded. */ byte mod_md5[16]; /* MD5 for module code. */ int may_load_nif; /* true if NIFs may later be loaded for this module */ @@ -341,7 +341,7 @@ typedef struct { #define GetTagAndValue(Stp, Tag, Val) \ do { \ - Uint __w; \ + UWord __w; \ GetByte(Stp, __w); \ Tag = __w & 0x07; \ if ((__w & 0x08) == 0) { \ @@ -388,7 +388,7 @@ typedef struct { goto load_error; \ } else { \ int __n = (N); \ - Uint __result = 0; \ + UWord __result = 0; \ Stp->file_left -= (unsigned) __n; \ while (__n-- > 0) { \ __result = __result << 8 | *Stp->file_p++; \ @@ -465,7 +465,7 @@ static int bin_load(Process *c_p, ErtsProcLocks c_p_locks, static void init_state(LoaderState* stp); static int insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, Eterm group_leader, Eterm module, - Eterm* code, Uint size, Uint catches); + UWord* code, Uint size, UWord catches); static int scan_iff_file(LoaderState* stp, Uint* chunk_types, Uint num_types, Uint num_mandatory); static int load_atom_table(LoaderState* stp); @@ -499,8 +499,8 @@ static void load_printf(int line, LoaderState* context, char *fmt, ...); static int transform_engine(LoaderState* st); static void id_to_string(Uint id, char* s); static void new_genop(LoaderState* stp); -static int get_int_val(LoaderState* stp, Uint len_code, Uint* result); -static int get_erlang_integer(LoaderState* stp, Uint len_code, Uint* result); +static int get_int_val(LoaderState* stp, Uint len_code, UWord* result); +static int get_erlang_integer(LoaderState* stp, Uint len_code, UWord* result); static int new_label(LoaderState* stp); static void new_literal_patch(LoaderState* stp, int pos); static void new_string_patch(LoaderState* stp, int pos); @@ -513,7 +513,7 @@ static Eterm compilation_info_for_module(Process* p, Eterm mod); static Eterm native_addresses(Process* p, Eterm mod); int patch_funentries(Eterm Patchlist); int patch(Eterm Addresses, Uint fe); -static int safe_mul(Uint a, Uint b, Uint* resp); +static int safe_mul(UWord a, UWord b, UWord* resp); static int must_swap_floats; @@ -592,6 +592,15 @@ erts_load_module(Process *c_p, return result; } +#ifdef DEBUG +extern void check_allocators(void); +extern void check_allocated_block(Uint type, void *blk); +#define CHKALLOC() check_allocators() +#define CHKBLK(TYPE,BLK) if ((BLK) != NULL) check_allocated_block((TYPE),(BLK)) +#else +#define CHKALLOC() /* nothing */ +#define CHKBLK(TYPE,BLK) /* nothing */ +#endif static int bin_load(Process *c_p, ErtsProcLocks c_p_locks, @@ -608,6 +617,12 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Scan the IFF file. */ +#ifdef DEBUG + fprintf(stderr,"Loading a module\r\n"); +#endif + + CHKALLOC(); + CHKBLK(ERTS_ALC_T_CODE,state.code); state.file_name = "IFF header for Beam file"; state.file_p = bytes; state.file_left = unloaded_size; @@ -619,6 +634,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Read the header for the code chunk. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); define_file(&state, "code chunk header", CODE_CHUNK); if (!read_code_header(&state)) { goto load_error; @@ -628,6 +644,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Read the atom table. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); define_file(&state, "atom table", ATOM_CHUNK); if (!load_atom_table(&state)) { goto load_error; @@ -637,6 +654,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Read the import table. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); define_file(&state, "import table", IMP_CHUNK); if (!load_import_table(&state)) { goto load_error; @@ -646,6 +664,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Read the lambda (fun) table. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); if (state.chunks[LAMBDA_CHUNK].size > 0) { define_file(&state, "lambda (fun) table", LAMBDA_CHUNK); if (!read_lambda_table(&state)) { @@ -657,6 +676,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Read the literal table. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); if (state.chunks[LITERAL_CHUNK].size > 0) { define_file(&state, "literals table (constant pool)", LITERAL_CHUNK); if (!read_literal_table(&state)) { @@ -668,18 +688,25 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Load the code chunk. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); state.file_name = "code chunk"; state.file_p = state.code_start; state.file_left = state.code_size; - if (!load_code(&state) || !freeze_code(&state)) { + if (!load_code(&state)) { goto load_error; } + CHKBLK(ERTS_ALC_T_CODE,state.code); + if (!freeze_code(&state)) { + goto load_error; + } + /* * Read and validate the export table. (This must be done after * loading the code, because it contains labels.) */ + CHKBLK(ERTS_ALC_T_CODE,state.code); define_file(&state, "export table", EXP_CHUNK); if (!read_export_table(&state)) { goto load_error; @@ -690,16 +717,19 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * exported and imported functions. This can't fail. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); rval = insert_new_code(c_p, c_p_locks, state.group_leader, state.module, state.code, state.loaded_size, state.catches); if (rval < 0) { goto load_error; } + CHKBLK(ERTS_ALC_T_CODE,state.code); final_touch(&state); /* * Loading succeded. */ + CHKBLK(ERTS_ALC_T_CODE,state.code); rval = 0; state.code = NULL; /* Prevent code from being freed. */ *modp = state.module; @@ -755,6 +785,9 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.genop_blocks); state.genop_blocks = next; } +#ifdef DEBUG + erts_fprintf(stderr,"Loaded %T\r\n",*modp); +#endif return rval; } @@ -791,7 +824,7 @@ init_state(LoaderState* stp) static int insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, - Eterm group_leader, Eterm module, Eterm* code, Uint size, Uint catches) + Eterm group_leader, Eterm module, UWord* code, Uint size, UWord catches) { Module* modp; int rval; @@ -833,7 +866,7 @@ insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, modules[i] = modules[i-1]; } modules[i].start = code; - modules[i].end = (Eterm *) (((byte *)code) + size); + modules[i].end = (UWord *) (((byte *)code) + size); num_loaded_modules++; mid_module = &modules[num_loaded_modules/2]; return 0; @@ -1083,7 +1116,7 @@ load_import_table(LoaderState* stp) * the BIF function. */ if ((e = erts_find_export_entry(mod, func, arity)) != NULL) { - if (e->code[3] == (Uint) em_apply_bif) { + if (e->code[3] == (UWord) em_apply_bif) { stp->import[i].bf = (BifFunction) e->code[4]; if (func == am_load_nif && mod == am_erlang && arity == 2) { stp->may_load_nif = 1; @@ -1151,7 +1184,7 @@ read_export_table(LoaderState* stp) * redefine). */ if ((e = erts_find_export_entry(stp->module, func, arity)) != NULL) { - if (e->code[3] == (Uint) em_apply_bif) { + if (e->code[3] == (UWord) em_apply_bif) { int j; for (j = 0; j < sizeof(allow_redef)/sizeof(allow_redef[0]); j++) { @@ -1220,7 +1253,7 @@ static int read_literal_table(LoaderState* stp) { int i; - Uint uncompressed_sz; + UWord uncompressed_sz; byte* uncompressed = 0; GetInt(stp, 4, uncompressed_sz); @@ -1338,8 +1371,8 @@ read_code_header(LoaderState* stp) * Initialize code area. */ stp->code_buffer_size = erts_next_heap_size(2048 + stp->num_functions, 0); - stp->code = (Eterm*) erts_alloc(ERTS_ALC_T_CODE, - sizeof(Eterm) * stp->code_buffer_size); + stp->code = (UWord *) erts_alloc(ERTS_ALC_T_CODE, + sizeof(UWord) * stp->code_buffer_size); stp->code[MI_NUM_FUNCTIONS] = stp->num_functions; stp->ci = MI_FUNCTIONS + stp->num_functions + 1; @@ -1365,16 +1398,18 @@ read_code_header(LoaderState* stp) LoadError2(Stp, "bad tag %d; expected %d", Actual, Expected); \ } else {} -#define Need(w) \ - ASSERT(ci <= code_buffer_size); \ - if (code_buffer_size < ci+(w)) { \ - code_buffer_size = erts_next_heap_size(ci+(w), 0); \ - stp->code = code \ - = (Eterm *) erts_realloc(ERTS_ALC_T_CODE, \ - (void *) code, \ - code_buffer_size * sizeof(Eterm)); \ - } +#define CodeNeed(w) do { \ + ASSERT(ci <= code_buffer_size); \ + if (code_buffer_size < ci+(w)) { \ + code_buffer_size = erts_next_heap_size(ci+(w), 0); \ + stp->code = code \ + = (UWord *) erts_realloc(ERTS_ALC_T_CODE, \ + (void *) code, \ + code_buffer_size * sizeof(UWord)); \ + } \ +} while (0) +#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) static int @@ -1387,7 +1422,7 @@ load_code(LoaderState* stp) char* sign; int arg; /* Number of current argument. */ int num_specific; /* Number of specific ops for current. */ - Eterm* code; + UWord* code; int code_buffer_size; int specific; Uint last_label = 0; /* Number of last label. */ @@ -1446,7 +1481,7 @@ load_code(LoaderState* stp) if (((First) & 0x08) == 0) { \ Val = (First) >> 4; \ } else if (((First) & 0x10) == 0) { \ - Uint __w; \ + UWord __w; \ GetByte(Stp, __w); \ Val = (((First) >> 5) << 8) | __w; \ } else { \ @@ -1455,7 +1490,7 @@ load_code(LoaderState* stp) } while (0) for (arg = 0; arg < arity; arg++) { - Uint first; + UWord first; GetByte(stp, first); last_op->a[arg].type = first & 0x07; @@ -1464,7 +1499,7 @@ load_code(LoaderState* stp) if ((first & 0x08) == 0) { last_op->a[arg].val = first >> 4; } else if ((first & 0x10) == 0) { - Uint w; + UWord w; GetByte(stp, w); ASSERT(first < 0x800); last_op->a[arg].val = ((first >> 5) << 8) | w; @@ -1523,7 +1558,7 @@ load_code(LoaderState* stp) break; case TAG_z: { - Uint ext_tag; + UWord ext_tag; unsigned tag; GetValue(stp, first, ext_tag); @@ -1531,14 +1566,14 @@ load_code(LoaderState* stp) case 0: /* Floating point number */ { Eterm* hp; -# ifndef ARCH_64 +#if !defined(ARCH_64) || HALFWORD_HEAP /* XXX:PaN - Should use ARCH_64 variant instead */ Uint high, low; # endif last_op->a[arg].val = new_literal(stp, &hp, FLOAT_SIZE_OBJECT); hp[0] = HEADER_FLONUM; last_op->a[arg].type = TAG_q; -# ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP GetInt(stp, 8, hp[1]); # else GetInt(stp, 4, high); @@ -1575,10 +1610,10 @@ load_code(LoaderState* stp) break; case 3: /* Allocation list. */ { - Uint n; - Uint type; - Uint val; - Uint words = 0; + UWord n; + UWord type; + UWord val; + UWord words = 0; stp->new_float_instructions = 1; GetTagAndValue(stp, tag, n); @@ -1607,7 +1642,7 @@ load_code(LoaderState* stp) } case 4: /* Literal. */ { - Uint val; + UWord val; GetTagAndValue(stp, tag, val); VerifyTag(stp, tag, TAG_u); @@ -1734,7 +1769,7 @@ load_code(LoaderState* stp) } stp->specific_op = specific; - Need(opc[stp->specific_op].sz+2); /* Extra margin for packing */ + CodeNeed(opc[stp->specific_op].sz+2); /* Extra margin for packing */ code[ci++] = BeamOpCode(stp->specific_op); } @@ -1772,7 +1807,7 @@ load_code(LoaderState* stp) case 'c': /* Tagged constant */ switch (tag) { case TAG_i: - code[ci++] = make_small(tmp_op->a[arg].val); + code[ci++] = (UWord) make_small((Uint) tmp_op->a[arg].val); break; case TAG_a: code[ci++] = tmp_op->a[arg].val; @@ -1802,7 +1837,7 @@ load_code(LoaderState* stp) code[ci++] = make_yreg(tmp_op->a[arg].val); break; case TAG_i: - code[ci++] = make_small(tmp_op->a[arg].val); + code[ci++] = (UWord) make_small((Uint)tmp_op->a[arg].val); break; case TAG_a: code[ci++] = tmp_op->a[arg].val; @@ -1896,12 +1931,12 @@ load_code(LoaderState* stp) if (stp->import[i].bf == NULL) { LoadError1(stp, "not a BIF: import table index %d", i); } - code[ci++] = (Eterm) stp->import[i].bf; + code[ci++] = (UWord) stp->import[i].bf; break; - case 'P': /* Byte offset into tuple */ + case 'P': /* Byte offset into tuple */ /* XXX:PaN - * sizeof(Eterm or Eterm *) ? */ VerifyTag(stp, tag, TAG_u); tmp = tmp_op->a[arg].val; - code[ci++] = (Eterm) ((tmp_op->a[arg].val+1) * sizeof(Eterm *)); + code[ci++] = (UWord) ((tmp_op->a[arg].val+1) * sizeof(Eterm)); break; case 'l': /* Floating point register. */ VerifyTag(stp, tag_to_letter[tag], *sign); @@ -1925,17 +1960,17 @@ load_code(LoaderState* stp) for ( ; arg < tmp_op->arity; arg++) { switch (tmp_op->a[arg].type) { case TAG_i: - Need(1); + CodeNeed(1); code[ci++] = make_small(tmp_op->a[arg].val); break; case TAG_u: case TAG_a: case TAG_v: - Need(1); + CodeNeed(1); code[ci++] = tmp_op->a[arg].val; break; case TAG_f: - Need(1); + CodeNeed(1); code[ci] = stp->labels[tmp_op->a[arg].val].patches; stp->labels[tmp_op->a[arg].val].patches = ci; ci++; @@ -1947,24 +1982,41 @@ load_code(LoaderState* stp) lit = stp->literals[tmp_op->a[arg].val].term; if (is_big(lit)) { Eterm* bigp; + Eterm *tmp; Uint size; + Uint term_size; bigp = big_val(lit); - size = bignum_header_arity(*bigp); - Need(size+1); - code[ci++] = *bigp++; - while (size-- > 0) { - code[ci++] = *bigp++; + term_size = bignum_header_arity(*bigp); + size = TermWords(term_size + 1); + CodeNeed(size); + tmp = (Eterm *) (code + ci); + *tmp++ = *bigp++; + while (term_size-- > 0) { + *tmp++ = *bigp++; } + ci +=size; } else if (is_float(lit)) { -#ifdef ARCH_64 - Need(1); +#if defined(ARCH_64) && !HALFWORD_HEAP + CodeNeed(1); code[ci++] = float_val(stp->literals[tmp_op->a[arg].val].term)[1]; +#elif HALFWORD_HEAP + Eterm* fptr; + Uint size; + Eterm *tmp; + + fptr = float_val(stp->literals[tmp_op->a[arg].val].term)+1; + size = TermWords(2); + CodeNeed(size); + tmp = (Eterm *) (code + ci); + *tmp++ = *fptr++; + *tmp = *fptr; + ci += size; #else Eterm* fptr; fptr = float_val(stp->literals[tmp_op->a[arg].val].term)+1; - Need(2); + CodeNeed(2); code[ci++] = *fptr++; code[ci++] = *fptr; #endif @@ -1978,7 +2030,7 @@ load_code(LoaderState* stp) tag_to_letter[tmp_op->a[arg].type]); } } - +#if !HALFWORD_HEAP /* XXX:PaN - just disabled during development */ /* * The packing engine. */ @@ -1987,7 +2039,7 @@ load_code(LoaderState* stp) 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... */ for (prog = opc[stp->specific_op].pack; *prog; prog++) { switch (*prog) { case 'g': /* Get instruction; push on stack. */ @@ -2015,7 +2067,7 @@ load_code(LoaderState* stp) } ASSERT(sp == stack); /* Incorrect program? */ } - +#endif /* !HALFWORD_HEAP */ /* * Handle a few special cases. */ @@ -2037,9 +2089,9 @@ load_code(LoaderState* stp) /* Must make room for call_nif op */ int pad = MIN_FUNC_SZ - (finfo_ix - last_func_start); ASSERT(pad > 0 && pad < MIN_FUNC_SZ); - Need(pad); - sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FINFO_SZ*sizeof(Eterm)); - sys_memset(&code[finfo_ix], 0, pad*sizeof(Eterm)); + CodeNeed(pad); + sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FINFO_SZ*sizeof(UWord)); + sys_memset(&code[finfo_ix], 0, pad*sizeof(UWord)); ci += pad; stp->labels[last_label].value += pad; } @@ -2050,6 +2102,7 @@ load_code(LoaderState* stp) */ stp->function = code[ci-2]; stp->arity = code[ci-1]; + ASSERT(stp->labels[last_label].value == ci - FINFO_SZ); offset = MI_FUNCTIONS + function_number; code[offset] = stp->labels[last_label].patches; @@ -2161,7 +2214,6 @@ load_code(LoaderState* stp) } } -#undef Need load_error: return 0; @@ -2373,7 +2425,7 @@ gen_get_integer2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms, GenOpArg Live, GenOpArg Flags, GenOpArg Dst) { GenOp* op; - Uint bits; + UWord bits; NEW_GENOP(stp, op); @@ -2838,14 +2890,14 @@ gen_literal_timeout(LoaderState* stp, GenOpArg Fail, GenOpArg Time) op->a[1].type = TAG_u; if (Time.type == TAG_i && (timeout = Time.val) >= 0 && -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP (timeout >> 32) == 0 #else 1 #endif ) { op->a[1].val = timeout; -#if !defined(ARCH_64) +#if !defined(ARCH_64) || HALFWORD_HEAP } else if (Time.type == TAG_q) { Eterm big; @@ -2856,11 +2908,13 @@ gen_literal_timeout(LoaderState* stp, GenOpArg Fail, GenOpArg Time) if (big_arity(big) > 1 || big_sign(big)) { goto error; } else { - (void) term_to_Uint(big, &op->a[1].val); + Uint u; + (void) term_to_Uint(big, &u); + op->a[1].val = (UWord) u; } #endif } else { -#if !defined(ARCH_64) +#if !defined(ARCH_64) || HALFWORD_HEAP error: #endif op->op = genop_i_wait_error_0; @@ -2883,14 +2937,14 @@ gen_literal_timeout_locked(LoaderState* stp, GenOpArg Fail, GenOpArg Time) op->a[1].type = TAG_u; if (Time.type == TAG_i && (timeout = Time.val) >= 0 && -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP (timeout >> 32) == 0 #else 1 #endif ) { op->a[1].val = timeout; -#ifndef ARCH_64 +#if !defined(ARCH_64) || HALFWORD_HEAP } else if (Time.type == TAG_q) { Eterm big; @@ -2901,11 +2955,13 @@ gen_literal_timeout_locked(LoaderState* stp, GenOpArg Fail, GenOpArg Time) if (big_arity(big) > 1 || big_sign(big)) { goto error; } else { - (void) term_to_Uint(big, &op->a[1].val); + Uint u; + (void) term_to_Uint(big, &u); + op->a[1].val = (UWord) u; } #endif } else { -#ifndef ARCH_64 +#if !defined(ARCH_64) || HALFWORD_HEAP error: #endif op->op = genop_i_wait_error_locked_0; @@ -3321,7 +3377,7 @@ gen_make_fun2(LoaderState* stp, GenOpArg idx) op->op = genop_i_make_fun_2; op->arity = 2; op->a[0].type = TAG_u; - op->a[0].val = (Uint) fe; + op->a[0].val = (UWord) fe; op->a[1].type = TAG_u; op->a[1].val = stp->lambdas[idx.val].num_free; op->next = NULL; @@ -3376,7 +3432,8 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif, static int freeze_code(LoaderState* stp) { - Eterm* code = stp->code; + UWord* code = stp->code; + Uint *literal_end = NULL; Uint index; int i; byte* str_table; @@ -3401,46 +3458,49 @@ freeze_code(LoaderState* stp) * Calculate the final size of the code. */ - size = (stp->ci + stp->total_literal_size) * sizeof(Eterm) + + size = (stp->ci * sizeof(UWord)) + (stp->total_literal_size * sizeof(Eterm)) + strtab_size + attr_size + compile_size; /* * Move the code to its final location. */ - code = (Eterm *) erts_realloc(ERTS_ALC_T_CODE, (void *) code, size); - + code = (UWord *) erts_realloc(ERTS_ALC_T_CODE, (void *) code, size); + CHKBLK(ERTS_ALC_T_CODE,code); /* * Place a pointer to the op_int_code_end instruction in the * function table in the beginning of the file. */ - code[MI_FUNCTIONS+stp->num_functions] = (Eterm) (code + stp->ci - 1); + code[MI_FUNCTIONS+stp->num_functions] = (UWord) (code + stp->ci - 1); + CHKBLK(ERTS_ALC_T_CODE,code); /* * Store the pointer to the on_load function. */ if (stp->on_load) { - code[MI_ON_LOAD_FUNCTION_PTR] = (Eterm) (code + stp->on_load); + code[MI_ON_LOAD_FUNCTION_PTR] = (UWord) (code + stp->on_load); } else { code[MI_ON_LOAD_FUNCTION_PTR] = 0; } + CHKBLK(ERTS_ALC_T_CODE,code); + literal_end = (Uint *) (code+stp->ci); /* * Place the literal heap directly after the code and fix up all * put_literal instructions that refer to it. */ { - Eterm* ptr; - Eterm* low; - Eterm* high; + Uint* ptr; + Uint* low; + Uint* high; LiteralPatch* lp; - low = code+stp->ci; + low = (Uint *) (code+stp->ci); high = low + stp->total_literal_size; - code[MI_LITERALS_START] = (Eterm) low; - code[MI_LITERALS_END] = (Eterm) high; + code[MI_LITERALS_START] = (UWord) low; + code[MI_LITERALS_END] = (UWord) high; ptr = low; for (i = 0; i < stp->num_literals; i++) { Uint offset; @@ -3472,7 +3532,7 @@ freeze_code(LoaderState* stp) } lp = stp->literal_patches; while (lp != 0) { - Uint* op_ptr; + UWord* op_ptr; Uint literal; Literal* lit; @@ -3485,38 +3545,48 @@ freeze_code(LoaderState* stp) op_ptr[0] = literal; lp = lp->next; } - stp->ci += stp->total_literal_size; + literal_end += stp->total_literal_size; } /* * Place the string table and, optionally, attributes, after the literal heap. */ + CHKBLK(ERTS_ALC_T_CODE,code); - sys_memcpy(code+stp->ci, stp->chunks[STR_CHUNK].start, strtab_size); - str_table = (byte *) (code+stp->ci); + sys_memcpy(literal_end, stp->chunks[STR_CHUNK].start, strtab_size); + CHKBLK(ERTS_ALC_T_CODE,code); + str_table = (byte *) literal_end; if (attr_size) { byte* attr = str_table + strtab_size; sys_memcpy(attr, stp->chunks[ATTR_CHUNK].start, stp->chunks[ATTR_CHUNK].size); - code[MI_ATTR_PTR] = (Eterm) attr; - code[MI_ATTR_SIZE] = (Eterm) stp->chunks[ATTR_CHUNK].size; + code[MI_ATTR_PTR] = (UWord) attr; + code[MI_ATTR_SIZE] = (UWord) stp->chunks[ATTR_CHUNK].size; decoded_size = erts_decode_ext_size(attr, attr_size, 0); if (decoded_size < 0) { LoadError0(stp, "bad external term representation of module attributes"); } code[MI_ATTR_SIZE_ON_HEAP] = decoded_size; } + CHKBLK(ERTS_ALC_T_CODE,code); if (compile_size) { byte* compile_info = str_table + strtab_size + attr_size; + CHKBLK(ERTS_ALC_T_CODE,code); sys_memcpy(compile_info, stp->chunks[COMPILE_CHUNK].start, stp->chunks[COMPILE_CHUNK].size); - code[MI_COMPILE_PTR] = (Eterm) compile_info; - code[MI_COMPILE_SIZE] = (Eterm) stp->chunks[COMPILE_CHUNK].size; + CHKBLK(ERTS_ALC_T_CODE,code); + code[MI_COMPILE_PTR] = (UWord) compile_info; + CHKBLK(ERTS_ALC_T_CODE,code); + code[MI_COMPILE_SIZE] = (UWord) stp->chunks[COMPILE_CHUNK].size; + CHKBLK(ERTS_ALC_T_CODE,code); decoded_size = erts_decode_ext_size(compile_info, compile_size, 0); + CHKBLK(ERTS_ALC_T_CODE,code); if (decoded_size < 0) { LoadError0(stp, "bad external term representation of compilation information"); } + CHKBLK(ERTS_ALC_T_CODE,code); code[MI_COMPILE_SIZE_ON_HEAP] = decoded_size; } + CHKBLK(ERTS_ALC_T_CODE,code); /* @@ -3529,9 +3599,10 @@ freeze_code(LoaderState* stp) while (index != 0) { Uint next = code[index]; code[index] = BeamOpCode(op_put_string_IId); - code[index+2] = (Uint) (str_table + code[index+2] + code[index+1] - 1); + code[index+2] = (UWord) (str_table + code[index+2] + code[index+1] - 1); index = next; } + CHKBLK(ERTS_ALC_T_CODE,code); /* * Go through all i_new_bs_put_strings instructions, restore the pointer to @@ -3543,23 +3614,25 @@ freeze_code(LoaderState* stp) while (index != 0) { Uint next = code[index]; code[index] = BeamOpCode(op_bs_put_string_II); - code[index+2] = (Uint) (str_table + code[index+2]); + code[index+2] = (UWord) (str_table + code[index+2]); index = next; } + CHKBLK(ERTS_ALC_T_CODE,code); { StringPatch* sp = stp->string_patches; while (sp != 0) { - Uint* op_ptr; + UWord* op_ptr; byte* strp; op_ptr = code + sp->pos; strp = str_table + op_ptr[0]; - op_ptr[0] = (Eterm) strp; + op_ptr[0] = (UWord) strp; sp = sp->next; } } + CHKBLK(ERTS_ALC_T_CODE,code); /* * Resolve all labels. @@ -3579,10 +3652,11 @@ freeze_code(LoaderState* stp) ASSERT(this_patch < stp->ci); next_patch = code[this_patch]; ASSERT(next_patch < stp->ci); - code[this_patch] = (Uint) (code + value); + code[this_patch] = (UWord) (code + value); this_patch = next_patch; } } + CHKBLK(ERTS_ALC_T_CODE,code); /* * Fix all catch_yf instructions. @@ -3590,13 +3664,14 @@ freeze_code(LoaderState* stp) index = stp->catches; catches = BEAM_CATCHES_NIL; while (index != 0) { - Uint next = code[index]; + UWord next = code[index]; code[index] = BeamOpCode(op_catch_yf); - catches = beam_catches_cons((Uint*)code[index+2], catches); + catches = beam_catches_cons((UWord *)code[index+2], catches); code[index+2] = make_catch(catches); index = next; } stp->catches = catches; + CHKBLK(ERTS_ALC_T_CODE,code); /* * Save the updated code pointer and code size. @@ -3605,6 +3680,7 @@ freeze_code(LoaderState* stp) stp->code = code; stp->loaded_size = size; + CHKBLK(ERTS_ALC_T_CODE,code); return 1; load_error: @@ -3638,7 +3714,7 @@ final_touch(LoaderState* stp) * callable yet. */ ep->address = ep->code+3; - ep->code[4] = (Eterm) stp->export[i].address; + ep->code[4] = (UWord) stp->export[i].address; } } @@ -3650,14 +3726,14 @@ final_touch(LoaderState* stp) Eterm mod; Eterm func; Uint arity; - Uint import; + UWord import; Uint current; Uint next; mod = stp->import[i].module; func = stp->import[i].function; arity = stp->import[i].arity; - import = (Uint) erts_export_put(mod, func, arity); + import = (UWord) erts_export_put(mod, func, arity); current = stp->import[i].patches; while (current != 0) { ASSERT(current < stp->ci); @@ -3675,7 +3751,7 @@ final_touch(LoaderState* stp) for (i = 0; i < stp->num_lambdas; i++) { unsigned entry_label = stp->lambdas[i].label; ErlFunEntry* fe = stp->lambdas[i].fe; - Eterm* code_ptr = (Eterm *) (stp->code + stp->labels[entry_label].value); + UWord* code_ptr = (UWord *) (stp->code + stp->labels[entry_label].value); if (fe->address[0] != 0) { /* @@ -3807,7 +3883,7 @@ transform_engine(LoaderState* st) if (i >= st->num_imports || st->import[i].bf == NULL) goto restart; if (bif_number != -1 && - bif_export[bif_number]->code[4] != (Uint) st->import[i].bf) { + bif_export[bif_number]->code[4] != (UWord) st->import[i].bf) { goto restart; } } @@ -4071,7 +4147,7 @@ load_printf(int line, LoaderState* context, char *fmt,...) static int -get_int_val(LoaderState* stp, Uint len_code, Uint* result) +get_int_val(LoaderState* stp, Uint len_code, UWord* result) { Uint count; Uint val; @@ -4103,7 +4179,7 @@ get_int_val(LoaderState* stp, Uint len_code, Uint* result) static int -get_erlang_integer(LoaderState* stp, Uint len_code, Uint* result) +get_erlang_integer(LoaderState* stp, Uint len_code, UWord* result) { Uint count; Sint val; @@ -4124,11 +4200,12 @@ get_erlang_integer(LoaderState* stp, Uint len_code, Uint* result) count = len_code + 2; } else { Uint tag; + UWord len_word; ASSERT(len_code == 7); - GetTagAndValue(stp, tag, len_code); + GetTagAndValue(stp, tag, len_word); VerifyTag(stp, TAG_u, tag); - count = len_code + 9; + count = len_word + 9; } /* @@ -4376,7 +4453,7 @@ functions_in_module(Process* p, /* Process whose heap to use. */ Eterm mod) /* Tagged atom for module. */ { Module* modp; - Eterm* code; + UWord* code; int i; Uint num_functions; Eterm* hp; @@ -4394,9 +4471,9 @@ functions_in_module(Process* p, /* Process whose heap to use. */ num_functions = code[MI_NUM_FUNCTIONS]; hp = HAlloc(p, 5*num_functions); for (i = num_functions-1; i >= 0 ; i--) { - Eterm* func_info = (Eterm *) code[MI_FUNCTIONS+i]; - Eterm name = func_info[3]; - int arity = func_info[4]; + UWord* func_info = (UWord *) code[MI_FUNCTIONS+i]; + Eterm name = (Eterm) func_info[3]; + int arity = (int) func_info[4]; Eterm tuple; ASSERT(is_atom(name)); @@ -4419,7 +4496,7 @@ static Eterm native_addresses(Process* p, Eterm mod) { Module* modp; - Eterm* code; + UWord* code; int i; Eterm* hp; Uint num_functions; @@ -4442,9 +4519,9 @@ native_addresses(Process* p, Eterm mod) hp = HAlloc(p, need); hp_end = hp + need; for (i = num_functions-1; i >= 0 ; i--) { - Eterm* func_info = (Eterm *) code[MI_FUNCTIONS+i]; - Eterm name = func_info[3]; - int arity = func_info[4]; + UWord* func_info = (UWord *) code[MI_FUNCTIONS+i]; + Eterm name = (Eterm) func_info[3]; + int arity = (int) func_info[4]; Eterm tuple; ASSERT(is_atom(name)); @@ -4486,7 +4563,7 @@ exported_from_module(Process* p, /* Process whose heap to use. */ Eterm tuple; if (ep->address == ep->code+3 && - ep->code[3] == (Eterm) em_call_error_handler) { + ep->code[3] == (UWord) em_call_error_handler) { /* There is a call to the function, but it does not exist. */ continue; } @@ -4519,7 +4596,7 @@ attributes_for_module(Process* p, /* Process whose heap to use. */ { Module* modp; - Eterm* code; + UWord* code; Eterm* hp; byte* ext; Eterm result = NIL; @@ -4559,7 +4636,7 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ Eterm mod) /* Tagged atom for module. */ { Module* modp; - Eterm* code; + UWord* code; Eterm* hp; byte* ext; Eterm result = NIL; @@ -4591,8 +4668,8 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ /* * Returns a pointer to {module, function, arity}, or NULL if not found. */ -Eterm* -find_function_from_pc(Eterm* pc) +UWord * +find_function_from_pc(UWord* pc) { Range* low = modules; Range* high = low + num_loaded_modules; @@ -4604,9 +4681,9 @@ find_function_from_pc(Eterm* pc) } else if (pc > mid->end) { low = mid + 1; } else { - Eterm** low1 = (Eterm **) (mid->start + MI_FUNCTIONS); - Eterm** high1 = low1 + mid->start[MI_NUM_FUNCTIONS]; - Eterm** mid1; + UWord** low1 = (UWord **) (mid->start + MI_FUNCTIONS); + UWord** high1 = low1 + mid->start[MI_NUM_FUNCTIONS]; + UWord** mid1; while (low1 < high1) { mid1 = low1 + (high1-low1) / 2; @@ -4719,10 +4796,10 @@ code_module_md5_1(Process* p, Eterm Bin) #define WORDS_PER_FUNCTION 6 -static Eterm* -make_stub(Eterm* fp, Eterm mod, Eterm func, Uint arity, Uint native, Eterm OpCode) +static UWord* +make_stub(UWord* fp, Eterm mod, Eterm func, Uint arity, Uint native, UWord OpCode) { - fp[0] = (Eterm) BeamOp(op_i_func_info_IaaI); + fp[0] = (UWord) BeamOp(op_i_func_info_IaaI); fp[1] = native; fp[2] = mod; fp[3] = func; @@ -4741,14 +4818,14 @@ static byte* stub_copy_info(LoaderState* stp, int chunk, /* Chunk: ATTR_CHUNK or COMPILE_CHUNK */ byte* info, /* Where to store info. */ - Eterm* ptr_word, /* Where to store pointer into info. */ - Eterm* size_word) /* Where to store size of info. */ + UWord* ptr_word, /* Where to store pointer into info. */ + UWord* size_word) /* Where to store size of info. */ { Sint decoded_size; Uint size = stp->chunks[chunk].size; if (size != 0) { memcpy(info, stp->chunks[chunk].start, size); - *ptr_word = (Eterm) info; + *ptr_word = (UWord) info; decoded_size = erts_decode_ext_size(info, size, 0); if (decoded_size < 0) { return 0; @@ -4791,7 +4868,7 @@ stub_read_export_table(LoaderState* stp) } static void -stub_final_touch(LoaderState* stp, Eterm* fp) +stub_final_touch(LoaderState* stp, UWord* fp) { int i; int n = stp->num_exps; @@ -4978,12 +5055,12 @@ Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) { LoaderState state; - Eterm Funcs; - Eterm Patchlist; + UWord Funcs; + UWord Patchlist; Eterm* tp; - Eterm* code = NULL; - Eterm* ptrs; - Eterm* fp; + UWord* code = NULL; + UWord* ptrs; + UWord* fp; byte* info; Uint ci; int n; @@ -5072,7 +5149,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Allocate memory for the stub module. */ - code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(Eterm); + code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(UWord); code_size += state.chunks[ATTR_CHUNK].size; code_size += state.chunks[COMPILE_CHUNK].size; code = erts_alloc_fnf(ERTS_ALC_T_CODE, code_size); @@ -5141,7 +5218,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Set the pointer and make the stub. Put a return instruction * as the body until we know what kind of trap we should put there. */ - ptrs[i] = (Eterm) fp; + ptrs[i] = (UWord) fp; #ifdef HIPE op = (Eterm) BeamOpCode(op_hipe_trap_call); /* Might be changed later. */ #else @@ -5154,8 +5231,8 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Insert the last pointer and the int_code_end instruction. */ - ptrs[i] = (Eterm) fp; - *fp++ = (Eterm) BeamOp(op_int_code_end); + ptrs[i] = (UWord) fp; + *fp++ = (UWord) BeamOp(op_int_code_end); /* * Copy attributes and compilation information. @@ -5222,9 +5299,9 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) #undef WORDS_PER_FUNCTION -static int safe_mul(Uint a, Uint b, Uint* resp) +static int safe_mul(UWord a, UWord b, UWord* resp) { - Uint res = a * b; + UWord res = a * b; *resp = res; if (b == 0) { diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h index c17844a553..a24460d2a5 100644 --- a/erts/emulator/beam/beam_load.h +++ b/erts/emulator/beam/beam_load.h @@ -44,13 +44,13 @@ extern void** beam_ops; #endif -extern Eterm beam_debug_apply[]; -extern Eterm* em_call_error_handler; -extern Eterm* em_apply_bif; -extern Eterm* em_call_traced_function; +extern UWord beam_debug_apply[]; +extern UWord* em_call_error_handler; +extern UWord* em_apply_bif; +extern UWord* em_call_traced_function; typedef struct { - Eterm* start; /* Pointer to start of module. */ - Eterm* end; /* Points one word beyond last function in module. */ + UWord* start; /* Pointer to start of module. */ + UWord* end; /* Points one word beyond last function in module. */ } Range; /* diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 0b21cf3afd..3aa258b675 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3470,7 +3470,12 @@ BIF_RETTYPE make_fun_3(BIF_ALIST_3) } hp = HAlloc(BIF_P, 2); hp[0] = HEADER_EXPORT; +#if HALFWORD_HEAP + /* Yes, May be misaligned, but X86_64 will fix it... */ + memcpy(hp+1,erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity),sizeof(Export *)); +#else hp[1] = (Eterm) erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity); +#endif BIF_RET(make_export(hp)); } @@ -3886,7 +3891,7 @@ BIF_RETTYPE hash_2(BIF_ALIST_2) if ((range = signed_val(BIF_ARG_2)) <= 0) { /* [1..MAX_SMALL] */ BIF_ERROR(BIF_P, BADARG); } -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP if (range > ((1L << 27) - 1)) BIF_ERROR(BIF_P, BADARG); #endif @@ -3958,7 +3963,7 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2) /* * Return either a small or a big. Use the heap for bigs if there is room. */ -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP BIF_RET(make_small(final_hash)); #else if (IS_USMALL(0, final_hash)) { @@ -4120,8 +4125,8 @@ void erts_init_bif(void) #else bif_return_trap_export.code[2] = 1; #endif - bif_return_trap_export.code[3] = (Eterm) em_apply_bif; - bif_return_trap_export.code[4] = (Eterm) &bif_return_trap; + bif_return_trap_export.code[3] = (UWord) em_apply_bif; + bif_return_trap_export.code[4] = (UWord) &bif_return_trap; flush_monitor_message_trap = erts_export_put(am_erlang, am_flush_monitor_message, diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h index 05e9b78c28..4342a6cf4e 100644 --- a/erts/emulator/beam/bif.h +++ b/erts/emulator/beam/bif.h @@ -125,7 +125,7 @@ do { \ #define ERTS_BIF_PREP_TRAP0(Ret, Trap, Proc) \ do { \ (Proc)->arity = 0; \ - (Proc)->def_arg_reg[3] = (Eterm) (Trap->address); \ + *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -134,7 +134,8 @@ do { \ do { \ (Proc)->arity = 1; \ (Proc)->def_arg_reg[0] = (Eterm) (A0); \ - (Proc)->def_arg_reg[3] = (Eterm) ((Trap)->address); \ + *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ + (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -144,7 +145,8 @@ do { \ (Proc)->arity = 2; \ (Proc)->def_arg_reg[0] = (Eterm) (A0); \ (Proc)->def_arg_reg[1] = (Eterm) (A1); \ - (Proc)->def_arg_reg[3] = (Eterm) ((Trap)->address); \ + *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ + (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -155,14 +157,15 @@ do { \ (Proc)->def_arg_reg[0] = (Eterm) (A0); \ (Proc)->def_arg_reg[1] = (Eterm) (A1); \ (Proc)->def_arg_reg[2] = (Eterm) (A2); \ - (Proc)->def_arg_reg[3] = (Eterm) ((Trap)->address); \ + *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ + (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) #define BIF_TRAP0(p, Trap_) do { \ (p)->arity = 0; \ - (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \ + *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) @@ -170,7 +173,7 @@ do { \ #define BIF_TRAP1(Trap_, p, A0) do { \ (p)->arity = 1; \ (p)->def_arg_reg[0] = (A0); \ - (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \ + *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) @@ -179,7 +182,7 @@ do { \ (p)->arity = 2; \ (p)->def_arg_reg[0] = (A0); \ (p)->def_arg_reg[1] = (A1); \ - (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \ + *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) @@ -189,14 +192,14 @@ do { \ (p)->def_arg_reg[0] = (A0); \ (p)->def_arg_reg[1] = (A1); \ (p)->def_arg_reg[2] = (A2); \ - (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \ + *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) #define BIF_TRAP_CODE_PTR_0(p, Code_) do { \ (p)->arity = 0; \ - (p)->def_arg_reg[3] = (Eterm) (Code_); \ + *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) (Code_); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index 03c88da8c6..b8464ded28 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1459,7 +1459,31 @@ Eterm uint_to_big(Uint x, Eterm *y) BIG_DIGIT(y, 0) = x; return make_big(y); } +/* +** convert UWord to bigint +** (must only be used if x is to big to be stored as a small) +** Allocation is tricky, the heap need has to be calculated +** with the macro BIG_UWORD_HEAP_SIZE(x) +*/ +Eterm uword_to_big(UWord x, Eterm *y) +{ +#if HALFWORD_HEAP + Uint upper = x >> 32; + Uint lower = x & 0xFFFFFFFFUL; + if (upper == 0) { + *y = make_pos_bignum_header(1); + } else { + *y = make_pos_bignum_header(2); + BIG_DIGIT(y, 1) = upper; + } + BIG_DIGIT(y, 0) = lower; +#else + *y = make_pos_bignum_header(1); + BIG_DIGIT(y, 0) = x; +#endif + return make_big(y); +} /* ** convert signed int to bigint diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h index b8e38d482c..d74da7cef7 100644 --- a/erts/emulator/beam/big.h +++ b/erts/emulator/beam/big.h @@ -34,7 +34,7 @@ typedef Uint ErtsDigit; -#if (SIZEOF_VOID_P == 4) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) +#if ((SIZEOF_VOID_P == 4) || HALFWORD_HEAP) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) /* Assume 32-bit machine with long long support */ typedef Uint64 ErtsDoubleDigit; typedef Uint16 ErtsHalfDigit; @@ -58,7 +58,7 @@ typedef Uint32 ErtsHalfDigit; typedef Uint dsize_t; /* Vector size type */ -#define D_EXP (SIZEOF_VOID_P*8) +#define D_EXP (ERTS_SIZEOF_ETERM*8) #define D_MASK ((ErtsDigit)(-1)) /* D_BASE-1 */ /* macros for bignum objects */ @@ -88,6 +88,12 @@ typedef Uint dsize_t; /* Vector size type */ #define BIG_UINT_HEAP_SIZE (1 + 1) /* always, since sizeof(Uint) <= sizeof(Eterm) */ +#if HALFWORD_HEAP +#define BIG_UWORD_HEAP_SIZE(UW) (((UW) >> (sizeof(Uint) * 8)) ? 3 : 2) +#else +#define BIG_UWORD_HEAP_SIZE(UW) BIG_UINT_HEAP_SIZE +#endif + #ifdef ARCH_32 #define ERTS_UINT64_BIG_HEAP_SIZE__(X) \ @@ -136,6 +142,7 @@ int big_ucomp (Eterm, Eterm); int big_to_double(Eterm x, double* resp); Eterm small_to_big(Sint, Eterm*); Eterm uint_to_big(Uint, Eterm*); +Eterm uword_to_big(UWord, Eterm*); Eterm erts_make_integer(Uint, Process *); dsize_t big_bytes(Eterm); diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index cc69977b79..0b7afcac02 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -381,7 +381,7 @@ loaded(int to, void *to_arg) int i; int old = 0; int cur = 0; - Eterm* code; + UWord* code; /* * Calculate and print totals. diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 64ab88fc45..eb8fb02904 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -1620,9 +1620,9 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy) */ data_size >>= (10-4); -#if defined(ARCH_64) +#if defined(ARCH_64) && !HALFWORD_HEAP data_size &= 0x003fffffffffffff; -#elif defined(ARCH_32) +#elif defined(ARCH_32) || HALFWORD_HEAP data_size &= 0x003fffff; #else # error "Ohh come on ... !?!" @@ -1706,9 +1706,9 @@ dist_port_commandv(Port *prt, ErtsDistOutputBuf *obuf) } -#if defined(ARCH_64) +#if defined(ARCH_64) && !HALFWORD_HEAP #define ERTS_PORT_REDS_MASK__ 0x003fffffffffffffL -#elif defined(ARCH_32) +#elif defined(ARCH_32) || HALFWORD_HEAP #define ERTS_PORT_REDS_MASK__ 0x003fffff #else # error "Ohh come on ... !?!" diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index 4403a19f4a..9c5210fed6 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -220,7 +220,7 @@ set_default_ll_alloc_opts(struct au_init *ip) ip->init.util.ramv = 0; ip->init.util.mmsbc = 0; ip->init.util.mmmbc = 0; - ip->init.util.sbct = ~((Uint) 0); + ip->init.util.sbct = ~((UWord) 0); ip->init.util.name_prefix = "ll_"; ip->init.util.alloc_no = ERTS_ALC_A_LONG_LIVED; #ifndef SMALL_MEMORY @@ -394,7 +394,7 @@ static void init_thr_ix(int static_ixs); void erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) { - Uint extra_block_size = 0; + UWord extra_block_size = 0; int i; erts_alc_hndl_args_init_t init = { 0, @@ -542,7 +542,6 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) sys_alloc_opt(SYS_ALLOC_OPT_TRIM_THRESHOLD, init.trim_threshold); sys_alloc_opt(SYS_ALLOC_OPT_TOP_PAD, init.top_pad); - if (erts_allctrs_info[ERTS_FIX_CORE_ALLOCATOR].enabled) erts_fix_core_allocator_ix = ERTS_FIX_CORE_ALLOCATOR; else @@ -719,8 +718,8 @@ start_au_allocator(ErtsAlcType_t alctr_n, init->init.util.name_prefix); tspec->allctr = (Allctr_t **) states; states = ((char *) states) + sizeof(Allctr_t *) * (tspec->size + 1); - states = ((((Uint) states) & ERTS_CACHE_LINE_MASK) - ? (void *) ((((Uint) states) & ~ERTS_CACHE_LINE_MASK) + states = ((((UWord) states) & ERTS_CACHE_LINE_MASK) + ? (void *) ((((UWord) states) & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE) : (void *) states); tspec->allctr[0] = init->thr_spec > 0 ? (Allctr_t *) state : (Allctr_t *) NULL; @@ -2948,9 +2947,9 @@ unsigned long erts_alc_test(unsigned long op, #endif -#define FENCE_SZ (3*sizeof(Uint)) +#define FENCE_SZ (3*sizeof(UWord)) -#ifdef ARCH_64 +#if defined(ARCH_64) #define FENCE_PATTERN 0xABCDEF97ABCDEF97 #else #define FENCE_PATTERN 0xABCDEF97 @@ -2960,7 +2959,7 @@ unsigned long erts_alc_test(unsigned long op, #define TYPE_PATTERN_SHIFT 16 #define FIXED_FENCE_PATTERN_MASK \ - (~((Uint) (TYPE_PATTERN_MASK << TYPE_PATTERN_SHIFT))) + (~((UWord) (TYPE_PATTERN_MASK << TYPE_PATTERN_SHIFT))) #define FIXED_FENCE_PATTERN \ (FENCE_PATTERN & FIXED_FENCE_PATTERN_MASK) @@ -2971,21 +2970,60 @@ unsigned long erts_alc_test(unsigned long op, (((P) >> TYPE_PATTERN_SHIFT) & TYPE_PATTERN_MASK) +#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG +static void *check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func); + +void check_allocated_block( Uint type, void *blk) +{ + Uint dummy; + check_memory_fence(blk, &dummy, ERTS_ALC_T2N(type), ERTS_ALC_O_FREE); +} + +void check_allocators(void) +{ + int i; + if (!erts_initialized) + return; + for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; ++i) { + if (erts_allctrs_info[i].alloc_util) { + ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) erts_allctrs[i].extra; + Allctr_t *allctr = real_af->extra; + Carrier_t *ct; +#ifdef USE_THREADS + if (allctr->thread_safe) + erts_mtx_lock(&allctr->mutex); +#endif + + if (allctr->check_mbc) { + for (ct = allctr->mbc_list.first; ct; ct = ct->next) { + fprintf(stderr,"Checking allocator %d\r\n",i); + allctr->check_mbc(allctr,ct); + } + } +#ifdef USE_THREADS + if (allctr->thread_safe) + erts_mtx_unlock(&allctr->mutex); +#endif + } + } +} +#endif + static void * set_memory_fence(void *ptr, Uint sz, ErtsAlcType_t n) { - Uint *ui_ptr; - Uint pattern; + UWord *ui_ptr; + UWord pattern; if (!ptr) return NULL; - ui_ptr = (Uint *) ptr; + ui_ptr = (UWord *) ptr; pattern = MK_PATTERN(n); *(ui_ptr++) = sz; *(ui_ptr++) = pattern; - memcpy((void *) (((char *) ui_ptr)+sz), (void *) &pattern, sizeof(Uint)); + memcpy((void *) (((char *) ui_ptr)+sz), (void *) &pattern, sizeof(UWord)); return (void *) ui_ptr; } @@ -2995,14 +3033,14 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func) { Uint sz; Uint found_type; - Uint pre_pattern; - Uint post_pattern; - Uint *ui_ptr; + UWord pre_pattern; + UWord post_pattern; + UWord *ui_ptr; if (!ptr) return NULL; - ui_ptr = (Uint *) ptr; + ui_ptr = (UWord *) ptr; pre_pattern = *(--ui_ptr); *size = sz = *(--ui_ptr); @@ -3015,7 +3053,7 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func) (unsigned long) ptr); } - memcpy((void *) &post_pattern, (void *) (((char *)ptr)+sz), sizeof(Uint)); + memcpy((void *) &post_pattern, (void *) (((char *)ptr)+sz), sizeof(UWord)); if (post_pattern != MK_PATTERN(n) || pre_pattern != post_pattern) { diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h index e7a203002f..3f090abdc2 100644 --- a/erts/emulator/beam/erl_alloc.h +++ b/erts/emulator/beam/erl_alloc.h @@ -553,7 +553,7 @@ NAME##_free(TYPE *p) \ } #ifdef DEBUG -#define ERTS_ALC_DBG_BLK_SZ(PTR) (*(((Uint *) (PTR)) - 2)) +#define ERTS_ALC_DBG_BLK_SZ(PTR) (*(((UWord *) (PTR)) - 2)) #endif /* #ifdef DEBUG */ #undef ERTS_ALC_INLINE diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index f808d3b66e..2d7077227f 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -138,6 +138,7 @@ type PEND_SUSPEND SHORT_LIVED PROCESSES pending_suspend type PROC_LIST SHORT_LIVED PROCESSES proc_list type FUN_ENTRY FIXED_SIZE CODE fun_entry type ATOM_TXT LONG_LIVED ATOM atom_text +type BEAM_REGISTER EHEAP PROCESSES beam_register type HEAP EHEAP PROCESSES heap type OLD_HEAP EHEAP PROCESSES old_heap type HEAP_FRAG EHEAP PROCESSES heap_frag diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index 8b71b51912..022a2829f6 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -69,14 +69,14 @@ static int initialized = 0; #if HAVE_ERTS_MSEG -#define INV_MSEG_UNIT_MASK ((Uint) (mseg_unit_size - 1)) +#define INV_MSEG_UNIT_MASK ((UWord) (mseg_unit_size - 1)) #define MSEG_UNIT_MASK (~INV_MSEG_UNIT_MASK) #define MSEG_UNIT_FLOOR(X) ((X) & MSEG_UNIT_MASK) #define MSEG_UNIT_CEILING(X) MSEG_UNIT_FLOOR((X) + INV_MSEG_UNIT_MASK) #endif -#define INV_SYS_ALLOC_CARRIER_MASK ((Uint) (sys_alloc_carrier_size - 1)) +#define INV_SYS_ALLOC_CARRIER_MASK ((UWord) (sys_alloc_carrier_size - 1)) #define SYS_ALLOC_CARRIER_MASK (~INV_SYS_ALLOC_CARRIER_MASK) #define SYS_ALLOC_CARRIER_FLOOR(X) ((X) & SYS_ALLOC_CARRIER_MASK) #define SYS_ALLOC_CARRIER_CEILING(X) \ @@ -85,7 +85,7 @@ static int initialized = 0; #undef ASSERT #define ASSERT ASSERT_EXPR -#define ERTS_ALCU_FLG_FAIL_REALLOC_MOVE ((Uint) 1) +#define ERTS_ALCU_FLG_FAIL_REALLOC_MOVE ((UWord) 1) #if 0 /* Can be useful for debugging */ @@ -114,12 +114,12 @@ static Uint mseg_unit_size; /* Blocks ... */ -#define SBC_BLK_FTR_FLG (((Uint) 1) << 0) -#define UNUSED1_BLK_FTR_FLG (((Uint) 1) << 1) -#define UNUSED2_BLK_FTR_FLG (((Uint) 1) << 2) +#define SBC_BLK_FTR_FLG (((UWord) 1) << 0) +#define UNUSED1_BLK_FTR_FLG (((UWord) 1) << 1) +#define UNUSED2_BLK_FTR_FLG (((UWord) 1) << 2) #define ABLK_HDR_SZ (sizeof(Block_t)) -#define FBLK_FTR_SZ (sizeof(Uint)) +#define FBLK_FTR_SZ (sizeof(UWord)) #define UMEMSZ2BLKSZ(AP, SZ) \ (ABLK_HDR_SZ + (SZ) <= (AP)->min_block_size \ @@ -130,14 +130,14 @@ static Uint mseg_unit_size; #define BLK2UMEM(P) ((void *) (((char *) (P)) + ABLK_HDR_SZ)) #define PREV_BLK_SZ(B) \ - ((Uint) (*(((Uint *) (B)) - 1) & SZ_MASK)) + ((UWord) (*(((UWord *) (B)) - 1) & SZ_MASK)) #define SET_BLK_SZ_FTR(B, SZ) \ - (*((Uint *) (((char *) (B)) + (SZ) - sizeof(Uint))) = (SZ)) + (*((UWord *) (((char *) (B)) + (SZ) - sizeof(UWord))) = (SZ)) -#define THIS_FREE_BLK_HDR_FLG (((Uint) 1) << 0) -#define PREV_FREE_BLK_HDR_FLG (((Uint) 1) << 1) -#define LAST_BLK_HDR_FLG (((Uint) 1) << 2) +#define THIS_FREE_BLK_HDR_FLG (((UWord) 1) << 0) +#define PREV_FREE_BLK_HDR_FLG (((UWord) 1) << 1) +#define LAST_BLK_HDR_FLG (((UWord) 1) << 2) #define SET_BLK_SZ(B, SZ) \ (ASSERT(((SZ) & FLG_MASK) == 0), \ @@ -156,11 +156,11 @@ static Uint mseg_unit_size; (*((Block_t *) (B)) &= ~LAST_BLK_HDR_FLG) #define SBH_THIS_FREE THIS_FREE_BLK_HDR_FLG -#define SBH_THIS_ALLOCED ((Uint) 0) +#define SBH_THIS_ALLOCED ((UWord) 0) #define SBH_PREV_FREE PREV_FREE_BLK_HDR_FLG -#define SBH_PREV_ALLOCED ((Uint) 0) +#define SBH_PREV_ALLOCED ((UWord) 0) #define SBH_LAST_BLK LAST_BLK_HDR_FLG -#define SBH_NOT_LAST_BLK ((Uint) 0) +#define SBH_NOT_LAST_BLK ((UWord) 0) #define SET_BLK_HDR(B, Sz, F) \ (ASSERT(((Sz) & FLG_MASK) == 0), *((Block_t *) (B)) = ((Sz) | (F))) @@ -200,7 +200,7 @@ static Uint mseg_unit_size; ((FTR) = 0) #define IS_SBC_BLK(B) \ - (IS_PREV_BLK_FREE((B)) && (((Uint *) (B))[-1] & SBC_BLK_FTR_FLG)) + (IS_PREV_BLK_FREE((B)) && (((UWord *) (B))[-1] & SBC_BLK_FTR_FLG)) #define IS_MBC_BLK(B) \ (!IS_SBC_BLK((B))) @@ -211,8 +211,8 @@ static Uint mseg_unit_size; /* Carriers ... */ -#define MSEG_CARRIER_HDR_FLAG (((Uint) 1) << 0) -#define SBC_CARRIER_HDR_FLAG (((Uint) 1) << 1) +#define MSEG_CARRIER_HDR_FLAG (((UWord) 1) << 0) +#define SBC_CARRIER_HDR_FLAG (((UWord) 1) << 1) #define SCH_SYS_ALLOC 0 #define SCH_MSEG MSEG_CARRIER_HDR_FLAG @@ -407,18 +407,18 @@ do { \ /* Debug stuff... */ #ifdef DEBUG -static Uint carrier_alignment; +static UWord carrier_alignment; #define DEBUG_SAVE_ALIGNMENT(C) \ do { \ - Uint algnmnt__ = sizeof(Unit_t) - (((Uint) (C)) % sizeof(Unit_t)); \ + UWord algnmnt__ = sizeof(Unit_t) - (((UWord) (C)) % sizeof(Unit_t)); \ carrier_alignment = MIN(carrier_alignment, algnmnt__); \ - ASSERT(((Uint) (C)) % sizeof(Uint) == 0); \ + ASSERT(((UWord) (C)) % sizeof(UWord) == 0); \ } while (0) #define DEBUG_CHECK_ALIGNMENT(P) \ do { \ - ASSERT(sizeof(Unit_t) - (((Uint) (P)) % sizeof(Unit_t)) \ + ASSERT(sizeof(Unit_t) - (((UWord) (P)) % sizeof(Unit_t)) \ >= carrier_alignment); \ - ASSERT(((Uint) (P)) % sizeof(Uint) == 0); \ + ASSERT(((UWord) (P)) % sizeof(UWord) == 0); \ } while (0) #else @@ -610,7 +610,7 @@ unlink_carrier(CarrierList_t *cl, Carrier_t *crr) } -static Block_t *create_carrier(Allctr_t *, Uint, Uint); +static Block_t *create_carrier(Allctr_t *, Uint, UWord); static void destroy_carrier(Allctr_t *, Block_t *); /* Multi block carrier alloc/realloc/free ... */ @@ -662,14 +662,14 @@ static ERTS_INLINE void mbc_alloc_finalize(Allctr_t *allctr, Block_t *blk, Uint org_blk_sz, - Uint flags, + UWord flags, Uint want_blk_sz, int valid_blk_info) { Uint blk_sz; Uint nxt_blk_sz; Block_t *nxt_blk; - Uint prev_free_flg = flags & PREV_FREE_BLK_HDR_FLG; + UWord prev_free_flg = flags & PREV_FREE_BLK_HDR_FLG; ASSERT(org_blk_sz >= want_blk_sz); ASSERT(blk); @@ -859,7 +859,7 @@ mbc_free(Allctr_t *allctr, void *p) } static void * -mbc_realloc(Allctr_t *allctr, void *p, Uint size, Uint flgs) +mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs) { void *new_p; Uint old_blk_sz; @@ -1150,7 +1150,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, Uint flgs) } else { Uint new_blk_sz; - Uint new_blk_flgs; + UWord new_blk_flgs; Uint prev_blk_sz; Uint blk_cpy_sz; @@ -1245,7 +1245,7 @@ do { \ static Block_t * -create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) +create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags) { Block_t *blk; Carrier_t *crr; @@ -1289,8 +1289,8 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) if (crr_sz < allctr->mbc_header_size + blk_sz) crr_sz = allctr->mbc_header_size + blk_sz; #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG - if (sizeof(Unit_t) == sizeof(Uint)) - crr_sz += sizeof(Uint); + if (sizeof(Unit_t) == sizeof(UWord)) + crr_sz += sizeof(UWord); #endif } crr_sz = MSEG_UNIT_CEILING(crr_sz); @@ -1330,8 +1330,8 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) && bcrr_sz < allctr->smallest_mbc_size) bcrr_sz = allctr->smallest_mbc_size; #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG - if (sizeof(Unit_t) == sizeof(Uint)) - bcrr_sz += sizeof(Uint); + if (sizeof(Unit_t) == sizeof(UWord)) + bcrr_sz += sizeof(UWord); #endif } @@ -1366,7 +1366,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) blk = SBC2BLK(allctr, crr); - SET_SBC_BLK_FTR(((Uint *) blk)[-1]); + SET_SBC_BLK_FTR(((UWord *) blk)[-1]); SET_BLK_HDR(blk, blk_sz, SBH_THIS_ALLOCED|SBH_PREV_FREE|SBH_LAST_BLK); link_carrier(&allctr->sbc_list, crr); @@ -1385,13 +1385,13 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) blk = MBC2FBLK(allctr, crr); #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG - if (sizeof(Unit_t) == sizeof(Uint)) - crr_sz -= sizeof(Uint); + if (sizeof(Unit_t) == sizeof(UWord)) + crr_sz -= sizeof(UWord); #endif blk_sz = UNIT_FLOOR(crr_sz - allctr->mbc_header_size); - SET_MBC_BLK_FTR(((Uint *) blk)[-1]); + SET_MBC_BLK_FTR(((UWord *) blk)[-1]); SET_BLK_HDR(blk, blk_sz, SBH_THIS_FREE|SBH_PREV_FREE|SBH_LAST_BLK); #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG @@ -1406,13 +1406,13 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) link_carrier(&allctr->mbc_list, crr); #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG - if (sizeof(Unit_t) == sizeof(Uint)) - crr_sz += sizeof(Uint); + if (sizeof(Unit_t) == sizeof(UWord)) + crr_sz += sizeof(UWord); #endif CHECK_1BLK_CARRIER(allctr, 0, is_mseg, crr, crr_sz, blk, blk_sz); #ifdef ERTS_ALLOC_UTIL_HARD_DEBUG - if (sizeof(Unit_t) == sizeof(Uint)) - crr_sz -= sizeof(Uint); + if (sizeof(Unit_t) == sizeof(UWord)) + crr_sz -= sizeof(UWord); #endif if (allctr->creating_mbc) (*allctr->creating_mbc)(allctr, crr); @@ -1424,11 +1424,12 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags) } static Block_t * -resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, Uint flags) +resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags) { Block_t *new_blk; Carrier_t *new_crr, *old_crr; - Uint create_flags, old_crr_sz, old_blk_sz, new_blk_sz, new_crr_sz; + UWord create_flags; + Uint old_crr_sz, old_blk_sz, new_blk_sz, new_crr_sz; Uint new_bcrr_sz; if (flags & CFLG_MBC) { @@ -2605,16 +2606,16 @@ erts_alcu_alloc_thr_pref(ErtsAlcType_t type, void *extra, Uint size) Allctr_t *allctr; void *res; - ASSERT(sizeof(Uint) == sizeof(Allctr_t *)); + ASSERT(sizeof(UWord) == sizeof(Allctr_t *)); ASSERT(ix > 0); if (ix >= tspec->size) ix = (ix % (tspec->size - 1)) + 1; allctr = tspec->allctr[ix]; erts_mtx_lock(&allctr->mutex); - res = do_erts_alcu_alloc(type, allctr, size + sizeof(Uint)); + res = do_erts_alcu_alloc(type, allctr, size + sizeof(UWord)); if (res) { *((Allctr_t **) res) = allctr; - res = (void *) (((char *) res) + sizeof(Uint)); + res = (void *) (((char *) res) + sizeof(UWord)); } erts_mtx_unlock(&allctr->mutex); DEBUG_CHECK_ALIGNMENT(res); @@ -2692,7 +2693,7 @@ void erts_alcu_free_thr_pref(ErtsAlcType_t type, void *unused, void *p) { if (p) { - void *ptr = (void *) (((char *) p) - sizeof(Uint)); + void *ptr = (void *) (((char *) p) - sizeof(UWord)); Allctr_t *allctr = *((Allctr_t **) ptr); erts_mtx_lock(&allctr->mutex); do_erts_alcu_free(type, allctr, ptr); @@ -2709,7 +2710,7 @@ do_erts_alcu_realloc(ErtsAlcType_t type, void *extra, void *p, Uint size, - Uint flgs) + UWord flgs) { Allctr_t *allctr = (Allctr_t *) extra; Block_t *blk; @@ -2981,7 +2982,7 @@ erts_alcu_realloc_thr_pref(ErtsAlcType_t type, void *extra, void *p, Uint size) if (!p) return erts_alcu_alloc_thr_pref(type, extra, size); - ptr = (void *) (((char *) p) - sizeof(Uint)); + ptr = (void *) (((char *) p) - sizeof(UWord)); used_allctr = *((Allctr_t **) ptr); ix = erts_alc_get_thr_ix(); @@ -2995,32 +2996,32 @@ erts_alcu_realloc_thr_pref(ErtsAlcType_t type, void *extra, void *p, Uint size) res = do_erts_alcu_realloc(type, used_allctr, ptr, - size + sizeof(Uint), + size + sizeof(UWord), (pref_allctr != used_allctr ? ERTS_ALCU_FLG_FAIL_REALLOC_MOVE : 0)); erts_mtx_unlock(&used_allctr->mutex); if (res) { ASSERT(used_allctr == *((Allctr_t **) res)); - res = (void *) (((char *) res) + sizeof(Uint)); + res = (void *) (((char *) res) + sizeof(UWord)); DEBUG_CHECK_ALIGNMENT(res); } else { erts_mtx_lock(&pref_allctr->mutex); - res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(Uint)); + res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(UWord)); erts_mtx_unlock(&pref_allctr->mutex); if (res) { Block_t *blk; size_t cpy_size; *((Allctr_t **) res) = pref_allctr; - res = (void *) (((char *) res) + sizeof(Uint)); + res = (void *) (((char *) res) + sizeof(UWord)); DEBUG_CHECK_ALIGNMENT(res); erts_mtx_lock(&used_allctr->mutex); blk = UMEM2BLK(ptr); - cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(Uint); + cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(UWord); if (cpy_size > size) cpy_size = size; sys_memcpy(res, p, cpy_size); @@ -3045,7 +3046,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra, if (!p) return erts_alcu_alloc_thr_pref(type, extra, size); - ptr = (void *) (((char *) p) - sizeof(Uint)); + ptr = (void *) (((char *) p) - sizeof(UWord)); used_allctr = *((Allctr_t **) ptr); ix = erts_alc_get_thr_ix(); @@ -3056,7 +3057,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra, ASSERT(used_allctr && pref_allctr); erts_mtx_lock(&pref_allctr->mutex); - res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(Uint)); + res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(UWord)); if (!res) { erts_mtx_unlock(&pref_allctr->mutex); res = erts_alcu_realloc_thr_pref(type, extra, p, size); @@ -3067,7 +3068,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra, Allctr_t *allctr; *((Allctr_t **) res) = pref_allctr; - res = (void *) (((char *) res) + sizeof(Uint)); + res = (void *) (((char *) res) + sizeof(UWord)); DEBUG_CHECK_ALIGNMENT(res); @@ -3080,7 +3081,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra, } blk = UMEM2BLK(ptr); - cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(Uint); + cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(UWord); if (cpy_size > size) cpy_size = size; sys_memcpy(res, p, cpy_size); @@ -3157,11 +3158,11 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) if (allctr->min_block_size < ABLK_HDR_SZ) goto error; allctr->min_block_size = UNIT_CEILING(allctr->min_block_size - + sizeof(Uint)); + + sizeof(UWord)); #if HAVE_ERTS_MSEG - if (allctr->mseg_opt.abs_shrink_th > ~((Uint) 0) / 100) - allctr->mseg_opt.abs_shrink_th = ~((Uint) 0) / 100; + if (allctr->mseg_opt.abs_shrink_th > ~((UWord) 0) / 100) + allctr->mseg_opt.abs_shrink_th = ~((UWord) 0) / 100; #endif #ifdef USE_THREADS @@ -3201,15 +3202,15 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) allctr->mbc_header_size = (UNIT_CEILING(allctr->mbc_header_size + FBLK_FTR_SZ + ABLK_HDR_SZ - + sizeof(Uint)) + + sizeof(UWord)) - ABLK_HDR_SZ - - sizeof(Uint)); + - sizeof(UWord)); allctr->sbc_header_size = (UNIT_CEILING(sizeof(Carrier_t) + FBLK_FTR_SZ + ABLK_HDR_SZ - + sizeof(Uint)) + + sizeof(UWord)) - ABLK_HDR_SZ - - sizeof(Uint)); + - sizeof(UWord)); } else #endif @@ -3437,7 +3438,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk) is_free_blk = (int) IS_FREE_BLK(blk); if(is_free_blk) { if (IS_NOT_LAST_BLK(blk)) - ASSERT(*((Uint *) (((char *) blk)+blk_sz-sizeof(Uint))) + ASSERT(*((UWord *) (((char *) blk)+blk_sz-sizeof(UWord))) == blk_sz); } @@ -3445,7 +3446,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk) (*allctr->check_block)(allctr, blk, (int) is_free_blk); if (IS_LAST_BLK(blk)) { - carrier_end = ((char *) NXT_BLK(blk)) + sizeof(Uint); + carrier_end = ((char *) NXT_BLK(blk)) + sizeof(UWord); mbc = *((Carrier_t **) NXT_BLK(blk)); prev_blk = NULL; blk = MBC2FBLK(allctr, mbc); @@ -3461,7 +3462,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk) ASSERT((((char *) mbc) + allctr->mbc_header_size + tot_blk_sz - + sizeof(Uint)) == carrier_end); + + sizeof(UWord)) == carrier_end); ASSERT(((char *) mbc) + CARRIER_SZ(mbc) == carrier_end); if (allctr->check_mbc) diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index 10b11661e6..e805883ddc 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -27,8 +27,8 @@ typedef struct Allctr_t_ Allctr_t; typedef struct { - Uint ycs; - Uint mmc; + UWord ycs; + UWord mmc; } AlcUInit_t; typedef struct { @@ -38,22 +38,22 @@ typedef struct { int tspec; int tpref; int ramv; - Uint sbct; - Uint asbcst; - Uint rsbcst; - Uint rsbcmt; - Uint rmbcmt; - Uint mmbcs; - Uint mmsbc; - Uint mmmbc; - Uint lmbcs; - Uint smbcs; - Uint mbcgs; + UWord sbct; + UWord asbcst; + UWord rsbcst; + UWord rsbcmt; + UWord rmbcmt; + UWord mmbcs; + UWord mmsbc; + UWord mmmbc; + UWord lmbcs; + UWord smbcs; + UWord mbcgs; } AllctrInit_t; typedef struct { - Uint blocks; - Uint carriers; + UWord blocks; + UWord carriers; } AllctrSize_t; #ifndef SMALL_MEMORY @@ -150,7 +150,7 @@ void erts_alcu_current_size(Allctr_t *, AllctrSize_t *); #undef ERTS_ALLOC_UTIL_HARD_DEBUG #ifdef DEBUG -# if 0 +# if 1 # define ERTS_ALLOC_UTIL_HARD_DEBUG # endif #endif @@ -163,19 +163,19 @@ void erts_alcu_current_size(Allctr_t *, AllctrSize_t *); #define CEILING(X, I) ((((X) - 1)/(I) + 1)*(I)) #undef WORD_MASK -#define INV_WORD_MASK ((Uint) (sizeof(Uint) - 1)) +#define INV_WORD_MASK ((UWord) (sizeof(UWord) - 1)) #define WORD_MASK (~INV_WORD_MASK) #define WORD_FLOOR(X) ((X) & WORD_MASK) #define WORD_CEILING(X) WORD_FLOOR((X) + INV_WORD_MASK) #undef UNIT_MASK -#define INV_UNIT_MASK ((Uint) (sizeof(Unit_t) - 1)) +#define INV_UNIT_MASK ((UWord) (sizeof(Unit_t) - 1)) #define UNIT_MASK (~INV_UNIT_MASK) #define UNIT_FLOOR(X) ((X) & UNIT_MASK) #define UNIT_CEILING(X) UNIT_FLOOR((X) + INV_UNIT_MASK) -#define SZ_MASK (~((Uint) 0) << 3) +#define SZ_MASK (~((UWord) 0) << 3) #define FLG_MASK (~(SZ_MASK)) @@ -189,7 +189,7 @@ typedef union {char c[8]; long l; double d;} Unit_t; typedef struct Carrier_t_ Carrier_t; struct Carrier_t_ { - Uint chdr; + UWord chdr; Carrier_t *next; Carrier_t *prev; }; @@ -199,17 +199,17 @@ typedef struct { Carrier_t *last; } CarrierList_t; -typedef Uint Block_t; -typedef Uint FreeBlkFtr_t; +typedef UWord Block_t; +typedef UWord FreeBlkFtr_t; typedef struct { - Uint giga_no; - Uint no; + UWord giga_no; + UWord no; } CallCounter_t; typedef struct { - Uint no; - Uint size; + UWord no; + UWord size; } StatValues_t; typedef struct { diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c index b090564649..ef9644c3d1 100644 --- a/erts/emulator/beam/erl_async.c +++ b/erts/emulator/beam/erl_async.c @@ -390,7 +390,7 @@ int check_async_ready(void) ** async_data data to pass to invoke function ** async_free function for relase async_data in case of failure */ -long driver_async(ErlDrvPort ix, unsigned int* key, +long driver_async(ErlDrvPort ix, unsigned long* key, void (*async_invoke)(void*), void* async_data, void (*async_free)(void*)) { diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c index 445ba00ca7..e76b0b9252 100644 --- a/erts/emulator/beam/erl_bif_chksum.c +++ b/erts/emulator/beam/erl_bif_chksum.c @@ -49,9 +49,9 @@ void erts_init_bif_chksum(void) chksum_md5_2_exp.code[1] = am_atom_put("md5_trap",8); chksum_md5_2_exp.code[2] = 2; chksum_md5_2_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; chksum_md5_2_exp.code[4] = - (Eterm) &md5_2; + (UWord) &md5_2; } diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 8d3618393a..40f8b7f23a 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -127,7 +127,7 @@ bld_bin_list(Uint **hpp, Uint *szp, ProcBin* pb) Eterm tuple; for (; pb; pb = pb->next) { - Eterm val = erts_bld_uint(hpp, szp, (Uint) pb->val); + Eterm val = erts_bld_uword(hpp, szp, (UWord) pb->val); Eterm orig_size = erts_bld_uint(hpp, szp, pb->val->orig_size); if (szp) @@ -1010,7 +1010,7 @@ process_info_aux(Process *BIF_P, hp = HAlloc(BIF_P, 3); res = am_undefined; } else { - Eterm* current; + UWord* current; if (rp->current[0] == am_erlang && rp->current[1] == am_process_info && @@ -2829,7 +2829,7 @@ fun_info_2(Process* p, Eterm fun, Eterm what) goto error; } } else if (is_export(fun)) { - Export* exp = (Export *) (export_val(fun))[1]; + Export* exp = (Export *) ((UWord) (export_val(fun))[1]); switch (what) { case am_type: hp = HAlloc(p, 3); @@ -3022,11 +3022,11 @@ BIF_RETTYPE statistics_1(BIF_ALIST_1) res = erts_run_queues_len(NULL); BIF_RET(make_small(res)); } else if (BIF_ARG_1 == am_wall_clock) { - Uint w1, w2; + UWord w1, w2; Eterm b1, b2; wall_clock_elapsed_time_both(&w1, &w2); - b1 = erts_make_integer(w1,BIF_P); - b2 = erts_make_integer(w2,BIF_P); + b1 = erts_make_integer((Uint) w1,BIF_P); + b2 = erts_make_integer((Uint) w2,BIF_P); hp = HAlloc(BIF_P,3); res = TUPLE2(hp, b1, b2); BIF_RET(res); diff --git a/erts/emulator/beam/erl_bif_op.c b/erts/emulator/beam/erl_bif_op.c index 6da72dcef9..372b858832 100644 --- a/erts/emulator/beam/erl_bif_op.c +++ b/erts/emulator/beam/erl_bif_op.c @@ -251,7 +251,7 @@ BIF_RETTYPE is_function_2(BIF_ALIST_2) BIF_RET(am_true); } } else if (is_export(BIF_ARG_1)) { - Export* exp = (Export *) (export_val(BIF_ARG_1))[1]; + Export* exp = (Export *) EXPAND_POINTER((export_val(BIF_ARG_1))[1]); if (exp->code[2] == (Uint) arity) { BIF_RET(am_true); diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c index c027cd5984..4b527ce215 100644 --- a/erts/emulator/beam/erl_bif_re.c +++ b/erts/emulator/beam/erl_bif_re.c @@ -76,8 +76,8 @@ void erts_init_bif_re(void) re_exec_trap_export.code[0] = am_erlang; re_exec_trap_export.code[1] = am_re_run_trap; re_exec_trap_export.code[2] = 3; - re_exec_trap_export.code[3] = (Eterm) em_apply_bif; - re_exec_trap_export.code[4] = (Eterm) &re_exec_trap; + re_exec_trap_export.code[3] = (UWord) em_apply_bif; + re_exec_trap_export.code[4] = (UWord) &re_exec_trap; grun_trap_exportp = erts_export_put(am_re,am_grun,3); urun_trap_exportp = erts_export_put(am_re,am_urun,3); @@ -103,7 +103,7 @@ Sint erts_re_set_loop_limit(Sint limit) static int term_to_int(Eterm term, int *sp) { -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP if (is_small(term)) { Uint x = signed_val(term); @@ -154,7 +154,7 @@ static int term_to_int(Eterm term, int *sp) static Eterm make_signed_integer(int x, Process *p) { -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP return make_small(x); #else Eterm* hp; diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c index 1740569b69..23f4879d45 100644 --- a/erts/emulator/beam/erl_bif_timer.c +++ b/erts/emulator/beam/erl_bif_timer.c @@ -155,7 +155,7 @@ create_ref(Uint *hp, Uint32 *ref_numbers, Uint32 len) erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__); } -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP hp[0] = make_ref_thing_header(len/2 + 1); datap = (Uint32 *) &hp[1]; *(datap++) = len; @@ -173,7 +173,7 @@ create_ref(Uint *hp, Uint32 *ref_numbers, Uint32 len) static int eq_non_standard_ref_numbers(Uint32 *rn1, Uint32 len1, Uint32 *rn2, Uint32 len2) { -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP #define MAX_REF_HEAP_SZ (1+(ERTS_MAX_REF_NUMBERS/2+1)) #else #define MAX_REF_HEAP_SZ (1+ERTS_MAX_REF_NUMBERS) @@ -398,7 +398,7 @@ setup_bif_timer(Uint32 xflags, if (!term_to_Uint(time, &timeout)) return THE_NON_VALUE; -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP if ((timeout >> 32) != 0) return THE_NON_VALUE; #endif diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 6623eea4f3..c46a0074fc 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -962,12 +962,12 @@ static int function_is_traced(Eterm mfa[3], e.code[2] = mfa[2]; if ((ep = export_get(&e)) != NULL) { if (ep->address == ep->code+3 && - ep->code[3] != (Uint) em_call_error_handler) { - if (ep->code[3] == (Uint) em_call_traced_function) { + ep->code[3] != (UWord) em_call_error_handler) { + if (ep->code[3] == (UWord) em_call_traced_function) { *ms = ep->match_prog_set; return FUNC_TRACE_GLOBAL_TRACE; } - if (ep->code[3] == (Uint) em_apply_bif) { + if (ep->code[3] == (UWord) em_apply_bif) { for (i = 0; i < BIF_SIZE; ++i) { if (bif_export[i] == ep) { int r = 0; @@ -1439,9 +1439,9 @@ static int setup_func_trace(Export* ep, void* match_prog) { if (ep->address == ep->code+3) { - if (ep->code[3] == (Uint) em_call_error_handler) { + if (ep->code[3] == (UWord) em_call_error_handler) { return 0; - } else if (ep->code[3] == (Uint) em_call_traced_function) { + } else if (ep->code[3] == (UWord) em_call_traced_function) { MatchSetUnref(ep->match_prog_set); ep->match_prog_set = match_prog; MatchSetRef(ep->match_prog_set); @@ -1461,8 +1461,8 @@ setup_func_trace(Export* ep, void* match_prog) return 0; } - ep->code[3] = (Uint) em_call_traced_function; - ep->code[4] = (Uint) ep->address; + ep->code[3] = (UWord) em_call_traced_function; + ep->code[4] = (UWord) ep->address; ep->address = ep->code+3; ep->match_prog_set = match_prog; MatchSetRef(ep->match_prog_set); @@ -1474,7 +1474,7 @@ static void setup_bif_trace(int bif_index) { ASSERT(ExportIsBuiltIn(ep)); ASSERT(ep->code[4]); - ep->code[4] = (Uint) bif_table[bif_index].traced; + ep->code[4] = (UWord) bif_table[bif_index].traced; } static void set_trace_bif(int bif_index, void* match_prog) { @@ -1501,9 +1501,9 @@ static int reset_func_trace(Export* ep) { if (ep->address == ep->code+3) { - if (ep->code[3] == (Uint) em_call_error_handler) { + if (ep->code[3] == (UWord) em_call_error_handler) { return 0; - } else if (ep->code[3] == (Uint) em_call_traced_function) { + } else if (ep->code[3] == (UWord) em_call_traced_function) { ep->address = (Uint *) ep->code[4]; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; @@ -1536,8 +1536,8 @@ static void reset_bif_trace(int bif_index) { ASSERT(ExportIsBuiltIn(ep)); ASSERT(ep->code[4]); ASSERT(! ep->match_prog_set); - ASSERT(! erts_is_mtrace_bif((Uint *)ep->code+3, NULL, NULL)); - ep->code[4] = (Uint) bif_table[bif_index].f; + ASSERT(! erts_is_mtrace_bif((UWord *)ep->code+3, NULL, NULL)); + ep->code[4] = (UWord) bif_table[bif_index].f; } static void clear_trace_bif(int bif_index) { diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h index 1f948a9684..5b0b3bcec2 100644 --- a/erts/emulator/beam/erl_binary.h +++ b/erts/emulator/beam/erl_binary.h @@ -164,7 +164,7 @@ byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, unsigned extra); #endif #define ERTS_CHK_BIN_ALIGNMENT(B) \ - do { ASSERT(!(B) || (((Uint) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((Uint) 0)) } while(0) + do { ASSERT(!(B) || (((UWord) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((UWord) 0)) } while(0) ERTS_GLB_INLINE byte* erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr); ERTS_GLB_INLINE void erts_free_aligned_binary_bytes(byte* buf); diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index e4f5d50ddf..3f69ddcdb6 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -255,7 +255,7 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff * Simply shift whole bytes into the result. */ switch (BYTE_OFFSET(n)) { -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP case 7: w = (w << 8) | *bp++; case 6: w = (w << 8) | *bp++; case 5: w = (w << 8) | *bp++; @@ -360,7 +360,7 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff case 3: v32 = LSB[0] + (LSB[1]<<8) + (LSB[2]<<16); goto big_small; -#if !defined(ARCH_64) +#if !defined(ARCH_64) || HALFWORD_HEAP case 4: v32 = (LSB[0] + (LSB[1]<<8) + (LSB[2]<<16) + (LSB[3]<<24)); if (!IS_USMALL(sgn, v32)) { diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 08c448882f..959f7fa37c 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -87,7 +87,7 @@ static union { static struct { union { DbTable *tb; /* Only directly readable if slot is ALIVE */ - Uint next_free; /* (index<<2)|1 if slot is FREE */ + UWord next_free; /* (index<<2)|1 if slot is FREE */ }u; } *meta_main_tab; @@ -187,7 +187,7 @@ static Eterm ms_delete_all_buff[8]; /* To compare with for deletion static void fix_table_locked(Process* p, DbTable* tb); static void unfix_table_locked(Process* p, DbTable* tb, db_lock_kind_t* kind); -static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data); +static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data); static void free_heir_data(DbTable*); static void free_fixations_locked(DbTable *tb); @@ -1186,7 +1186,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) Eterm val; Eterm ret; Eterm heir; - Eterm heir_data; + UWord heir_data; Uint32 status; Sint keypos; int is_named, is_fine_locked; @@ -1206,7 +1206,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) is_named = 0; is_fine_locked = 0; heir = am_none; - heir_data = am_undefined; + heir_data = (UWord) am_undefined; list = BIF_ARG_2; while(is_list(list)) { @@ -1566,9 +1566,15 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) * (it looks like an continuation pointer), but that is will crash the * emulator if this BIF is call traced. */ +#if HALFWORD_HEAP + Eterm *hp = HAlloc(BIF_P, 3); + hp[0] = make_pos_bignum_header(2); + *((UWord *) (UWord) (hp+1)) = (UWord) tb; +#else Eterm *hp = HAlloc(BIF_P, 2); hp[0] = make_pos_bignum_header(1); hp[1] = (Eterm) tb; +#endif BIF_TRAP1(&ets_delete_continue_exp, BIF_P, make_big(hp)); } else { @@ -1638,7 +1644,7 @@ BIF_RETTYPE ets_setopts_2(BIF_ALIST_2) Eterm* tp; Eterm opt; Eterm heir = THE_NON_VALUE; - Eterm heir_data = THE_NON_VALUE; + UWord heir_data = (UWord) THE_NON_VALUE; Uint32 protection = 0; DeclareTmpHeap(fakelist,2,BIF_P); Eterm tail; @@ -2618,7 +2624,7 @@ void init_db(void) { DbTable init_tb; int i; - extern Eterm* em_apply_bif; + extern UWord* em_apply_bif; Eterm *hp; unsigned bits; size_t size; @@ -2747,9 +2753,9 @@ void init_db(void) ets_select_delete_continue_exp.code[1] = am_atom_put("delete_trap",11); ets_select_delete_continue_exp.code[2] = 1; ets_select_delete_continue_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; ets_select_delete_continue_exp.code[4] = - (Eterm) &ets_select_delete_1; + (UWord) &ets_select_delete_1; /* Non visual BIF to trap to. */ memset(&ets_select_count_continue_exp, 0, sizeof(Export)); @@ -2759,9 +2765,9 @@ void init_db(void) ets_select_count_continue_exp.code[1] = am_atom_put("count_trap",11); ets_select_count_continue_exp.code[2] = 1; ets_select_count_continue_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; ets_select_count_continue_exp.code[4] = - (Eterm) &ets_select_count_1; + (UWord) &ets_select_count_1; /* Non visual BIF to trap to. */ memset(&ets_select_continue_exp, 0, sizeof(Export)); @@ -2771,9 +2777,9 @@ void init_db(void) ets_select_continue_exp.code[1] = am_atom_put("select_trap",11); ets_select_continue_exp.code[2] = 1; ets_select_continue_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; ets_select_continue_exp.code[4] = - (Eterm) &ets_select_trap_1; + (UWord) &ets_select_trap_1; /* Non visual BIF to trap to. */ memset(&ets_delete_continue_exp, 0, sizeof(Export)); @@ -2781,8 +2787,8 @@ void init_db(void) ets_delete_continue_exp.code[0] = am_ets; ets_delete_continue_exp.code[1] = am_atom_put("delete_trap",11); ets_delete_continue_exp.code[2] = 1; - ets_delete_continue_exp.code[3] = (Eterm) em_apply_bif; - ets_delete_continue_exp.code[4] = (Eterm) &ets_delete_trap; + ets_delete_continue_exp.code[3] = (UWord) em_apply_bif; + ets_delete_continue_exp.code[4] = (UWord) &ets_delete_trap; hp = ms_delete_all_buff; ms_delete_all = CONS(hp, am_true, NIL); @@ -2878,7 +2884,7 @@ static int give_away_to_heir(Process* p, DbTable* tb) ErtsProcLocks to_locks = ERTS_PROC_LOCK_MAIN; DeclareTmpHeap(buf,5,p); Eterm to_pid; - Eterm heir_data; + UWord heir_data; ASSERT(tb->common.owner == p->id); ASSERT(is_internal_pid(tb->common.heir)); @@ -3301,7 +3307,7 @@ static void free_fixations_locked(DbTable *tb) tb->common.fixations = NULL; } -static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data) +static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data) { tb->common.heir = heir; if (heir == am_none) { @@ -3326,7 +3332,7 @@ static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data) UseTmpHeap(2,me); /* Make a dummy 1-tuple around data to use db_get_term() */ - heir_data = (Eterm) db_get_term(&tb->common, NULL, 0, + heir_data = (UWord) db_get_term(&tb->common, NULL, 0, TUPLE1(tmp,heir_data)); UnUseTmpHeap(2,me); ASSERT(!is_immed(heir_data)); @@ -3351,7 +3357,7 @@ static BIF_RETTYPE ets_delete_trap(Process *p, Eterm cont) { int trap; Eterm* ptr = big_val(cont); - DbTable *tb = (DbTable *) ptr[1]; + DbTable *tb = *((DbTable **) (UWord) (ptr + 1)); ASSERT(*ptr == make_pos_bignum_header(1)); diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index b421da591b..71c594854b 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -443,9 +443,9 @@ void db_initialize_tree(void) ets_select_reverse_exp.code[1] = am_reverse; ets_select_reverse_exp.code[2] = 3; ets_select_reverse_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; ets_select_reverse_exp.code[4] = - (Eterm) &ets_select_reverse; + (UWord) &ets_select_reverse; return; }; diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index de12b9bdbf..c565e1ee89 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -281,7 +281,7 @@ typedef struct dmc_guard_bif { */ DMC_DECLARE_STACK_TYPE(Eterm); -DMC_DECLARE_STACK_TYPE(Uint); +DMC_DECLARE_STACK_TYPE(UWord); DMC_DECLARE_STACK_TYPE(unsigned); @@ -382,7 +382,7 @@ cleanup_match_pseudo_process(ErtsMatchPseudoProcess *mpsp, int keep_heap) else { int i; for (i = 0; i < ERTS_DEFAULT_MS_HEAP_SIZE; i++) { -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP mpsp->default_heap[i] = (Eterm) 0xdeadbeefdeadbeef; #else mpsp->default_heap[i] = (Eterm) 0xdeadbeef; @@ -830,42 +830,42 @@ static Uint my_size_object(Eterm t); static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap); /* Guard compilation */ -static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(Uint) *text, +static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(UWord) *text, Eterm t); static DMCRet dmc_list(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant); static DMCRet dmc_tuple(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant); static DMCRet dmc_variable(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant); static DMCRet dmc_fun(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant); static DMCRet dmc_expr(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant); static DMCRet compile_guard_expr(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t); /* match expression subroutine */ static DMCRet dmc_one_term(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(Eterm) *stack, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm c); @@ -1185,7 +1185,7 @@ Eterm erts_match_set_run(Process *p, Binary *mpsp, Eterm ret; ret = db_prog_match(p, mpsp, - (Eterm) args, + (Eterm) COMPRESS_POINTER(args), num_args, return_flags); #if defined(HARDDEBUG) if (is_non_value(ret)) { @@ -1245,7 +1245,7 @@ Binary *db_match_compile(Eterm *matchexpr, { DMCHeap heap; DMC_STACK_TYPE(Eterm) stack; - DMC_STACK_TYPE(Uint) text; + DMC_STACK_TYPE(UWord) text; DMCContext context; MatchProg *ret = NULL; Eterm t; @@ -1491,8 +1491,8 @@ restart: ** A special case is when the match expression is a single binding ** (i.e '$1'), then the field single_variable is set to 1. */ - bp = erts_create_magic_binary(((sizeof(MatchProg) - sizeof(Uint)) + - (DMC_STACK_NUM(text) * sizeof(Uint))), + bp = erts_create_magic_binary(((sizeof(MatchProg) - sizeof(UWord)) + + (DMC_STACK_NUM(text) * sizeof(UWord))), erts_db_match_prog_destructor); ret = Binary2MatchProg(bp); ret->saved_program_buf = NULL; @@ -1501,7 +1501,7 @@ restart: ret->num_bindings = heap.used; ret->single_variable = context.special; sys_memcpy(ret->text, DMC_STACK_DATA(text), - DMC_STACK_NUM(text) * sizeof(Uint)); + DMC_STACK_NUM(text) * sizeof(UWord)); ret->heap_size = ((heap.used * sizeof(Eterm)) + (max_eheap_need * sizeof(Eterm)) + (context.stack_need * sizeof(Eterm *)) + @@ -1601,7 +1601,8 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term, Eterm **sp; Eterm *esp; Eterm *hp; - Uint *pc = prog->text; + UWord *cp; + UWord *pc = prog->text; Eterm *ehp; Eterm ret; Uint n = 0; /* To avoid warning. */ @@ -1616,9 +1617,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term, int fail_label; int atomic_trace; #ifdef DMC_DEBUG - unsigned long *heap_fence; - unsigned long *eheap_fence; - unsigned long *stack_fence; + Uint *heap_fence; + Uint *eheap_fence; + Uint *stack_fence; Uint save_op; #endif /* DMC_DEBUG */ @@ -1654,9 +1655,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term, #ifdef DMC_DEBUG save_op = 0; - heap_fence = (unsigned long *) mpsp->heap + prog->eheap_offset - 1; - eheap_fence = (unsigned long *) mpsp->heap + prog->stack_offset - 1; - stack_fence = (unsigned long *) mpsp->heap + prog->heap_size - 1; + heap_fence = (Uint *) mpsp->heap + prog->eheap_offset - 1; + eheap_fence = (Uint *) mpsp->heap + prog->stack_offset - 1; + stack_fence = (Uint *) mpsp->heap + prog->heap_size - 1; *heap_fence = FENCE_PATTERN; *eheap_fence = FENCE_PATTERN; *stack_fence = FENCE_PATTERN; @@ -1709,11 +1710,12 @@ restart: n = *pc++; if ((int) n != arity) FAIL(); - ep = (Eterm *) *ep; + ep = (Eterm *) EXPAND_POINTER(*ep); break; - case matchArrayBind: /* When the array size is unknown. */ + case matchArrayBind: /* When the array size is unknown. */ /* XXX:PaN - where does + this array come from? */ n = *pc++; - hp[n] = dpm_array_to_list(psp, (Eterm *) term, arity); + hp[n] = dpm_array_to_list(psp, (Eterm *) EXPAND_POINTER(term), arity); break; case matchTuple: /* *ep is a tuple of arity n */ if (!is_tuple(*ep)) @@ -1884,7 +1886,7 @@ restart: break; case matchPushArrayAsList: n = arity; /* Only happens when 'term' is an array */ - tp = (Eterm *) term; + tp = (Eterm *) EXPAND_POINTER(term); *esp++ = make_list(ehp); while (n--) { *ehp++ = *tp++; @@ -1897,7 +1899,7 @@ restart: break; case matchPushArrayAsListU: /* This instruction is NOT efficient. */ - *esp++ = dpm_array_to_list(psp, (Eterm *) term, arity); + *esp++ = dpm_array_to_list(psp, (Eterm *) EXPAND_POINTER(term), arity); break; case matchTrue: if (*--esp != am_true) @@ -2095,14 +2097,14 @@ restart: } break; case matchCaller: - if (!(c_p->cp) || !(hp = find_function_from_pc(c_p->cp))) { + if (!(c_p->cp) || !(cp = find_function_from_pc(c_p->cp))) { *esp++ = am_undefined; } else { *esp++ = make_tuple(ehp); ehp[0] = make_arityval(3); - ehp[1] = hp[0]; - ehp[2] = hp[1]; - ehp[3] = make_small(hp[2]); + ehp[1] = cp[0]; + ehp[2] = cp[1]; + ehp[3] = make_small((Uint) hp[2]); ehp += 4; } break; @@ -2609,7 +2611,7 @@ static void add_dmc_err(DMCErrInfo *err_info, static DMCRet dmc_one_term(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(Eterm) *stack, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm c) { Sint n; @@ -2756,7 +2758,7 @@ static DMCRet dmc_one_term(DMCContext *context, ** Match guard compilation */ -static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(Uint) *text, +static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(UWord) *text, Eterm t) { int sz; @@ -2810,7 +2812,7 @@ add_dmc_err((ContextP)->err_info, String, -1, T, dmcWarning) static DMCRet dmc_list(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -2846,11 +2848,11 @@ static DMCRet dmc_list(DMCContext *context, static DMCRet dmc_tuple(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { - DMC_STACK_TYPE(Uint) instr_save; + DMC_STACK_TYPE(UWord) instr_save; int all_constant = 1; int textpos = DMC_STACK_NUM(*text); Eterm *p = tuple_val(t); @@ -2906,7 +2908,7 @@ static DMCRet dmc_tuple(DMCContext *context, static DMCRet dmc_whole_expression(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -2934,7 +2936,7 @@ static DMCRet dmc_whole_expression(DMCContext *context, static DMCRet dmc_variable(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -2955,7 +2957,7 @@ static DMCRet dmc_variable(DMCContext *context, static DMCRet dmc_all_bindings(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -2982,7 +2984,7 @@ static DMCRet dmc_all_bindings(DMCContext *context, static DMCRet dmc_const(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -2999,7 +3001,7 @@ static DMCRet dmc_const(DMCContext *context, static DMCRet dmc_and(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3028,7 +3030,7 @@ static DMCRet dmc_and(DMCContext *context, static DMCRet dmc_or(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3058,7 +3060,7 @@ static DMCRet dmc_or(DMCContext *context, static DMCRet dmc_andalso(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3107,7 +3109,7 @@ static DMCRet dmc_andalso(DMCContext *context, static DMCRet dmc_orelse(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3155,7 +3157,7 @@ static DMCRet dmc_orelse(DMCContext *context, static DMCRet dmc_message(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3197,7 +3199,7 @@ static DMCRet dmc_message(DMCContext *context, static DMCRet dmc_self(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3217,7 +3219,7 @@ static DMCRet dmc_self(DMCContext *context, static DMCRet dmc_return_trace(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3247,7 +3249,7 @@ static DMCRet dmc_return_trace(DMCContext *context, static DMCRet dmc_exception_trace(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3279,7 +3281,7 @@ static DMCRet dmc_exception_trace(DMCContext *context, static DMCRet dmc_is_seq_trace(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3305,7 +3307,7 @@ static DMCRet dmc_is_seq_trace(DMCContext *context, static DMCRet dmc_set_seq_token(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3354,7 +3356,7 @@ static DMCRet dmc_set_seq_token(DMCContext *context, static DMCRet dmc_get_seq_token(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3391,7 +3393,7 @@ static DMCRet dmc_get_seq_token(DMCContext *context, static DMCRet dmc_display(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3431,7 +3433,7 @@ static DMCRet dmc_display(DMCContext *context, static DMCRet dmc_process_dump(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3461,7 +3463,7 @@ static DMCRet dmc_process_dump(DMCContext *context, static DMCRet dmc_enable_trace(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3521,7 +3523,7 @@ static DMCRet dmc_enable_trace(DMCContext *context, static DMCRet dmc_disable_trace(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3581,7 +3583,7 @@ static DMCRet dmc_disable_trace(DMCContext *context, static DMCRet dmc_trace(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3655,7 +3657,7 @@ static DMCRet dmc_trace(DMCContext *context, static DMCRet dmc_caller(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3688,7 +3690,7 @@ static DMCRet dmc_caller(DMCContext *context, static DMCRet dmc_silent(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3730,7 +3732,7 @@ static DMCRet dmc_silent(DMCContext *context, static DMCRet dmc_fun(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3847,7 +3849,7 @@ static DMCRet dmc_fun(DMCContext *context, erl_exit(1,"ets:match() internal error, " "guard with more than 3 arguments."); } - DMC_PUSH(*text, (Uint) b->biff); + DMC_PUSH(*text, (UWord) b->biff); context->stack_used -= (((int) a) - 2); if (context->stack_used > context->stack_need) context->stack_need = context->stack_used; @@ -3856,7 +3858,7 @@ static DMCRet dmc_fun(DMCContext *context, static DMCRet dmc_expr(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm t, int *constant) { @@ -3919,7 +3921,7 @@ static DMCRet dmc_expr(DMCContext *context, static DMCRet compile_guard_expr(DMCContext *context, DMCHeap *heap, - DMC_STACK_TYPE(Uint) *text, + DMC_STACK_TYPE(UWord) *text, Eterm l) { DMCRet ret; @@ -4233,7 +4235,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) Eterm l; Uint32 ret_flags; Uint sz; - Eterm *save_cp; + UWord *save_cp; if (trace && !(is_list(against) || against == NIL)) { return THE_NON_VALUE; @@ -4276,7 +4278,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) } } else { n = 0; - arr = (Eterm *) against; + arr = (Eterm *) EXPAND_POINTER(against); } /* We are in the context of a BIF, @@ -4327,7 +4329,7 @@ static Eterm seq_trace_fake(Process *p, Eterm arg1) static void db_match_dis(Binary *bp) { MatchProg *prog = Binary2MatchProg(bp); - Uint *t = prog->text; + UWord *t = prog->text; Uint n; Eterm p; int first; @@ -4402,7 +4404,7 @@ static void db_match_dis(Binary *bp) first = 0; else erts_printf(", "); -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP erts_printf("0x%016bpx", *t); #else erts_printf("0x%08bpx", *t); @@ -4422,7 +4424,7 @@ static void db_match_dis(Binary *bp) first = 0; else erts_printf(", "); -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP erts_printf("0x%016bpx", *t); #else erts_printf("0x%08bpx", *t); diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 4fc7b4f52e..fbc25aaf2b 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -212,7 +212,7 @@ typedef struct db_table_common { #endif Eterm owner; /* Pid of the creator */ Eterm heir; /* Pid of the heir */ - Eterm heir_data; /* To send in ETS-TRANSFER (is_immed or (DbTerm*) */ + UWord heir_data; /* To send in ETS-TRANSFER (is_immed or (DbTerm*) */ SysTimeval heir_started; /* To further identify the heir */ Eterm the_name; /* an atom */ Eterm id; /* atom | integer */ @@ -304,9 +304,9 @@ typedef struct match_prog { Uint eheap_offset; Uint stack_offset; #ifdef DMC_DEBUG - Uint* prog_end; /* End of program */ + UWord* prog_end; /* End of program */ #endif - Uint text[1]; /* Beginning of program */ + UWord text[1]; /* Beginning of program */ } MatchProg; /* diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c index 99b05fcf26..9c7a47da0a 100644 --- a/erts/emulator/beam/erl_debug.c +++ b/erts/emulator/beam/erl_debug.c @@ -235,9 +235,9 @@ pps(Process* p, Eterm* stop) } while(sp >= stop) { - erts_print(to, to_arg, "%0*lx: ", PTR_SIZE, (Eterm) sp); + erts_print(to, to_arg, "%0*lx: ", PTR_SIZE, (UWord) sp); if (is_catch(*sp)) { - erts_print(to, to_arg, "catch %d", (Uint)catch_pc(*sp)); + erts_print(to, to_arg, "catch %ld", (UWord)catch_pc(*sp)); } else { paranoid_display(to, to_arg, p, *sp); } diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index 489e74d960..316d0ef992 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -567,7 +567,7 @@ EXTERN int driver_send_term(ErlDrvPort ix, ErlDrvTermData to, /* Async IO functions */ EXTERN long driver_async(ErlDrvPort ix, - unsigned int* key, + unsigned long* key, void (*async_invoke)(void*), void* async_data, void (*async_free)(void*)); diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c index 79e844b315..e6884c1179 100644 --- a/erts/emulator/beam/erl_fun.c +++ b/erts/emulator/beam/erl_fun.c @@ -50,8 +50,8 @@ static void fun_free(ErlFunEntry* obj); * to unloaded_fun[]. The -1 in unloaded_fun[0] will be interpreted * as an illegal arity when attempting to call a fun. */ -static Eterm unloaded_fun_code[3] = {NIL, -1, 0}; -static Eterm* unloaded_fun = unloaded_fun_code + 2; +static UWord unloaded_fun_code[3] = {NIL, -1, 0}; +static UWord* unloaded_fun = unloaded_fun_code + 2; void erts_init_fun_table(void) @@ -207,7 +207,7 @@ erts_cleanup_funs(ErlFunThing* funp) #endif void -erts_cleanup_funs_on_purge(Eterm* start, Eterm* end) +erts_cleanup_funs_on_purge(UWord* start, UWord* end) { int limit; HashBucket** bucket; @@ -222,7 +222,7 @@ erts_cleanup_funs_on_purge(Eterm* start, Eterm* end) while (b) { ErlFunEntry* fe = (ErlFunEntry *) b; - Eterm* addr = fe->address; + UWord* addr = fe->address; if (start <= addr && addr < end) { fe->address = unloaded_fun; diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h index fb5e75649b..980cdd414a 100644 --- a/erts/emulator/beam/erl_fun.h +++ b/erts/emulator/beam/erl_fun.h @@ -33,10 +33,10 @@ typedef struct erl_fun_entry { int index; /* New style index. */ int old_uniq; /* Unique number (old_style) */ int old_index; /* Old style index */ - Eterm* address; /* Pointer to code for fun */ + UWord* address; /* Pointer to code for fun */ #ifdef HIPE - Eterm* native_address; /* Native entry code for fun. */ + UWord* native_address; /* Native entry code for fun. */ #endif Uint arity; /* The arity of the fun. */ @@ -58,7 +58,7 @@ typedef struct erl_fun_thing { #endif ErlFunEntry* fe; /* Pointer to fun entry. */ #ifdef HIPE - Eterm* native_address; /* Native code for the fun. */ + UWord* native_address; /* Native code for the fun. */ #endif Uint arity; /* The arity of the fun. */ Uint num_free; /* Number of free variables (in env). */ @@ -86,7 +86,7 @@ void erts_erase_fun_entry(ErlFunEntry* fe); #ifndef HYBRID /* FIND ME! */ void erts_cleanup_funs(ErlFunThing* funp); #endif -void erts_cleanup_funs_on_purge(Eterm* start, Eterm* end); +void erts_cleanup_funs_on_purge(UWord* start, UWord* end); void erts_dump_fun_entries(int, void *); #endif diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index e9bf37a173..9ed566e66e 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -126,7 +126,7 @@ static void disallow_heap_frag_ref_in_old_heap(Process* p); static void disallow_heap_frag_ref(Process* p, Eterm* n_htop, Eterm* objv, int nobj); #endif -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP # define MAX_HEAP_SIZES 154 #else # define MAX_HEAP_SIZES 55 @@ -1551,7 +1551,7 @@ disallow_heap_frag_ref_in_old_heap(Process* p) val = *hp++; switch (primary_tag(val)) { case TAG_PRIMARY_BOXED: - ptr = (Eterm *) val; + ptr = (Eterm *) EXPAND_POINTER(val); if (!in_area(ptr, old_heap, old_heap_size)) { if (in_area(ptr, new_heap, new_heap_size)) { abort(); @@ -1564,7 +1564,7 @@ disallow_heap_frag_ref_in_old_heap(Process* p) } break; case TAG_PRIMARY_LIST: - ptr = (Eterm *) val; + ptr = (Eterm *) EXPAND_POINTER(val); if (!in_area(ptr, old_heap, old_heap_size)) { if (in_area(ptr, new_heap, new_heap_size)) { abort(); diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c index ea2ba4d55c..33d93d344d 100644 --- a/erts/emulator/beam/erl_goodfit_alloc.c +++ b/erts/emulator/beam/erl_goodfit_alloc.c @@ -49,30 +49,30 @@ #define MIN_MBC_FIRST_FREE_SZ (4*1024) #define MAX_SUB_MASK_IX \ - ((((Uint)1) << (NO_OF_BKT_IX_BITS - SUB_MASK_IX_SHIFT)) - 1) -#define MAX_SUB_BKT_IX ((((Uint)1) << SUB_MASK_IX_SHIFT) - 1) + ((((UWord)1) << (NO_OF_BKT_IX_BITS - SUB_MASK_IX_SHIFT)) - 1) +#define MAX_SUB_BKT_IX ((((UWord)1) << SUB_MASK_IX_SHIFT) - 1) #define MAX_BKT_IX (NO_OF_BKTS - 1) -#define MIN_BLK_SZ UNIT_CEILING(sizeof(GFFreeBlock_t) + sizeof(Uint)) +#define MIN_BLK_SZ UNIT_CEILING(sizeof(GFFreeBlock_t) + sizeof(UWord)) -#define IX2SBIX(IX) ((IX) & (~(~((Uint)0) << SUB_MASK_IX_SHIFT))) +#define IX2SBIX(IX) ((IX) & (~(~((UWord)0) << SUB_MASK_IX_SHIFT))) #define IX2SMIX(IX) ((IX) >> SUB_MASK_IX_SHIFT) #define MAKE_BKT_IX(SMIX, SBIX) \ - ((((Uint)(SMIX)) << SUB_MASK_IX_SHIFT) | ((Uint)(SBIX))) + ((((UWord)(SMIX)) << SUB_MASK_IX_SHIFT) | ((UWord)(SBIX))) #define SET_BKT_MASK_IX(BM, IX) \ do { \ int sub_mask_ix__ = IX2SMIX((IX)); \ - (BM).main |= (((Uint) 1) << sub_mask_ix__); \ - (BM).sub[sub_mask_ix__] |= (((Uint)1) << IX2SBIX((IX))); \ + (BM).main |= (((UWord) 1) << sub_mask_ix__); \ + (BM).sub[sub_mask_ix__] |= (((UWord)1) << IX2SBIX((IX))); \ } while (0) #define UNSET_BKT_MASK_IX(BM, IX) \ do { \ int sub_mask_ix__ = IX2SMIX((IX)); \ - (BM).sub[sub_mask_ix__] &= ~(((Uint)1) << IX2SBIX((IX))); \ + (BM).sub[sub_mask_ix__] &= ~(((UWord)1) << IX2SBIX((IX))); \ if (!(BM).sub[sub_mask_ix__]) \ - (BM).main &= ~(((Uint)1) << sub_mask_ix__); \ + (BM).main &= ~(((UWord)1) << sub_mask_ix__); \ } while (0) /* Buckets ... */ @@ -263,8 +263,8 @@ find_bucket(BucketMask_t *bmask, int min_index) while(max != min) { \ mid = ((max - min) >> 1) + min; \ if((BitMask) \ - & (~(~((Uint) 0) << (mid + 1))) \ - & (~((Uint) 0) << min)) \ + & (~(~((UWord) 0) << (mid + 1))) \ + & (~((UWord) 0) << min)) \ max = mid; \ else \ min = mid + 1; \ @@ -272,21 +272,21 @@ find_bucket(BucketMask_t *bmask, int min_index) (MinBit) = min - ASSERT(bmask->main < (((Uint) 1) << (MAX_SUB_MASK_IX+1))); + ASSERT(bmask->main < (((UWord) 1) << (MAX_SUB_MASK_IX+1))); sub_mask_ix = IX2SMIX(min_index); - if ((bmask->main & (~((Uint) 0) << sub_mask_ix)) == 0) + if ((bmask->main & (~((UWord) 0) << sub_mask_ix)) == 0) return -1; /* There exists a non empty bucket; find it... */ - if (bmask->main & (((Uint) 1) << sub_mask_ix)) { + if (bmask->main & (((UWord) 1) << sub_mask_ix)) { sub_bkt_ix = IX2SBIX(min_index); - if ((bmask->sub[sub_mask_ix] & (~((Uint) 0) << sub_bkt_ix)) == 0) { + if ((bmask->sub[sub_mask_ix] & (~((UWord) 0) << sub_bkt_ix)) == 0) { sub_mask_ix++; sub_bkt_ix = 0; - if ((bmask->main & (~((Uint) 0)<< sub_mask_ix)) == 0) + if ((bmask->main & (~((UWord) 0)<< sub_mask_ix)) == 0) return -1; } else @@ -299,17 +299,17 @@ find_bucket(BucketMask_t *bmask, int min_index) ASSERT(sub_mask_ix <= MAX_SUB_MASK_IX); /* Has to be a bit > sub_mask_ix */ - ASSERT(bmask->main & (~((Uint) 0) << (sub_mask_ix))); + ASSERT(bmask->main & (~((UWord) 0) << (sub_mask_ix))); GET_MIN_BIT(sub_mask_ix, bmask->main, sub_mask_ix, MAX_SUB_MASK_IX); find_sub_bkt_ix: ASSERT(sub_mask_ix <= MAX_SUB_MASK_IX); ASSERT(sub_bkt_ix <= MAX_SUB_BKT_IX); - if ((bmask->sub[sub_mask_ix] & (((Uint) 1) << sub_bkt_ix)) == 0) { + if ((bmask->sub[sub_mask_ix] & (((UWord) 1) << sub_bkt_ix)) == 0) { ASSERT(sub_mask_ix + 1 <= MAX_SUB_BKT_IX); /* Has to be a bit > sub_bkt_ix */ - ASSERT(bmask->sub[sub_mask_ix] & (~((Uint) 0) << sub_bkt_ix)); + ASSERT(bmask->sub[sub_mask_ix] & (~((UWord) 0) << sub_bkt_ix)); GET_MIN_BIT(sub_bkt_ix, bmask->sub[sub_mask_ix], @@ -336,7 +336,7 @@ search_bucket(Allctr_t *allctr, int ix, Uint size) Uint min_sz; Uint blk_sz; Uint cand_sz = 0; - Uint max_blk_search; + UWord max_blk_search; GFFreeBlock_t *blk; GFFreeBlock_t *cand = NULL; int blk_on_lambc; @@ -615,9 +615,9 @@ check_block(Allctr_t *allctr, Block_t * blk, int free_block) Uint blk_sz = BLK_SZ(blk); bi = BKT_IX(gfallctr, blk_sz); - ASSERT(gfallctr->bucket_mask.main & (((Uint) 1) << IX2SMIX(bi))); + ASSERT(gfallctr->bucket_mask.main & (((UWord) 1) << IX2SMIX(bi))); ASSERT(gfallctr->bucket_mask.sub[IX2SMIX(bi)] - & (((Uint) 1) << IX2SBIX(bi))); + & (((UWord) 1) << IX2SBIX(bi))); found = 0; for (fblk = gfallctr->buckets[bi]; fblk; fblk = fblk->next) @@ -648,9 +648,9 @@ check_mbc(Allctr_t *allctr, Carrier_t *mbc) int bi; for(bi = 0; bi < NO_OF_BKTS; bi++) { - if ((gfallctr->bucket_mask.main & (((Uint) 1) << IX2SMIX(bi))) + if ((gfallctr->bucket_mask.main & (((UWord) 1) << IX2SMIX(bi))) && (gfallctr->bucket_mask.sub[IX2SMIX(bi)] - & (((Uint) 1) << IX2SBIX(bi)))) { + & (((UWord) 1) << IX2SBIX(bi)))) { ASSERT(gfallctr->buckets[bi] != NULL); } else { diff --git a/erts/emulator/beam/erl_goodfit_alloc.h b/erts/emulator/beam/erl_goodfit_alloc.h index 3d1b8c01f6..648800ce31 100644 --- a/erts/emulator/beam/erl_goodfit_alloc.h +++ b/erts/emulator/beam/erl_goodfit_alloc.h @@ -28,7 +28,7 @@ typedef struct GFAllctr_t_ GFAllctr_t; typedef struct { - Uint mbsd; + UWord mbsd; } GFAllctrInit_t; #define ERTS_DEFAULT_GF_ALLCTR_INIT { \ @@ -49,18 +49,18 @@ Allctr_t *erts_gfalc_start(GFAllctr_t *, GFAllctrInit_t *, AllctrInit_t *); #include "erl_alloc_util.h" #define NO_OF_BKT_IX_BITS (8) -#ifdef ARCH_64 +#if defined(ARCH_64) # define SUB_MASK_IX_SHIFT (6) #else # define SUB_MASK_IX_SHIFT (5) #endif -#define NO_OF_BKTS (((Uint) 1) << NO_OF_BKT_IX_BITS) -#define NO_OF_SUB_MASKS (NO_OF_BKTS/(((Uint) 1) << SUB_MASK_IX_SHIFT)) +#define NO_OF_BKTS (((UWord) 1) << NO_OF_BKT_IX_BITS) +#define NO_OF_SUB_MASKS (NO_OF_BKTS/(((UWord) 1) << SUB_MASK_IX_SHIFT)) typedef struct { - Uint main; - Uint sub[NO_OF_SUB_MASKS]; -} BucketMask_t; + UWord main; + UWord sub[NO_OF_SUB_MASKS]; +} BucketMask_t; typedef struct GFFreeBlock_t_ GFFreeBlock_t; struct GFFreeBlock_t_ { @@ -74,11 +74,11 @@ struct GFAllctr_t_ { char * last_aux_mbc_start; char * last_aux_mbc_end; - Uint bkt_max_size_d; - Uint bkt_intrvl_d; + UWord bkt_max_size_d; + UWord bkt_intrvl_d; BucketMask_t bucket_mask; GFFreeBlock_t * buckets[NO_OF_BKTS]; - Uint max_blk_search; + UWord max_blk_search; }; diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c index 3f022f92b8..62be9d379b 100644 --- a/erts/emulator/beam/erl_instrument.c +++ b/erts/emulator/beam/erl_instrument.c @@ -540,18 +540,18 @@ static void dump_memory_map_to_stream(FILE *fp) if (is_internal_pid(bp->pid)) fprintf(fp, "{%lu, %lu, %lu, {%lu,%lu,%lu}}.\n", - (Uint) bp->type_no, - (Uint) bp->mem, - (Uint) bp->size, - (Uint) pid_channel_no(bp->pid), - (Uint) pid_number(bp->pid), - (Uint) pid_serial(bp->pid)); + (UWord) bp->type_no, + (UWord) bp->mem, + (UWord) bp->size, + (UWord) pid_channel_no(bp->pid), + (UWord) pid_number(bp->pid), + (UWord) pid_serial(bp->pid)); else fprintf(fp, "{%lu, %lu, %lu, undefined}.\n", - (Uint) bp->type_no, - (Uint) bp->mem, - (Uint) bp->size); + (UWord) bp->type_no, + (UWord) bp->mem, + (UWord) bp->size); } if (lock) @@ -638,7 +638,7 @@ Eterm erts_instr_get_memory_map(Process *proc) hsz += 4; } - if ((Uint) bp->mem > MAX_SMALL) + if ((UWord) bp->mem > MAX_SMALL) hsz += BIG_UINT_HEAP_SIZE; if (bp->size > MAX_SMALL) hsz += BIG_UINT_HEAP_SIZE; @@ -749,12 +749,12 @@ Eterm erts_instr_get_memory_map(Process *proc) #endif type = make_small(bp->type_no); - if ((Uint) bp->mem > MAX_SMALL) { - ptr = uint_to_big((Uint) bp->mem, hp); + if ((UWord) bp->mem > MAX_SMALL) { + ptr = uint_to_big((UWord) bp->mem, hp); hp += BIG_UINT_HEAP_SIZE; } else - ptr = make_small((Uint) bp->mem); + ptr = make_small((UWord) bp->mem); if (bp->size > MAX_SMALL) { size = uint_to_big(bp->size, hp); @@ -962,12 +962,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period) fprintf(fp, "{total,[{total,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}]}.\n", - stats->tot.size, - stats->tot.max_size, - stats->tot.max_size_ever, - stats->tot.blocks, - stats->tot.max_blocks, - stats->tot.max_blocks_ever); + (UWord) stats->tot.size, + (UWord) stats->tot.max_size, + (UWord) stats->tot.max_size_ever, + (UWord) stats->tot.blocks, + (UWord) stats->tot.max_blocks, + (UWord) stats->tot.max_blocks_ever); a_max = 0; a_min = ~0; @@ -992,12 +992,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period) "%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s", i == a_min ? "{allocators,\n [" : " ", ERTS_ALC_A2AD(i), - stats->a[i].size, - stats->a[i].max_size, - stats->a[i].max_size_ever, - stats->a[i].blocks, - stats->a[i].max_blocks, - stats->a[i].max_blocks_ever, + (UWord) stats->a[i].size, + (UWord) stats->a[i].max_size, + (UWord) stats->a[i].max_size_ever, + (UWord) stats->a[i].blocks, + (UWord) stats->a[i].max_blocks, + (UWord) stats->a[i].max_blocks_ever, i == a_max ? "]}.\n" : ",\n"); } } @@ -1009,12 +1009,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period) "%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s", i == ERTS_ALC_C_MIN ? "{classes,\n [" : " ", ERTS_ALC_C2CD(i), - stats->c[i].size, - stats->c[i].max_size, - stats->c[i].max_size_ever, - stats->c[i].blocks, - stats->c[i].max_blocks, - stats->c[i].max_blocks_ever, + (UWord) stats->c[i].size, + (UWord) stats->c[i].max_size, + (UWord) stats->c[i].max_size_ever, + (UWord) stats->c[i].blocks, + (UWord) stats->c[i].max_blocks, + (UWord) stats->c[i].max_blocks_ever, i == ERTS_ALC_C_MAX ? "]}.\n" : ",\n" ); } @@ -1025,12 +1025,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period) "%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s", i == ERTS_ALC_N_MIN ? "{types,\n [" : " ", ERTS_ALC_N2TD(i), - stats->n[i].size, - stats->n[i].max_size, - stats->n[i].max_size_ever, - stats->n[i].blocks, - stats->n[i].max_blocks, - stats->n[i].max_blocks_ever, + (UWord) stats->n[i].size, + (UWord) stats->n[i].max_size, + (UWord) stats->n[i].max_size_ever, + (UWord) stats->n[i].blocks, + (UWord) stats->n[i].max_blocks, + (UWord) stats->n[i].max_blocks_ever, i == ERTS_ALC_N_MAX ? "]}.\n" : ",\n" ); } diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h index 5cf7c209bd..459c6363aa 100644 --- a/erts/emulator/beam/erl_message.h +++ b/erts/emulator/beam/erl_message.h @@ -49,7 +49,7 @@ typedef struct erl_heap_fragment ErlHeapFragment; struct erl_heap_fragment { ErlHeapFragment* next; /* Next heap fragment */ ErlOffHeap off_heap; /* Offset heap data. */ - unsigned size; /* Size in words of mem */ + unsigned size; /* Size in (half)words of mem */ unsigned used_size; /* With terms to be moved to heap by GC */ Eterm mem[1]; /* Data */ }; diff --git a/erts/emulator/beam/erl_mtrace.c b/erts/emulator/beam/erl_mtrace.c index 8b8ac2ec80..9f2aa62a9a 100644 --- a/erts/emulator/beam/erl_mtrace.c +++ b/erts/emulator/beam/erl_mtrace.c @@ -79,7 +79,7 @@ static erts_mtx_t mtrace_buf_mutex; #define UI16_SZ (2) #define UI32_SZ (4) #define UI64_SZ (8) -#ifdef ARCH_64 +#ifdef ARCH_64 /* XXX:PaN Halfword? (whole file...) */ # define UI_SZ UI64_SZ #else # define UI_SZ UI32_SZ @@ -188,7 +188,7 @@ check_alloc_entry(byte *sp, byte *ep, byte tag, Uint16 ct_no, int ct_no_n, Uint16 type, int type_n, - Uint res, int res_n, + UWord res, int res_n, Uint size, int size_n, Uint32 ti,int ti_n); void @@ -196,8 +196,8 @@ check_realloc_entry(byte *sp, byte *ep, byte tag, Uint16 ct_no, int ct_no_n, Uint16 type, int type_n, - Uint res, int res_n, - Uint ptr, int ptr_n, + UWord res, int res_n, + UWord ptr, int ptr_n, Uint size, int size_n, Uint32 ti,int ti_n); void @@ -205,7 +205,7 @@ check_free_entry(byte *sp, byte *ep, byte tag, Uint16 ct_no, int ct_no_n, Uint16 t_no, int t_no_n, - Uint ptr, int ptr_n, + UWord ptr, int ptr_n, Uint32 ti,int ti_n); void check_time_inc_entry(byte *sp, byte *ep, @@ -785,7 +785,7 @@ write_alloc_entry(byte tag, tag, ct_no, ct_no_n, t_no, t_no_n, - (Uint) res, res_n, + (UWord) res, res_n, size, size_n, ti, ti_n); #endif @@ -865,8 +865,8 @@ write_realloc_entry(byte tag, tag, ct_no, ct_no_n, t_no, t_no_n, - (Uint) res, res_n, - (Uint) ptr, ptr_n, + (UWord) res, res_n, + (UWord) ptr, ptr_n, size, size_n, ti, ti_n); #endif @@ -934,7 +934,7 @@ write_free_entry(byte tag, tag, ct_no, ct_no_n, t_no, t_no_n, - (Uint) ptr, ptr_n, + (UWord) ptr, ptr_n, ti, ti_n); #endif } @@ -1135,7 +1135,7 @@ check_alloc_entry(byte *sp, byte *ep, byte tag, Uint16 ct_no, int ct_no_n, Uint16 t_no, int t_no_n, - Uint res, int res_n, + UWord res, int res_n, Uint size, int size_n, Uint32 ti,int ti_n) { @@ -1163,8 +1163,8 @@ check_realloc_entry(byte *sp, byte *ep, byte tag, Uint16 ct_no, int ct_no_n, Uint16 t_no, int t_no_n, - Uint res, int res_n, - Uint ptr, int ptr_n, + UWord res, int res_n, + UWord ptr, int ptr_n, Uint size, int size_n, Uint32 ti,int ti_n) { @@ -1193,7 +1193,7 @@ check_free_entry(byte *sp, byte *ep, byte tag, Uint16 ct_no, int ct_no_n, Uint16 t_no, int t_no_n, - Uint ptr, int ptr_n, + UWord ptr, int ptr_n, Uint32 ti,int ti_n) { byte *p = sp; diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 585a6c1fdf..7c62bcb016 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -496,9 +496,9 @@ int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len) int enif_get_int(ErlNifEnv* env, Eterm term, int* ip) { -#if SIZEOF_INT == SIZEOF_VOID_P +#if SIZEOF_INT == ERTS_SIZEOF_ETERM return term_to_Sint(term, (Sint*)ip); -#elif SIZEOF_LONG == SIZEOF_VOID_P +#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM Sint i; if (!term_to_Sint(term, &i) || i < INT_MIN || i > INT_MAX) { return 0; @@ -512,9 +512,9 @@ int enif_get_int(ErlNifEnv* env, Eterm term, int* ip) int enif_get_uint(ErlNifEnv* env, Eterm term, unsigned* ip) { -#if SIZEOF_INT == SIZEOF_VOID_P +#if SIZEOF_LONG == ERTS_SIZEOF_ETERM return term_to_Uint(term, (Uint*)ip); -#elif SIZEOF_LONG == SIZEOF_VOID_P +#elif SIZEOF_INT == ERTS_SIZEOF_ETERM Uint i; if (!term_to_Uint(term, &i) || i > UINT_MAX) { return 0; @@ -526,8 +526,13 @@ int enif_get_uint(ErlNifEnv* env, Eterm term, unsigned* ip) int enif_get_long(ErlNifEnv* env, Eterm term, long* ip) { -#if SIZEOF_LONG == SIZEOF_VOID_P +#if SIZEOF_LONG == ERTS_SIZEOF_ETERM return term_to_Sint(term, ip); +#elif SIZEOF_INT == ERTS_SIZEOF_ETERM + Uint u; + term_to_Sint(term, u); + *ip = (long) u; + return 1; #else # error Unknown long word size #endif @@ -535,8 +540,14 @@ int enif_get_long(ErlNifEnv* env, Eterm term, long* ip) int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip) { -#if SIZEOF_LONG == SIZEOF_VOID_P +#if SIZEOF_LONG == ERTS_SIZEOF_ETERM return term_to_Uint(term, ip); +#elif SIZEOF_INT == ERTS_SIZEOF_ETERM + Uint u; + int r; + r = term_to_Uint(term, &u); + *ip = (unsigned long) u; + return r; #else # error Unknown long word size #endif @@ -565,27 +576,24 @@ int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail) ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i) { -#if SIZEOF_INT == SIZEOF_VOID_P +#if SIZEOF_INT == ERTS_SIZEOF_ETERM return IS_SSMALL(i) ? make_small(i) : small_to_big(i,alloc_heap(env,2)); -#elif SIZEOF_LONG == SIZEOF_VOID_P +#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM return make_small(i); #endif } ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i) { -#if SIZEOF_INT == SIZEOF_VOID_P +#if SIZEOF_INT == ERTS_SIZEOF_ETERM return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2)); -#elif SIZEOF_LONG == SIZEOF_VOID_P +#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM return make_small(i); #endif } ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i) { -#if SIZEOF_LONG != SIZEOF_VOID_P -# error Unknown long word size -#endif return IS_SSMALL(i) ? make_small(i) : small_to_big(i, alloc_heap(env,2)); } @@ -967,34 +975,34 @@ unsigned enif_sizeof_resource(ErlNifEnv* env, void* obj) ***************************************************************************/ -static Uint** get_func_pp(Eterm* mod_code, Eterm f_atom, unsigned arity) +static UWord** get_func_pp(UWord* mod_code, Eterm f_atom, unsigned arity) { int n = (int) mod_code[MI_NUM_FUNCTIONS]; int j; for (j = 0; j < n; ++j) { - Uint* code_ptr = (Uint*) mod_code[MI_FUNCTIONS+j]; - ASSERT(code_ptr[0] == (Uint) BeamOp(op_i_func_info_IaaI)); + UWord* code_ptr = (UWord*) mod_code[MI_FUNCTIONS+j]; + ASSERT(code_ptr[0] == (UWord) BeamOp(op_i_func_info_IaaI)); if (f_atom == ((Eterm) code_ptr[3]) && arity == ((unsigned) code_ptr[4])) { - return (Uint**) &mod_code[MI_FUNCTIONS+j]; + return (UWord**) &mod_code[MI_FUNCTIONS+j]; } } return NULL; } -/*static void refresh_cached_nif_data(Eterm* mod_code, +/*static void refresh_cached_nif_data(BeamInstr* mod_code, struct erl_module_nif* mod_nif) { int i; for (i=0; i < mod_nif->entry->num_of_funcs; i++) { Eterm f_atom; ErlNifFunc* func = &mod_nif->entry->funcs[i]; - Uint* code_ptr; + BeamInstr* code_ptr; erts_atom_get(func->name, sys_strlen(func->name), &f_atom); code_ptr = *get_func_pp(mod_code, f_atom, func->arity); - code_ptr[5+2] = (Uint) mod_nif->priv_data; + code_ptr[5+2] = (UWord) mod_nif->priv_data; } }*/ @@ -1098,7 +1106,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) Module* mod; Eterm mod_atom; Eterm f_atom; - Eterm* caller; + UWord* caller; ErtsSysDdllError errdesc = ERTS_SYS_DDLL_ERROR_INIT; Eterm ret = am_ok; int veto; @@ -1165,7 +1173,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) /*erts_fprintf(stderr, "Found module %T\r\n", mod_atom);*/ for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) { - Uint** code_pp; + UWord** code_pp; ErlNifFunc* f = &entry->funcs[i]; if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom) || (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) { @@ -1268,19 +1276,19 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) mod->nif = lib; for (i=0; i < entry->num_of_funcs; i++) { - Uint* code_ptr; + BeamInstr* code_ptr; erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom); code_ptr = *get_func_pp(mod->code, f_atom, entry->funcs[i].arity); if (code_ptr[1] == 0) { - code_ptr[5+0] = (Uint) BeamOp(op_call_nif); + code_ptr[5+0] = (BeamInstr) BeamOp(op_call_nif); } else { /* Function traced, patch the original instruction word */ BpData* bp = (BpData*) code_ptr[1]; - bp->orig_instr = (Uint) BeamOp(op_call_nif); + bp->orig_instr = (BeamInstr) BeamOp(op_call_nif); } - code_ptr[5+1] = (Uint) entry->funcs[i].fptr; - code_ptr[5+2] = (Uint) lib; + code_ptr[5+1] = (BeamInstr) entry->funcs[i].fptr; + code_ptr[5+2] = (BeamInstr) lib; } } else { diff --git a/erts/emulator/beam/erl_node_container_utils.h b/erts/emulator/beam/erl_node_container_utils.h index 87dbfc2a04..f620582bdb 100644 --- a/erts/emulator/beam/erl_node_container_utils.h +++ b/erts/emulator/beam/erl_node_container_utils.h @@ -251,7 +251,7 @@ extern int erts_use_r9_pids_ports; * Refs * \* */ -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP #define internal_ref_no_of_numbers(x) \ (internal_ref_data((x))[0]) diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index f3f10201b5..6960844e99 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -1109,11 +1109,21 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) break; } if (insert_bin) { +#if HALFWORD_HEAP + UWord val = (UWord) pb->val; + DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE*2); /* extra place allocated */ +#else DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE); +#endif Uint *hp = &id_heap[0]; InsertedBin *nib; +#if HALFWORD_HEAP + UseTmpHeapNoproc(BIG_UWORD_HEAP_SIZE(val)); + a.id = erts_bld_uword(&hp, NULL, (UWord) val); +#else UseTmpHeapNoproc(BIG_UINT_HEAP_SIZE); a.id = erts_bld_uint(&hp, NULL, (Uint) pb->val); +#endif erts_match_prog_foreach_offheap(pb->val, insert_offheap2, (void *) &a); @@ -1121,7 +1131,11 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) nib->bin_val = pb->val; nib->next = inserted_bins; inserted_bins = nib; +#if HALFWORD_HEAP + UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE*2); +#else UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE); +#endif } } } diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h index c48dac6219..3f53de9cf2 100644 --- a/erts/emulator/beam/erl_node_tables.h +++ b/erts/emulator/beam/erl_node_tables.h @@ -61,7 +61,7 @@ #define ERTS_DE_QFLGS_ALL (ERTS_DE_QFLG_BUSY \ | ERTS_DE_QFLG_EXIT) -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP #define ERTS_DIST_OUTPUT_BUF_DBG_PATTERN ((Uint) 0xf713f713f713f713UL) #else #define ERTS_DIST_OUTPUT_BUF_DBG_PATTERN ((Uint) 0xf713f713) diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c index 7fe3f3bca5..9ad0965144 100644 --- a/erts/emulator/beam/erl_printf_term.c +++ b/erts/emulator/beam/erl_printf_term.c @@ -246,7 +246,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount) if (is_CP(obj)) { PRINT_STRING(res, fn, arg, "'); return res; } @@ -406,7 +406,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount) break; case EXPORT_DEF: { - Export* ep = (Export *) (export_val(obj))[1]; + 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])); @@ -438,7 +438,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount) break; default: PRINT_STRING(res, fn, arg, "'); break; } diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index f5b1308ca4..429bdd74fb 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -91,9 +91,9 @@ do { \ #define ERTS_EMPTY_RUNQ(RQ) \ ((RQ)->len == 0 && (RQ)->misc.start == NULL) -extern Eterm beam_apply[]; -extern Eterm beam_exit[]; -extern Eterm beam_continue_exit[]; +extern UWord beam_apply[]; +extern UWord beam_exit[]; +extern UWord beam_continue_exit[]; static Sint p_last; static Sint p_next; @@ -334,7 +334,7 @@ do { \ static void init_processes_bif(void); static void save_terminating_process(Process *p); static void exec_misc_ops(ErtsRunQueue *); -static void print_function_from_pc(int to, void *to_arg, Eterm* x); +static void print_function_from_pc(int to, void *to_arg, UWord* x); static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg); #ifdef ERTS_SMP @@ -2078,9 +2078,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) erts_aligned_run_queues = erts_alloc(ERTS_ALC_T_RUNQS, (sizeof(ErtsAlignedRunQueue)*(n+1))); - if ((((Uint) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0) + if ((((UWord) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0) erts_aligned_run_queues = ((ErtsAlignedRunQueue *) - ((((Uint) erts_aligned_run_queues) + ((((UWord) erts_aligned_run_queues) & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE)); @@ -2175,9 +2175,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) erts_aligned_scheduler_data = erts_alloc(ERTS_ALC_T_SCHDLR_DATA, (sizeof(ErtsAlignedSchedulerData) *(n+1))); - if ((((Uint) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) == 0) + if ((((UWord) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) == 0) erts_aligned_scheduler_data = ((ErtsAlignedSchedulerData *) - ((((Uint) erts_aligned_scheduler_data) + ((((UWord) erts_aligned_scheduler_data) & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE)); for (ix = 0; ix < n; ix++) { @@ -2186,6 +2186,10 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) erts_bits_init_state(&esdp->erl_bits_state); esdp->match_pseudo_process = NULL; esdp->free_process = NULL; +#if HALFWORD_HEAP + /* Registers need to be heap allocated (correct memory range) for tracing to work */ + esdp->save_reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm)); +#endif #endif #if !HEAP_ON_C_STACK esdp->num_tmp_heap_used = 0; @@ -4484,7 +4488,7 @@ add_pend_suspend(Process *suspendee, sizeof(ErtsPendingSuspend)); psp->next = NULL; #ifdef DEBUG -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP psp->end = (ErtsPendingSuspend *) 0xdeaddeaddeaddead; #else psp->end = (ErtsPendingSuspend *) 0xdeaddead; @@ -6765,8 +6769,8 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). p->current = p->initial+INITIAL_MOD; - p->i = (Eterm *) beam_apply; - p->cp = (Eterm *) beam_apply+1; + p->i = (UWord *) beam_apply; + p->cp = (UWord *) beam_apply+1; p->arg_reg = p->def_arg_reg; p->max_arg_reg = sizeof(p->def_arg_reg)/sizeof(p->def_arg_reg[0]); @@ -7351,7 +7355,7 @@ set_proc_exiting(Process *p, Eterm reason, ErlHeapFragment *bp) p->freason = EXTAG_EXIT; KILL_CATCHES(p); cancel_timer(p); - p->i = (Eterm *) beam_exit; + p->i = (UWord *) beam_exit; } @@ -8279,7 +8283,7 @@ continue_exit_process(Process *p ASSERT(p->status == P_EXITING); - p->i = (Eterm *) beam_continue_exit; + p->i = (UWord *) beam_continue_exit; if (!(curr_locks & ERTS_PROC_LOCK_STATUS)) { erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS); @@ -8299,7 +8303,7 @@ continue_exit_process(Process *p static void timeout_proc(Process* p) { - p->i = (Eterm *) p->def_arg_reg[0]; + p->i = *((UWord **) (UWord) p->def_arg_reg); p->flags |= F_TIMO; p->flags &= ~F_INSLPQUEUE; @@ -8398,9 +8402,9 @@ erts_program_counter_info(int to, void *to_arg, Process *p) } static void -print_function_from_pc(int to, void *to_arg, Eterm* x) +print_function_from_pc(int to, void *to_arg, UWord* x) { - Eterm* addr = find_function_from_pc(x); + UWord* addr = find_function_from_pc(x); if (addr == NULL) { if (x == beam_exit) { erts_print(to, to_arg, ""); @@ -8434,7 +8438,7 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg) } if (is_CP(x)) { - erts_print(to, to_arg, "Return addr %p (", (Eterm *) x); + erts_print(to, to_arg, "Return addr %p (", (Eterm *) EXPAND_POINTER(x)); print_function_from_pc(to, to_arg, cp_val(x)); erts_print(to, to_arg, ")\n"); yreg = 0; @@ -9263,8 +9267,8 @@ init_processes_bif(void) processes_trap_export.code[0] = am_erlang; processes_trap_export.code[1] = am_processes_trap; processes_trap_export.code[2] = 2; - processes_trap_export.code[3] = (Eterm) em_apply_bif; - processes_trap_export.code[4] = (Eterm) &processes_trap; + processes_trap_export.code[3] = (UWord) em_apply_bif; + processes_trap_export.code[4] = (UWord) &processes_trap; #if ERTS_PROCESSES_BIF_DEBUGLEVEL >= ERTS_PROCS_DBGLVL_CHK_TERM_PROC_LIST erts_get_emu_time(&debug_tv_start); diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 4466442fbc..df08f2474c 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -179,7 +179,7 @@ extern int erts_sched_thread_suggested_stack_size; #ifdef DEBUG -# ifdef ARCH_64 +# if defined(ARCH_64) && !HALFWORD_HEAP # define ERTS_DBG_SET_INVALID_RUNQP(RQP, N) \ (*((char **) &(RQP)) = (char *) (0xdeadbeefdead0003 | ((N) << 4))) # define ERTS_DBG_VERIFY_VALID_RUNQP(RQP) \ @@ -344,7 +344,11 @@ struct ErtsSchedulerData_ { * numbered registers as possible in the same cache * line). */ +#if !HALFWORD_HEAP Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers */ +#else + Eterm *save_reg; +#endif FloatDef freg[MAX_REG]; /* Floating point registers. */ ethr_tid tid; /* Thread id */ struct erl_bits_state erl_bits_state; /* erl_bits.c state */ @@ -525,8 +529,8 @@ struct process { unsigned max_arg_reg; /* Maximum number of argument registers available. */ Eterm def_arg_reg[6]; /* Default array for argument registers. */ - Eterm* cp; /* Continuation pointer (for threaded code). */ - Eterm* i; /* Program counter for threaded code. */ + UWord* cp; /* Continuation pointer (for threaded code). */ + UWord* i; /* Program counter for threaded code. */ Sint catches; /* Number of catches on stack */ Sint fcalls; /* * Number of reductions left to execute. @@ -573,11 +577,11 @@ struct process { Uint seq_trace_lastcnt; Eterm seq_trace_token; /* Sequential trace token (tuple size 5 see below) */ - Eterm initial[3]; /* Initial module(0), function(1), arity(2) */ - Eterm* current; /* Current Erlang function: + UWord initial[3]; /* Initial module(0), function(1), arity(2) */ + UWord* current; /* Current Erlang function, part of the funcinfo: * module(0), function(1), arity(2) * (module and functions are tagged atoms; - * arity an untagged integer). + * arity an untagged integer). UWord * because it references code */ /* @@ -1216,8 +1220,8 @@ erts_proc_get_error_handler(Process *p) if (!val) return am_error_handler; else { - ASSERT(is_atom(((Eterm) val))); - return (Eterm) val; + ASSERT(is_atom(((Eterm) (UWord) val))); + return (Eterm) (UWord) val; } } @@ -1227,13 +1231,13 @@ erts_proc_set_error_handler(Process *p, ErtsProcLocks plocks, Eterm handler) void *old_val; void *new_val; ASSERT(is_atom(handler)); - new_val = handler == am_error_handler ? NULL : (void *) handler; + new_val = (handler == am_error_handler) ? NULL : (void *) (UWord) handler; old_val = erts_psd_set(p, plocks, ERTS_PSD_ERROR_HANDLER, new_val); if (!old_val) return am_error_handler; else { - ASSERT(is_atom(((Eterm) old_val))); - return (Eterm) old_val; + ASSERT(is_atom(((Eterm) (UWord) old_val))); + return (Eterm) (UWord) old_val; } } diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c index 1666509c72..0b776367ed 100644 --- a/erts/emulator/beam/erl_process_dump.c +++ b/erts/emulator/beam/erl_process_dump.c @@ -45,16 +45,16 @@ static void dump_dist_ext(int to, void *to_arg, ErtsDistExternal *edep); static void dump_element_nl(int to, void *to_arg, Eterm x); static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg); -static void print_function_from_pc(int to, void *to_arg, Eterm* x); +static void print_function_from_pc(int to, void *to_arg, UWord* x); static void heap_dump(int to, void *to_arg, Eterm x); static void dump_binaries(int to, void *to_arg, Binary* root); static void dump_externally(int to, void *to_arg, Eterm term); static Binary* all_binaries; -extern Eterm beam_apply[]; -extern Eterm beam_exit[]; -extern Eterm beam_continue_exit[]; +extern UWord beam_apply[]; +extern UWord beam_exit[]; +extern UWord beam_continue_exit[]; void @@ -223,7 +223,7 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg) } if (is_CP(x)) { - erts_print(to, to_arg, "SReturn addr 0x%X (", (Eterm *) x); + erts_print(to, to_arg, "SReturn addr 0x%X (", cp_val(x)); print_function_from_pc(to, to_arg, cp_val(x)); erts_print(to, to_arg, ")\n"); yreg = 0; @@ -239,9 +239,9 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg) } static void -print_function_from_pc(int to, void *to_arg, Eterm* x) +print_function_from_pc(int to, void *to_arg, UWord* x) { - Eterm* addr = find_function_from_pc(x); + UWord* addr = find_function_from_pc(x); if (addr == NULL) { if (x == beam_exit) { erts_print(to, to_arg, ""); @@ -273,7 +273,7 @@ heap_dump(int to, void *to_arg, Eterm x) if (x == OUR_NIL) { /* We are done. */ return; } if (is_CP(x)) { - next = (Eterm *) x; + next = (Eterm *) EXPAND_POINTER(x); } else if (is_list(x)) { ptr = list_val(x); if (ptr[0] != OUR_NIL) { @@ -286,7 +286,7 @@ heap_dump(int to, void *to_arg, Eterm x) ptr[1] = make_small(0); } x = ptr[0]; - ptr[0] = (Eterm) next; + ptr[0] = (Eterm) COMPRESS_POINTER(next); next = ptr + 1; goto again; } @@ -316,7 +316,7 @@ heap_dump(int to, void *to_arg, Eterm x) ptr[0] = OUR_NIL; } else { x = ptr[arity]; - ptr[0] = (Eterm) next; + ptr[0] = (Eterm) COMPRESS_POINTER(next); next = ptr + arity - 1; goto again; } @@ -351,7 +351,7 @@ heap_dump(int to, void *to_arg, Eterm x) Binary* val = pb->val; if (erts_smp_atomic_xchg(&val->refc, 0) != 0) { - val->flags = (Uint) all_binaries; + val->flags = (UWord) all_binaries; all_binaries = val; } erts_print(to, to_arg, "Yc%X:%X:%X", val, diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c index c0ed3cb0a6..dd163b2b21 100644 --- a/erts/emulator/beam/erl_term.c +++ b/erts/emulator/beam/erl_term.c @@ -105,7 +105,7 @@ unsigned tag_val_def(Eterm x) break; } } - sprintf(msg, "tag_val_def: %#lx", x); + sprintf(msg, "tag_val_def: %#lx", (unsigned long) x); et_abort(msg, file, line); #undef file #undef line @@ -165,8 +165,8 @@ ET_DEFINE_CHECKED(Uint32*,external_ref_data,Eterm,is_external_ref); ET_DEFINE_CHECKED(struct erl_node_*,external_ref_node,Eterm,is_external_ref); ET_DEFINE_CHECKED(Eterm*,export_val,Eterm,is_export); -ET_DEFINE_CHECKED(Eterm,make_cp,Uint*,_is_taggable_pointer); -ET_DEFINE_CHECKED(Uint*,cp_val,Eterm,is_CP); +ET_DEFINE_CHECKED(Eterm,make_cp,UWord *,_is_taggable_pointer); +ET_DEFINE_CHECKED(UWord *,cp_val,Eterm,is_CP); ET_DEFINE_CHECKED(Uint,catch_val,Eterm,is_catch); ET_DEFINE_CHECKED(Uint,x_reg_offset,Uint,_is_xreg); ET_DEFINE_CHECKED(Uint,y_reg_offset,Uint,_is_yreg); diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 016d6e66a7..8e74502022 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -20,10 +20,7 @@ #ifndef __ERL_TERM_H #define __ERL_TERM_H -#ifdef ARCH_64 -#define HALFWORD_HEAP 1 -#define HALFWORD_ASSERT 1 -#endif +#include "sys.h" /* defines HALFWORD_HEAP */ #if HALFWORD_HEAP # define HEAP_ON_C_STACK 0 @@ -35,8 +32,8 @@ # endif # if 1 # define CHECK_POINTER_MASK 0xFFFFFFFF00000000UL -# define COMPRESS_POINTER(AnUint) (AnUint) -# define EXPAND_POINTER(APointer) (APointer) +# define COMPRESS_POINTER(APointer) ((Eterm) (UWord) (APointer)) +# define EXPAND_POINTER(AnEterm) ((UWord) (AnEterm)) # else # define CHECK_POINTER_MASK 0x0UL # define COMPRESS_POINTER(AnUint) (AnUint) @@ -188,14 +185,14 @@ struct erl_node_; /* Declared in erl_node_tables.h */ /* boxed object access methods */ #if HALFWORD_HEAP -#define _is_taggable_pointer(x) (((Uint)(x) & (CHECK_POINTER_MASK | 0x3)) == 0) +#define _is_taggable_pointer(x) (((UWord)(x) & (CHECK_POINTER_MASK | 0x3)) == 0) #define _boxed_precond(x) (is_boxed(x)) #else #define _is_taggable_pointer(x) (((Uint)(x) & 0x3) == 0) #define _boxed_precond(x) (is_boxed(x)) #endif #define _is_aligned(x) (((Uint)(x) & 0x3) == 0) -#define _unchecked_make_boxed(x) COMPRESS_POINTER((Uint)(x) + TAG_PRIMARY_BOXED) +#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED) _ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*); #define make_boxed(x) _ET_APPLY(make_boxed,(x)) #if 1 @@ -206,12 +203,12 @@ _ET_DECLARE_CHECKED(int,is_boxed,Eterm) #else #define is_boxed(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED) #endif -#define _unchecked_boxed_val(x) EXPAND_POINTER((Eterm*)((x) - TAG_PRIMARY_BOXED)) +#define _unchecked_boxed_val(x) ((Eterm*) EXPAND_POINTER(((x) - TAG_PRIMARY_BOXED))) _ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm); #define boxed_val(x) _ET_APPLY(boxed_val,(x)) /* cons cell ("list") access methods */ -#define _unchecked_make_list(x) COMPRESS_POINTER((Uint)(x) + TAG_PRIMARY_LIST) +#define _unchecked_make_list(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_LIST) _ET_DECLARE_CHECKED(Eterm,make_list,Eterm*); #define make_list(x) _ET_APPLY(make_list,(x)) #if 1 @@ -228,7 +225,7 @@ _ET_DECLARE_CHECKED(int,is_not_list,Eterm) #else #define _list_precond(x) (is_list(x)) #endif -#define _unchecked_list_val(x) EXPAND_POINTER((Eterm*)((x) - TAG_PRIMARY_LIST)) +#define _unchecked_list_val(x) ((Eterm*) EXPAND_POINTER((x) - TAG_PRIMARY_LIST)) _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm); #define list_val(x) _ET_APPLY(list_val,(x)) @@ -239,13 +236,13 @@ _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm); #define CDR(x) ((x)[1]) /* generic tagged pointer (boxed or list) access methods */ -#define _unchecked_ptr_val(x) EXPAND_POINTER((Eterm*)((x) & ~((Uint) 0x3))) +#define _unchecked_ptr_val(x) ((Eterm*) EXPAND_POINTER((x) & ~((Uint) 0x3))) #define ptr_val(x) _unchecked_ptr_val((x)) /*XXX*/ #define _unchecked_offset_ptr(x,offs) ((x)+((offs)*sizeof(Eterm))) #define offset_ptr(x,offs) _unchecked_offset_ptr(x,offs) /*XXX*/ /* fixnum ("small") access methods */ -#if defined(ARCH_64) +#if defined(ARCH_64) && !HALFWORD_HEAP #define SMALL_BITS (64-4) #define SMALL_DIGITS (17) #else @@ -370,7 +367,11 @@ _ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm) _ET_DECLARE_CHECKED(Eterm*,export_val,Eterm) #define export_val(x) _ET_APPLY(export_val,(x)) #define is_export_header(x) ((x) == HEADER_EXPORT) +#if HALFWORD_HEAP +#define HEADER_EXPORT _make_header(2,_TAG_HEADER_EXPORT) +#else #define HEADER_EXPORT _make_header(1,_TAG_HEADER_EXPORT) +#endif /* bignum access methods */ #define make_pos_bignum_header(sz) _make_header((sz),_TAG_HEADER_POS_BIG) @@ -394,7 +395,7 @@ _ET_DECLARE_CHECKED(Eterm*,big_val,Eterm) #define big_val(x) _ET_APPLY(big_val,(x)) /* flonum ("float") access methods */ -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP #define HEADER_FLONUM _make_header(1,_TAG_HEADER_FLOAT) #else #define HEADER_FLONUM _make_header(2,_TAG_HEADER_FLOAT) @@ -415,12 +416,12 @@ typedef union float_def byte fb[sizeof(ieee754_8)]; Uint16 fs[sizeof(ieee754_8) / sizeof(Uint16)]; Uint32 fw[sizeof(ieee754_8) / sizeof(Uint32)]; -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP Uint fdw; #endif } FloatDef; -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP #define GET_DOUBLE(x, f) (f).fdw = *(float_val(x)+1) #define PUT_DOUBLE(f, x) *(x) = HEADER_FLONUM, \ @@ -720,7 +721,7 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm) #define ERTS_MAX_REF_NUMBERS 3 #define ERTS_REF_NUMBERS ERTS_MAX_REF_NUMBERS -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP # define ERTS_REF_WORDS (ERTS_REF_NUMBERS/2 + 1) # define ERTS_REF_32BIT_WORDS (ERTS_REF_NUMBERS+1) #else @@ -742,7 +743,7 @@ typedef struct { #define make_ref_thing_header(DW) \ _make_header((DW)+REF_THING_HEAD_SIZE-1,_TAG_HEADER_REF) -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP /* * Ref layout on a 64-bit little endian machine: @@ -985,15 +986,15 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm) #error "fix yer arch, like" #endif -#define _unchecked_make_cp(x) ((Eterm)(x)) -_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*) +#define _unchecked_make_cp(x) ((Eterm) COMPRESS_POINTER(x)) +_ET_DECLARE_CHECKED(Eterm,make_cp,UWord*); #define make_cp(x) _ET_APPLY(make_cp,(x)) #define is_not_CP(x) ((x) & _CPMASK) #define is_CP(x) (!is_not_CP(x)) -#define _unchecked_cp_val(x) ((Uint*)(x)) -_ET_DECLARE_CHECKED(Uint*,cp_val,Eterm) +#define _unchecked_cp_val(x) ((UWord*) EXPAND_POINTER(x)) +_ET_DECLARE_CHECKED(UWord*,cp_val,Eterm); #define cp_val(x) _ET_APPLY(cp_val,(x)) #define make_catch(x) (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH) diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index f98d5ee522..eb61c72e90 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -1182,7 +1182,7 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type, * or {trace, Pid, return_to, {Mod, Func, Arity}} */ void -erts_trace_return_to(Process *p, Uint *pc) +erts_trace_return_to(Process *p, UWord *pc) { #define LOCAL_HEAP_SIZE (4+5+5) Eterm* hp; @@ -1190,7 +1190,7 @@ erts_trace_return_to(Process *p, Uint *pc) Eterm mess; DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); - Eterm *code_ptr = find_function_from_pc(pc); + UWord *code_ptr = find_function_from_pc(pc); UseTmpHeapNoproc(LOCAL_HEAP_SIZE); @@ -1249,7 +1249,7 @@ erts_trace_return_to(Process *p, Uint *pc) * or {trace, Pid, return_from, {Mod, Name, Arity}, Retval} */ void -erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid) +erts_trace_return(Process* p, UWord* fi, Eterm retval, Eterm *tracer_pid) { Eterm* hp; Eterm mfa; @@ -1380,7 +1380,7 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid) * Where Class is atomic but Value is any term. */ void -erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value, +erts_trace_exception(Process* p, UWord mfa[3], Eterm class, Eterm value, Eterm *tracer_pid) { Eterm* hp; @@ -1439,7 +1439,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value, UseTmpHeapNoproc(LOCAL_HEAP_SIZE); hp = local_heap; - mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2])); + mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], make_small((Eterm)mfa[2])); hp += 4; cv = TUPLE2(hp, class, value); hp += 3; @@ -1485,7 +1485,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value, * Build the trace tuple and put it into receive queue of the tracer process. */ - mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2])); + mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], make_small((Eterm) mfa[2])); hp += 4; value = copy_struct(value, value_size, &hp, off_heap); cv = TUPLE2(hp, class, value); @@ -1522,7 +1522,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value, * if it is a pid or port we do a meta trace. */ Uint32 -erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, +erts_call_trace(Process* p, UWord mfa[3], Binary *match_spec, Eterm* args, int local, Eterm *tracer_pid) { Eterm* hp; @@ -1589,7 +1589,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, * such as size_object() and copy_struct(), we must make sure that we * temporarily convert any match contexts to sub binaries. */ - arity = mfa[2]; + arity = (Eterm) mfa[2]; UseTmpHeap(ERL_SUB_BIN_SIZE,p); #ifdef DEBUG sub_bin_heap->thing_word = 0; @@ -1725,7 +1725,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, hp += 2; } } - mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], mfa_tuple); + mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], mfa_tuple); hp += 4; /* @@ -1888,7 +1888,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec, hp += 2; } } - mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], mfa_tuple); + mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], mfa_tuple); hp += 4; /* @@ -2092,7 +2092,7 @@ void save_calls(Process *p, Export *e) */ Eterm erts_bif_trace(int bif_index, Process* p, - Eterm arg1, Eterm arg2, Eterm arg3, Uint *I) + Eterm arg1, Eterm arg2, Eterm arg3, UWord *I) { Eterm result; int meta = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_META); @@ -2106,10 +2106,10 @@ erts_bif_trace(int bif_index, Process* p, * no tracing will occur. Doing the whole else branch will * also do nothing, only slower. */ - Eterm (*func)(Process*, Eterm, Eterm, Eterm, Uint*) = bif_table[bif_index].f; + Eterm (*func)(Process*, Eterm, Eterm, Eterm, UWord*) = bif_table[bif_index].f; result = func(p, arg1, arg2, arg3, I); } else { - Eterm (*func)(Process*, Eterm, Eterm, Eterm, Uint*); + Eterm (*func)(Process*, Eterm, Eterm, Eterm, UWord*); Export* ep = bif_export[bif_index]; Uint32 flags = 0, flags_meta = 0; int global = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_GLOBAL); @@ -2118,16 +2118,9 @@ erts_bif_trace(int bif_index, Process* p, int applying = (I == &(ep->code[3])); /* Yup, the apply code for a bif * is actually in the * export entry */ - Eterm *cp = p->cp; + UWord *cp = p->cp; -#ifndef _OSE_ Eterm args[3] = {arg1, arg2, arg3}; -#else - Eterm args[3]; - args[0] = arg1; - args[1] = arg2; - args[2] = arg3; -#endif /* * Make continuation pointer OK, it is not during direct BIF calls, @@ -2157,12 +2150,11 @@ erts_bif_trace(int bif_index, Process* p, Eterm *cpp; /* Maybe advance cp to skip trace stack frames */ for (cpp = p->stop; ; cp = cp_val(*cpp++)) { - ASSERT(is_CP((Eterm) cp)); - if (*cp_val((Eterm) cp) == i_return_trace) { + if (*cp == i_return_trace) { /* Skip stack frame variables */ while (is_not_CP(*cpp)) cpp++; cpp += 2; /* Skip return_trace parameters */ - } else if (*cp_val((Eterm) cp) == i_return_to_trace) { + } else if (*cp == i_return_to_trace) { /* A return_to trace message is going to be generated * by normal means, so we do not have to. */ diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index ab5811c70f..8f16f7338f 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -90,9 +90,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_utf8_trap",23); characters_to_utf8_trap_exp.code[2] = 3; characters_to_utf8_trap_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; characters_to_utf8_trap_exp.code[4] = - (Eterm) &characters_to_utf8_trap; + (UWord) &characters_to_utf8_trap; memset(&characters_to_list_trap_1_exp, 0, sizeof(Export)); characters_to_list_trap_1_exp.address = @@ -102,9 +102,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_1",25); characters_to_list_trap_1_exp.code[2] = 3; characters_to_list_trap_1_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; characters_to_list_trap_1_exp.code[4] = - (Eterm) &characters_to_list_trap_1; + (UWord) &characters_to_list_trap_1; memset(&characters_to_list_trap_2_exp, 0, sizeof(Export)); characters_to_list_trap_2_exp.address = @@ -114,9 +114,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_2",25); characters_to_list_trap_2_exp.code[2] = 3; characters_to_list_trap_2_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; characters_to_list_trap_2_exp.code[4] = - (Eterm) &characters_to_list_trap_2; + (UWord) &characters_to_list_trap_2; memset(&characters_to_list_trap_3_exp, 0, sizeof(Export)); @@ -127,9 +127,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_3",25); characters_to_list_trap_3_exp.code[2] = 3; characters_to_list_trap_3_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; characters_to_list_trap_3_exp.code[4] = - (Eterm) &characters_to_list_trap_3; + (UWord) &characters_to_list_trap_3; memset(&characters_to_list_trap_4_exp, 0, sizeof(Export)); characters_to_list_trap_4_exp.address = @@ -139,9 +139,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_4",25); characters_to_list_trap_4_exp.code[2] = 1; characters_to_list_trap_4_exp.code[3] = - (Eterm) em_apply_bif; + (UWord) em_apply_bif; characters_to_list_trap_4_exp.code[4] = - (Eterm) &characters_to_list_trap_4; + (UWord) &characters_to_list_trap_4; c_to_b_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_binary_int,2); c_to_l_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_list_int,2); diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h index 1b61bca440..235bd7931d 100644 --- a/erts/emulator/beam/erl_vm.h +++ b/erts/emulator/beam/erl_vm.h @@ -139,8 +139,12 @@ #define HeapWordsLeft(p) (HEAP_LIMIT(p) - HEAP_TOP(p)) #if defined(DEBUG) || defined(CHECK_FOR_HOLES) +#if HALFWORD_HEAP +# define ERTS_HOLE_MARKER (0xaf5e78ccU) +#else # define ERTS_HOLE_MARKER (((0xaf5e78ccUL << 24) << 8) | 0xaf5e78ccUL) #endif +#endif /* * Allocate heap memory on the ordinary heap, NEVER in a heap diff --git a/erts/emulator/beam/error.h b/erts/emulator/beam/error.h index 4930def4ed..8f95140864 100644 --- a/erts/emulator/beam/error.h +++ b/erts/emulator/beam/error.h @@ -187,10 +187,10 @@ extern Eterm exception_tag[NUMBER_EXC_TAGS]; struct StackTrace { Eterm header; /* bignum header - must be first in struct */ Eterm freason; /* original exception reason is saved in the struct */ - Eterm* pc; - Eterm* current; + UWord* pc; + UWord* current; int depth; /* number of saved pointers in trace[] */ - Eterm *trace[1]; /* varying size - must be last in struct */ + UWord *trace[1]; /* varying size - must be last in struct */ }; #endif /* __ERROR_H__ */ diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c index 271b40cf0f..c39f610924 100644 --- a/erts/emulator/beam/export.c +++ b/erts/emulator/beam/export.c @@ -46,8 +46,8 @@ static erts_smp_rwmtx_t export_table_lock; /* Locks the secondary export table. #define export_init_lock() erts_smp_rwmtx_init(&export_table_lock, \ "export_tab") -extern Eterm* em_call_error_handler; -extern Uint* em_call_traced_function; +extern UWord* em_call_error_handler; +extern UWord* em_call_traced_function; void export_info(int to, void *to_arg) @@ -93,7 +93,7 @@ export_alloc(Export* tmpl) obj->code[2] = tmpl->code[2]; obj->slot.index = -1; obj->address = obj->code+3; - obj->code[3] = (Eterm) em_call_error_handler; + obj->code[3] = (UWord) em_call_error_handler; obj->code[4] = 0; obj->match_prog_set = NULL; return obj; @@ -140,7 +140,7 @@ init_export_table(void) Export* erts_find_export_entry(Eterm m, Eterm f, unsigned int a) { - HashValue hval = EXPORT_HASH(m, f, a); + HashValue hval = EXPORT_HASH((UWord) m, (UWord) f, (UWord) a); int ix; HashBucket* b; @@ -185,7 +185,7 @@ erts_find_function(Eterm m, Eterm f, unsigned int a) ep = hash_get(&export_table.htable, (void*) &e); if (ep != NULL && ep->address == ep->code+3 && - ep->code[3] != (Uint) em_call_traced_function) { + ep->code[3] != (UWord) em_call_traced_function) { ep = NULL; } return ep; diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h index cd6af6dd85..57b6a7afcf 100644 --- a/erts/emulator/beam/export.h +++ b/erts/emulator/beam/export.h @@ -52,7 +52,11 @@ typedef struct export * on_load function that has not been run yet. * Otherwise: 0. */ +#if HALFWORD_HEAP + UWord code[5]; +#else Eterm code[5]; +#endif } Export; @@ -74,6 +78,6 @@ Export *export_get(Export*); #include "beam_load.h" /* For em_* extern declarations */ #define ExportIsBuiltIn(EntryPtr) \ (((EntryPtr)->address == (EntryPtr)->code + 3) && \ - ((EntryPtr)->code[3] == (Uint) em_apply_bif)) + ((EntryPtr)->code[3] == (UWord) em_apply_bif)) #endif diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index f7b498e414..d6cb6efb79 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -1489,20 +1489,28 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete static byte* enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) { - DECLARE_ESTACK(s); + DECLARE_WSTACK(s); Uint n; Uint i; Uint j; Uint* ptr; Eterm val; FloatDef f; +#if HALFWORD_HEAP + UWord wobj; +#endif + goto L_jump_start; outer_loop: - while (!ESTACK_ISEMPTY(s)) { - obj = ESTACK_POP(s); - switch (val = ESTACK_POP(s)) { + while (!WSTACK_ISEMPTY(s)) { +#if HALFWORD_HEAP + obj = (Eterm) (wobj = WSTACK_POP(s)); +#else + obj = WSTACK_POP(s); +#endif + switch (val = WSTACK_POP(s)) { case ENC_TERM: break; case ENC_ONE_CONS: @@ -1513,29 +1521,40 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) obj = CAR(cons); tl = CDR(cons); - ESTACK_PUSH(s, is_list(tl) ? ENC_ONE_CONS : ENC_TERM); - ESTACK_PUSH(s, tl); + WSTACK_PUSH(s, is_list(tl) ? ENC_ONE_CONS : ENC_TERM); + WSTACK_PUSH(s, tl); } break; case ENC_PATCH_FUN_SIZE: { +#if HALFWORD_HEAP + byte* size_p = (byte *) wobj; +#else byte* size_p = (byte *) obj; - +#endif put_int32(ep - size_p, size_p); } goto outer_loop; case ENC_LAST_ARRAY_ELEMENT: { +#if HALFWORD_HEAP + Eterm* ptr = (Eterm *) wobj; +#else Eterm* ptr = (Eterm *) obj; +#endif obj = *ptr; } break; default: /* ENC_LAST_ARRAY_ELEMENT+1 and upwards */ { +#if HALFWORD_HEAP + Eterm* ptr = (Eterm *) wobj; +#else Eterm* ptr = (Eterm *) obj; +#endif obj = *ptr++; - ESTACK_PUSH(s, val-1); - ESTACK_PUSH(s, (Eterm) ptr); + WSTACK_PUSH(s, val-1); + WSTACK_PUSH(s, (UWord) ptr); } break; } @@ -1665,8 +1684,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) ep += 4; } if (i > 0) { - ESTACK_PUSH(s, ENC_LAST_ARRAY_ELEMENT+i-1); - ESTACK_PUSH(s, (Eterm) ptr); + WSTACK_PUSH(s, ENC_LAST_ARRAY_ELEMENT+i-1); + WSTACK_PUSH(s, (UWord) ptr); } break; @@ -1744,7 +1763,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) } case EXPORT_DEF: { - Export* exp = (Export *) (export_val(obj))[1]; + Export* exp = *((Export **) (export_val(obj) + 1)); if ((dflags & DFLAG_EXPORT_PTR_TAG) != 0) { *ep++ = EXPORT_EXT; ep = enc_atom(acmp, exp->code[0], ep, dflags); @@ -1773,8 +1792,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) int ei; *ep++ = NEW_FUN_EXT; - ESTACK_PUSH(s, ENC_PATCH_FUN_SIZE); - ESTACK_PUSH(s, (Eterm) ep); /* Position for patching in size */ + WSTACK_PUSH(s, ENC_PATCH_FUN_SIZE); + WSTACK_PUSH(s, (UWord) ep); /* Position for patching in size */ ep += 4; *ep = funp->arity; ep += 1; @@ -1791,8 +1810,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) fun_env: for (ei = funp->num_free-1; ei > 0; ei--) { - ESTACK_PUSH(s, ENC_TERM); - ESTACK_PUSH(s, funp->env[ei]); + WSTACK_PUSH(s, ENC_TERM); + WSTACK_PUSH(s, (UWord) funp->env[ei]); } if (funp->num_free != 0) { obj = funp->env[0]; @@ -1835,7 +1854,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) break; } } - DESTROY_ESTACK(s); + DESTROY_WSTACK(s); return ep; } @@ -1959,7 +1978,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et while (next != NULL) { objp = next; - next = (Eterm *) (*objp); + next = (Eterm *) EXPAND_POINTER(*objp); switch (*ep++) { case INTEGER_EXT: @@ -1967,7 +1986,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et Sint sn = get_int32(ep); ep += 4; -#if defined(ARCH_64) +#if defined(ARCH_64) && !HALFWORD_HEAP *objp = make_small(sn); #else if (MY_IS_SSMALL(sn)) { @@ -2064,7 +2083,7 @@ dec_term_atom_common: hp += n; objp = hp - 1; while (n-- > 0) { - objp[0] = (Eterm) next; + objp[0] = (Eterm) COMPRESS_POINTER(next); next = objp; objp--; } @@ -2082,12 +2101,12 @@ dec_term_atom_common: *objp = make_list(hp); hp += 2*n; objp = hp - 2; - objp[0] = (Eterm) (objp+1); - objp[1] = (Eterm) next; + objp[0] = (Eterm) COMPRESS_POINTER((objp+1)); + objp[1] = (Eterm) COMPRESS_POINTER(next); next = objp; objp -= 2; while (--n > 0) { - objp[0] = (Eterm) next; + objp[0] = (Eterm) COMPRESS_POINTER(next); objp[1] = make_list(objp + 2); next = objp; objp -= 2; @@ -2242,7 +2261,7 @@ dec_term_atom_common: if(node == erts_this_node) { RefThing *rtp = (RefThing *) hp; hp += REF_THING_HEAD_SIZE; -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP rtp->header = make_ref_thing_header(ref_words/2 + 1); #else rtp->header = make_ref_thing_header(ref_words); @@ -2253,7 +2272,7 @@ dec_term_atom_common: ExternalThing *etp = (ExternalThing *) hp; hp += EXTERNAL_THING_HEAD_SIZE; -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP etp->header = make_external_ref_header(ref_words/2 + 1); #else etp->header = make_external_ref_header(ref_words); @@ -2266,7 +2285,7 @@ dec_term_atom_common: } ref_num = (Uint32 *) hp; -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP *(ref_num++) = ref_words /* 32-bit arity */; #endif ref_num[0] = r0; @@ -2274,7 +2293,7 @@ dec_term_atom_common: ref_num[i] = get_int32(ep); ep += 4; } -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP if ((1 + ref_words) % 2) ref_num[ref_words] = 0; hp += ref_words/2 + 1; @@ -2401,7 +2420,12 @@ dec_term_atom_common: } *objp = make_export(hp); *hp++ = HEADER_EXPORT; +#if HALFWORD_HEAP + *((UWord *) (UWord) hp) = (UWord) erts_export_get_or_make_stub(mod, name, arity); + hp += 2; +#else *hp++ = (Eterm) erts_export_get_or_make_stub(mod, name, arity); +#endif break; } break; @@ -2477,11 +2501,11 @@ dec_term_atom_common: /* Environment */ for (i = num_free-1; i >= 0; i--) { - funp->env[i] = (Eterm) next; + funp->env[i] = (Eterm) COMPRESS_POINTER(next); next = funp->env + i; } /* Creator */ - funp->creator = (Eterm) next; + funp->creator = (Eterm) COMPRESS_POINTER(next); next = &(funp->creator); break; } @@ -2552,7 +2576,7 @@ dec_term_atom_common: /* Environment */ for (i = num_free-1; i >= 0; i--) { - funp->env[i] = (Eterm) next; + funp->env[i] = (Eterm) COMPRESS_POINTER(next); next = funp->env + i; } break; @@ -2583,26 +2607,35 @@ dec_term_atom_common: static Uint encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) { - DECLARE_ESTACK(s); + DECLARE_WSTACK(s); Uint m, i, arity; Uint result = 0; +#if HALFWORD_HEAP + UWord wobj; +#endif goto L_jump_start; outer_loop: - while (!ESTACK_ISEMPTY(s)) { - obj = ESTACK_POP(s); - + while (!WSTACK_ISEMPTY(s)) { +#if HALFWORD_HEAP + obj = (Eterm) (wobj = WSTACK_POP(s)); +#else + obj = WSTACK_POP(s); +#endif handle_popped_obj: - if (is_CP(obj)) { + if (is_CP(obj)) { /* Does not look for CP, looks for "no tag" */ +#if HALFWORD_HEAP + Eterm* ptr = (Eterm *) wobj; +#else Eterm* ptr = (Eterm *) obj; - +#endif /* * Pointer into a tuple. */ obj = *ptr--; if (!is_header(obj)) { - ESTACK_PUSH(s, (Eterm)ptr); + WSTACK_PUSH(s, (UWord)ptr); } else { /* Reached tuple header */ ASSERT(header_is_arityval(obj)); @@ -2614,7 +2647,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) tl = CDR(cons); obj = CAR(cons); - ESTACK_PUSH(s, tl); + WSTACK_PUSH(s, tl); } else if (is_nil(obj)) { result++; goto outer_loop; @@ -2703,7 +2736,11 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) result += 1 + 4; } ptr += arity; +#if HALFWORD_HEAP + obj = (Eterm) (wobj = (UWord) ptr); +#else obj = (Eterm) ptr; +#endif goto handle_popped_obj; } break; @@ -2745,14 +2782,14 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) if (is_not_list(obj)) { /* Push any non-list terms on the stack */ - ESTACK_PUSH(s, obj); + WSTACK_PUSH(s, obj); } else { /* Lists must be handled specially. */ if ((m = is_string(obj)) && (m < MAX_STRING_LEN)) { result += m + 2 + 1; } else { result += 5; - ESTACK_PUSH(s, obj); + WSTACK_PUSH(s, obj); } } } @@ -2765,8 +2802,12 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) case EXPORT_DEF: { - Export* ep = (Export *) (export_val(obj))[1]; + Export* ep = *((Export **) (export_val(obj) + 1)); +#if HALFWORD_HEAP + result += 2; +#else result += 1; +#endif result += encode_size_struct2(acmp, ep->code[0], dflags); result += encode_size_struct2(acmp, ep->code[1], dflags); result += encode_size_struct2(acmp, make_small(ep->code[2]), dflags); @@ -2779,7 +2820,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) } } - DESTROY_ESTACK(s); + DESTROY_WSTACK(s); return result; } @@ -2891,7 +2932,7 @@ decoded_size(byte *ep, byte* endp, int no_refc_bins) ep += 2; atom_extra_skip = 1 + 4*id_words; /* In case it is an external ref */ -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP heap_size += EXTERNAL_THING_HEAD_SIZE + id_words/2 + 1; #else heap_size += EXTERNAL_THING_HEAD_SIZE + id_words; diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h index eada6d4f27..db86b4d796 100644 --- a/erts/emulator/beam/external.h +++ b/erts/emulator/beam/external.h @@ -212,7 +212,7 @@ erts_dist_ext_trailer(ErtsDistExternal *edep) { void *res = (void *) (edep->ext_endp + ERTS_WORD_ALIGN_PAD_SZ(edep->ext_endp)); - ASSERT((((Uint) res) % sizeof(Uint)) == 0); + ASSERT((((UWord) res) % sizeof(Uint)) == 0); return res; } diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 03e97a0ce4..2afb6775b5 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -403,7 +403,7 @@ extern Eterm erts_ddll_monitor_driver(Process *p, /* Add fields in ERTS_INTERNAL_BINARY_FIELDS, otherwise the drivers crash */ #define ERTS_INTERNAL_BINARY_FIELDS \ - Uint flags; \ + UWord flags; \ erts_refc_t refc; \ ERTS_BINARY_STRUCT_ALIGNMENT @@ -723,6 +723,60 @@ do { \ #define ESTACK_POP(s) (*(--ESTK_CONCAT(s,_sp))) +void erl_grow_wstack(UWord** start, UWord** sp, UWord** end); +#define WSTK_CONCAT(a,b) a##b +#define WSTK_SUBSCRIPT(s,i) *((UWord *)((byte *)WSTK_CONCAT(s,_start) + (i))) +#define DEF_WSTACK_SIZE (16) + +#define DECLARE_WSTACK(s) \ + UWord WSTK_CONCAT(s,_default_stack)[DEF_WSTACK_SIZE]; \ + UWord* WSTK_CONCAT(s,_start) = WSTK_CONCAT(s,_default_stack); \ + UWord* WSTK_CONCAT(s,_sp) = WSTK_CONCAT(s,_start); \ + UWord* WSTK_CONCAT(s,_end) = WSTK_CONCAT(s,_start) + DEF_WSTACK_SIZE + +#define DESTROY_WSTACK(s) \ +do { \ + if (WSTK_CONCAT(s,_start) != WSTK_CONCAT(s,_default_stack)) { \ + erts_free(ERTS_ALC_T_ESTACK, WSTK_CONCAT(s,_start)); \ + } \ +} while(0) + +#define WSTACK_PUSH(s, x) \ +do { \ + if (WSTK_CONCAT(s,_sp) == WSTK_CONCAT(s,_end)) { \ + erl_grow_wstack(&WSTK_CONCAT(s,_start), &WSTK_CONCAT(s,_sp), \ + &WSTK_CONCAT(s,_end)); \ + } \ + *WSTK_CONCAT(s,_sp)++ = (x); \ +} while(0) + +#define WSTACK_PUSH2(s, x, y) \ +do { \ + if (WSTK_CONCAT(s,_sp) > WSTK_CONCAT(s,_end) - 2) { \ + erl_grow_wstack(&WSTK_CONCAT(s,_start), &WSTK_CONCAT(s,_sp), \ + &WSTK_CONCAT(s,_end)); \ + } \ + *WSTK_CONCAT(s,_sp)++ = (x); \ + *WSTK_CONCAT(s,_sp)++ = (y); \ +} while(0) + +#define WSTACK_PUSH3(s, x, y, z) \ +do { \ + if (WSTK_CONCAT(s,_sp) > WSTK_CONCAT(s,_end) - 3) { \ + erl_grow_wstack(&WSTK_CONCAT(s,_start), &WSTK_CONCAT(s,_sp), \ + &WSTK_CONCAT(s,_end)); \ + } \ + *WSTK_CONCAT(s,_sp)++ = (x); \ + *WSTK_CONCAT(s,_sp)++ = (y); \ + *WSTK_CONCAT(s,_sp)++ = (z); \ +} while(0) + +#define WSTACK_COUNT(s) (WSTK_CONCAT(s,_sp) - WSTK_CONCAT(s,_start)) + +#define WSTACK_ISEMPTY(s) (WSTK_CONCAT(s,_sp) == WSTK_CONCAT(s,_start)) +#define WSTACK_POP(s) (*(--WSTK_CONCAT(s,_sp))) + + /* port status flags */ #define ERTS_PORT_SFLG_CONNECTED ((Uint32) (1 << 0)) @@ -802,7 +856,7 @@ void erts_system_profile_clear(Process *c_p); int erts_load_module(Process *c_p, ErtsProcLocks c_p_locks, Eterm group_leader, Eterm* mod, byte* code, int size); void init_load(void); -Eterm* find_function_from_pc(Eterm* pc); +UWord* find_function_from_pc(UWord* pc); Eterm erts_module_info_0(Process* p, Eterm module); Eterm erts_module_info_1(Process* p, Eterm module, Eterm what); Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info); @@ -1171,7 +1225,7 @@ erts_smp_port_unlock(Port *prt) ERTS_INVALID_PORT_OPT((PP), (ID), ERTS_PORT_SFLGS_INVALID_TRACER_LOOKUP) #define ERTS_PORT_SCHED_ID(P, ID) \ - ((Uint) erts_prtsd_set((P), ERTS_PSD_SCHED_ID, (void *) (ID))) + ((Uint) (UWord) erts_prtsd_set((P), ERTS_PSD_SCHED_ID, (void *) (UWord) (ID))) #ifdef ERTS_SMP Port *erts_de2port(DistEntry *, Process *, ErtsProcLocks); @@ -1463,6 +1517,7 @@ Uint32 make_hash(Eterm); Eterm erts_bld_atom(Uint **hpp, Uint *szp, char *str); Eterm erts_bld_uint(Uint **hpp, Uint *szp, Uint ui); +Eterm erts_bld_uword(Uint **hpp, Uint *szp, UWord uw); Eterm erts_bld_uint64(Uint **hpp, Uint *szp, Uint64 ui64); Eterm erts_bld_sint64(Uint **hpp, Uint *szp, Sint64 si64); Eterm erts_bld_cons(Uint **hpp, Uint *szp, Eterm car, Eterm cdr); @@ -1554,12 +1609,12 @@ void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *); void erts_send_sys_msg_proc(Eterm, Eterm, Eterm, ErlHeapFragment *); void trace_send(Process*, Eterm, Eterm); void trace_receive(Process*, Eterm); -Uint32 erts_call_trace(Process *p, Eterm mfa[], Binary *match_spec, Eterm* args, +Uint32 erts_call_trace(Process *p, UWord mfa[], Binary *match_spec, Eterm* args, int local, Eterm *tracer_pid); -void erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid); -void erts_trace_exception(Process* p, Eterm mfa[], Eterm class, Eterm value, +void erts_trace_return(Process* p, UWord* fi, Eterm retval, Eterm *tracer_pid); +void erts_trace_exception(Process* p, UWord mfa[], Eterm class, Eterm value, Eterm *tracer); -void erts_trace_return_to(Process *p, Uint *pc); +void erts_trace_return_to(Process *p, UWord *pc); void trace_sched(Process*, Eterm); void trace_proc(Process*, Process*, Eterm, Eterm); void trace_proc_spawn(Process*, Eterm pid, Eterm mod, Eterm func, Eterm args); @@ -1589,7 +1644,7 @@ Uint erts_trace_flag2bit(Eterm flag); int erts_trace_flags(Eterm List, Uint *pMask, Eterm *pTracer, int *pCpuTimestamp); Eterm erts_bif_trace(int bif_index, Process* p, - Eterm arg1, Eterm arg2, Eterm arg3, Uint *I); + Eterm arg1, Eterm arg2, Eterm arg3, UWord *I); #ifdef ERTS_SMP void erts_send_pending_trace_msgs(ErtsSchedulerData *esdp); @@ -1606,7 +1661,7 @@ void bin_write(int, void*, byte*, int); int intlist_to_buf(Eterm, char*, int); /* most callers pass plain char*'s */ struct Sint_buf { -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP char s[22]; #else char s[12]; diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index ac25eb9d5c..f3062c894c 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -3994,7 +3994,7 @@ drv_cancel_timer(Port *prt) erts_port_task_abort(prt->id, &prt->timeout_task); } -int driver_set_timer(ErlDrvPort ix, Uint t) +int driver_set_timer(ErlDrvPort ix, UWord t) { Port* prt = erts_drvport2port(ix); @@ -4053,12 +4053,16 @@ driver_read_timer(ErlDrvPort ix, unsigned long* t) int driver_get_now(ErlDrvNowData *now_data) { + Uint mega,secs,micro ERTS_SMP_CHK_NO_PROC_LOCKS; if (now_data == NULL) { return -1; } - get_now(&(now_data->megasecs),&(now_data->secs),&(now_data->microsecs)); + get_now(&mega,&secs,µ); + now_data->megasecs = (unsigned long) mega; + now_data->secs = (unsigned long) secs; + now_data->microsecs = (unsigned long) micro; return 0; } diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h index 87d13b3607..a09d5985db 100644 --- a/erts/emulator/beam/module.h +++ b/erts/emulator/beam/module.h @@ -29,8 +29,8 @@ typedef struct erl_module { IndexSlot slot; /* Must be located at top of struct! */ int module; /* Atom index for module (not tagged). */ - Eterm* code; - Eterm* old_code; + UWord* code; + UWord* old_code; int code_length; /* Length of loaded code in bytes. */ int old_code_length; /* Length of old loaded code in bytes */ unsigned catches, old_catches; diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 4b949523fa..b48b147953 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -20,6 +20,7 @@ #ifndef __SYS_H__ #define __SYS_H__ + #if defined(VALGRIND) && !defined(NO_FPE_SIGNALS) # define NO_FPE_SIGNALS #endif @@ -233,6 +234,10 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...)); ** UInt: An unsigned integer exactly as large as an Eterm. ** SInt: A signed integer exactly as large as an eterm and therefor large ** enough to hold the return value of the signed_val() macro. +** UWord: An unsigned integer at least as large as a void * and also as large +** or larger than an Eterm +** SWord: A signed integer at least as large as a void * and also as large +** or larger than an Eterm ** Uint32: An unsigned integer of 32 bits exactly ** Sint32: A signed integer of 32 bits exactly ** Uint16: An unsigned integer of 16 bits exactly @@ -253,11 +258,43 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...)); #else #error Neither 32 nor 64 bit architecture #endif +#ifdef ARCH_64 +# ifdef HALFWORD_HEAP_EMULATOR +# define HALFWORD_HEAP 1 +# define HALFWORD_ASSERT 1 +# else +# define HALFWORD_HEAP 0 +# define HALFWORD_ASSERT 1 +# endif +#endif #if SIZEOF_VOID_P != SIZEOF_SIZE_T #error sizeof(void*) != sizeof(size_t) #endif +#if HALFWORD_HEAP + +#if SIZEOF_INT == 4 +typedef unsigned int Eterm; +typedef unsigned int Uint; +typedef int Sint; +#define ERTS_SIZEOF_ETERM SIZEOF_INT +#else +#error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint' +#endif + +#if SIZEOF_VOID_P == SIZEOF_LONG +typedef unsigned long UWord; +typedef long SWord; +#elif SIZEOF_VOID_P == SIZEOF_INT +typedef unsigned int UWord; +typedef int SWord; +#else +#error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint' +#endif + +#else /* !HALFWORD_HEAP */ + #if SIZEOF_VOID_P == SIZEOF_LONG typedef unsigned long Eterm; typedef unsigned long Uint; @@ -272,6 +309,11 @@ typedef int Sint; #error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint' #endif +typedef Uint UWord; +typedef Sint SWord; + +#endif /* HALFWORD_HEAP */ + #ifndef HAVE_INT64 #if SIZEOF_LONG == 8 #define HAVE_INT64 1 diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index f59fbbee33..51c12a0b69 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -204,6 +204,25 @@ erl_grow_stack(Eterm** start, Eterm** sp, Eterm** end) *end = *start + new_size; *sp = *start + sp_offs; } +/* + * Helper function for the ESTACK macros defined in global.h. + */ +void +erl_grow_wstack(UWord** start, UWord** sp, UWord** end) +{ + Uint old_size = (*end - *start); + Uint new_size = old_size * 2; + Uint sp_offs = *sp - *start; + if (new_size > 2 * DEF_ESTACK_SIZE) { + *start = erts_realloc(ERTS_ALC_T_ESTACK, (void *) *start, new_size*sizeof(UWord)); + } else { + UWord* new_ptr = erts_alloc(ERTS_ALC_T_ESTACK, new_size*sizeof(UWord)); + sys_memcpy(new_ptr, *start, old_size*sizeof(UWord)); + *start = new_ptr; + } + *end = *start + new_size; + *sp = *start + sp_offs; +} /* CTYPE macros */ @@ -354,6 +373,31 @@ erts_bld_uint(Uint **hpp, Uint *szp, Uint ui) return res; } +/* + * Erts_bld_uword is more or less similar to erts_bld_uint, but a pointer + * can safely be passed. + */ + +Eterm +erts_bld_uword(Uint **hpp, Uint *szp, UWord uw) +{ + Eterm res = THE_NON_VALUE; + if (IS_USMALL(0, uw)) { + if (hpp) + res = make_small((Uint) uw); + } + else { + if (szp) + *szp += BIG_UWORD_HEAP_SIZE(uw); + if (hpp) { + res = uword_to_big(uw, *hpp); + *hpp += BIG_UWORD_HEAP_SIZE(uw); + } + } + return res; +} + + Eterm erts_bld_uint64(Uint **hpp, Uint *szp, Uint64 ui64) { @@ -711,7 +755,7 @@ hash_binary_bytes(Eterm bin, Uint sz, Uint32 hash) Uint32 make_hash(Eterm term_arg) { - DECLARE_ESTACK(stack); + DECLARE_WSTACK(stack); Eterm term = term_arg; Eterm hash = 0; unsigned op; @@ -770,7 +814,7 @@ tail_recur: Uint y2 = y1 < 0 ? -(Uint)y1 : y1; UINT32_HASH_STEP(y2, FUNNY_NUMBER2); -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP if (y2 >> 32) UINT32_HASH_STEP(y2 >> 32, FUNNY_NUMBER2); #endif @@ -787,7 +831,7 @@ tail_recur: } case EXPORT_DEF: { - Export* ep = (Export *) (export_val(term))[1]; + Export* ep = *((Export **) (export_val(term) + 1)); hash = hash * FUNNY_NUMBER11 + ep->code[2]; hash = hash*FUNNY_NUMBER1 + @@ -809,7 +853,7 @@ tail_recur: hash = hash*FUNNY_NUMBER2 + funp->fe->old_uniq; if (num_free > 0) { if (num_free > 1) { - ESTACK_PUSH3(stack, (Eterm) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP); + WSTACK_PUSH3(stack, (UWord) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP); } term = funp->env[0]; goto tail_recur; @@ -837,9 +881,9 @@ tail_recur: } case MAKE_HASH_CDR_PRE_OP: - term = ESTACK_POP(stack); + term = (Eterm) WSTACK_POP(stack); if (is_not_list(term)) { - ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP); + WSTACK_PUSH(stack, (UWord) MAKE_HASH_CDR_POST_OP); goto tail_recur; } /* fall through */ @@ -854,13 +898,13 @@ tail_recur: hash = hash*FUNNY_NUMBER2 + unsigned_val(*list); if (is_not_list(CDR(list))) { - ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP); + WSTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP); term = CDR(list); goto tail_recur; } list = list_val(CDR(list)); } - ESTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP); + WSTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP); term = CAR(list); goto tail_recur; } @@ -888,7 +932,7 @@ tail_recur: } d = BIG_DIGIT(ptr, k); k = sizeof(ErtsDigit); -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP if (!(d >> 32)) k /= 2; #endif @@ -904,21 +948,21 @@ tail_recur: Eterm* ptr = tuple_val(term); Uint arity = arityval(*ptr); - ESTACK_PUSH3(stack, arity, (Eterm)(ptr+1), arity); + WSTACK_PUSH3(stack, (UWord) arity, (UWord)(ptr+1), (UWord) arity); op = MAKE_HASH_TUPLE_OP; }/*fall through*/ case MAKE_HASH_TUPLE_OP: case MAKE_HASH_FUN_OP: { - Uint i = ESTACK_POP(stack); - Eterm* ptr = (Eterm*) ESTACK_POP(stack); + Uint i = (Uint) WSTACK_POP(stack); + Eterm* ptr = (Eterm*) WSTACK_POP(stack); if (i != 0) { term = *ptr; - ESTACK_PUSH3(stack, (Eterm)(ptr+1), i-1, op); + WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op); goto tail_recur; } if (op == MAKE_HASH_TUPLE_OP) { - Uint32 arity = ESTACK_POP(stack); + Uint32 arity = (Uint32) WSTACK_POP(stack); hash = hash*FUNNY_NUMBER9 + arity; } break; @@ -928,10 +972,10 @@ tail_recur: erl_exit(1, "Invalid tag in make_hash(0x%X,0x%X)\n", term, op); return 0; } - if (ESTACK_ISEMPTY(stack)) break; - op = ESTACK_POP(stack); + if (WSTACK_ISEMPTY(stack)) break; + op = WSTACK_POP(stack); } - DESTROY_ESTACK(stack); + DESTROY_WSTACK(stack); return hash; #undef UINT32_HASH_STEP @@ -1123,7 +1167,7 @@ make_hash2(Eterm term) break; case EXPORT_SUBTAG: { - Export* ep = (Export *) (export_val(term))[1]; + Export* ep = *((Export **) (export_val(term) + 1)); UINT32_HASH_2 (ep->code[2], @@ -1333,7 +1377,7 @@ make_hash2(Eterm term) Uint32 make_broken_hash(Eterm term) { Uint32 hash = 0; - DECLARE_ESTACK(stack); + DECLARE_WSTACK(stack); unsigned op; tail_recur: op = tag_val_def(term); @@ -1347,7 +1391,7 @@ tail_recur: (atom_tab(atom_val(term))->slot.bucket.hvalue); break; case SMALL_DEF: -#ifdef ARCH_64 +#if defined(ARCH_64) && !HALFWORD_HEAP { Sint y1 = signed_val(term); Uint y2 = y1 < 0 ? -(Uint)y1 : y1; @@ -1400,7 +1444,7 @@ tail_recur: case EXPORT_DEF: { - Export* ep = (Export *) (export_val(term))[1]; + Export* ep = *((Export **) (export_val(term) + 1)); hash = hash * FUNNY_NUMBER11 + ep->code[2]; hash = hash*FUNNY_NUMBER1 + @@ -1422,7 +1466,7 @@ tail_recur: hash = hash*FUNNY_NUMBER2 + funp->fe->old_uniq; if (num_free > 0) { if (num_free > 1) { - ESTACK_PUSH3(stack, (Eterm) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP); + WSTACK_PUSH3(stack, (UWord) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP); } term = funp->env[0]; goto tail_recur; @@ -1457,16 +1501,17 @@ tail_recur: break; case MAKE_HASH_CDR_PRE_OP: - term = ESTACK_POP(stack); + term = (Eterm) WSTACK_POP(stack); if (is_not_list(term)) { - ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP); + WSTACK_PUSH(stack, (UWord) MAKE_HASH_CDR_POST_OP); goto tail_recur; } /*fall through*/ case LIST_DEF: { Eterm* list = list_val(term); - ESTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP); + WSTACK_PUSH2(stack, (UWord) CDR(list), + (UWord) MAKE_HASH_CDR_PRE_OP); term = CAR(list); goto tail_recur; } @@ -1539,21 +1584,21 @@ tail_recur: Eterm* ptr = tuple_val(term); Uint arity = arityval(*ptr); - ESTACK_PUSH3(stack, arity, (Eterm)(ptr+1), arity); + WSTACK_PUSH3(stack, (UWord) arity, (UWord) (ptr+1), (UWord) arity); op = MAKE_HASH_TUPLE_OP; }/*fall through*/ case MAKE_HASH_TUPLE_OP: case MAKE_HASH_FUN_OP: { - Uint i = ESTACK_POP(stack); - Eterm* ptr = (Eterm*) ESTACK_POP(stack); + Uint i = (Uint) WSTACK_POP(stack); + Eterm* ptr = (Eterm*) WSTACK_POP(stack); if (i != 0) { term = *ptr; - ESTACK_PUSH3(stack, (Eterm)(ptr+1), i-1, op); + WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op); goto tail_recur; } if (op == MAKE_HASH_TUPLE_OP) { - Uint32 arity = ESTACK_POP(stack); + Uint32 arity = (UWord) WSTACK_POP(stack); hash = hash*FUNNY_NUMBER9 + arity; } break; @@ -1563,11 +1608,11 @@ tail_recur: erl_exit(1, "Invalid tag in make_broken_hash\n"); return 0; } - if (ESTACK_ISEMPTY(stack)) break; - op = ESTACK_POP(stack); + if (WSTACK_ISEMPTY(stack)) break; + op = (Uint) WSTACK_POP(stack); } - DESTROY_ESTACK(stack); + DESTROY_WSTACK(stack); return hash; #undef MAKE_HASH_TUPLE_OP @@ -1870,7 +1915,7 @@ erts_destroy_tmp_dsbuf(erts_dsprintf_buf_t *dsbufp) int eq(Eterm a, Eterm b) { - DECLARE_ESTACK(stack); + DECLARE_WSTACK(stack); Sint sz; Eterm* aa; Eterm* bb; @@ -1888,7 +1933,7 @@ tailrecur_ne: Eterm atmp = CAR(aval); Eterm btmp = CAR(bval); if (atmp != btmp) { - ESTACK_PUSH2(stack,CDR(bval),CDR(aval)); + WSTACK_PUSH2(stack,(UWord) CDR(bval),(UWord) CDR(aval)); a = atmp; b = btmp; goto tailrecur_ne; @@ -1958,8 +2003,8 @@ tailrecur_ne: case EXPORT_SUBTAG: { if (is_export(b)) { - Export* a_exp = (Export *) (export_val(a))[1]; - Export* b_exp = (Export *) (export_val(b))[1]; + Export* a_exp = *((Export **) (export_val(a) + 1)); + Export* b_exp = *((Export **) (export_val(b) + 1)); if (a_exp == b_exp) goto pop_next; } break; /* not equal */ @@ -2131,32 +2176,32 @@ term_array: /* arrays in 'aa' and 'bb', length in 'sz' */ goto not_equal; } if (i > 1) { /* push the rest */ - ESTACK_PUSH3(stack, i-1, (Eterm)(bp+1), - ((Eterm)(ap+1)) | TAG_PRIMARY_HEADER); + WSTACK_PUSH3(stack, i-1, (UWord)(bp+1), + ((UWord)(ap+1)) | TAG_PRIMARY_HEADER); /* We (ab)use TAG_PRIMARY_HEADER to recognize a term_array */ } goto tailrecur_ne; } pop_next: - if (!ESTACK_ISEMPTY(stack)) { - Eterm something = ESTACK_POP(stack); - if (primary_tag(something) == TAG_PRIMARY_HEADER) { /* a term_array */ + if (!WSTACK_ISEMPTY(stack)) { + UWord something = WSTACK_POP(stack); + if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */ aa = (Eterm*) something; - bb = (Eterm*) ESTACK_POP(stack); - sz = ESTACK_POP(stack); + bb = (Eterm*) WSTACK_POP(stack); + sz = WSTACK_POP(stack); goto term_array; } a = something; - b = ESTACK_POP(stack); + b = WSTACK_POP(stack); goto tailrecur; } - DESTROY_ESTACK(stack); + DESTROY_WSTACK(stack); return 1; not_equal: - DESTROY_ESTACK(stack); + DESTROY_WSTACK(stack); return 0; } @@ -2211,7 +2256,7 @@ static int cmp_atoms(Eterm a, Eterm b) Sint cmp(Eterm a, Eterm b) { - DECLARE_ESTACK(stack); + DECLARE_WSTACK(stack); Eterm* aa; Eterm* bb; int i; @@ -2328,7 +2373,7 @@ tailrecur_ne: Eterm atmp = CAR(aa); Eterm btmp = CAR(bb); if (atmp != btmp) { - ESTACK_PUSH2(stack,CDR(bb),CDR(aa)); + WSTACK_PUSH2(stack,(UWord) CDR(bb),(UWord) CDR(aa)); a = atmp; b = btmp; goto tailrecur_ne; @@ -2393,8 +2438,8 @@ tailrecur_ne: a_tag = EXPORT_DEF; goto mixed_types; } else { - Export* a_exp = (Export *) (export_val(a))[1]; - Export* b_exp = (Export *) (export_val(b))[1]; + Export* a_exp = *((Export **) (export_val(a) + 1)); + Export* b_exp = *((Export **) (export_val(b) + 1)); if ((j = cmp_atoms(a_exp->code[0], b_exp->code[0])) != 0) { RETURN_NEQ(j); @@ -2649,7 +2694,7 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */ } } else { /* (ab)Use TAG_PRIMARY_HEADER to recognize a term_array */ - ESTACK_PUSH3(stack, i, (Eterm)bb, (Eterm)aa | TAG_PRIMARY_HEADER); + WSTACK_PUSH3(stack, i, (UWord)bb, (UWord)aa | TAG_PRIMARY_HEADER); goto tailrecur_ne; } } @@ -2659,20 +2704,20 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */ goto tailrecur; pop_next: - if (!ESTACK_ISEMPTY(stack)) { - Eterm something = ESTACK_POP(stack); - if (primary_tag(something) == TAG_PRIMARY_HEADER) { /* a term_array */ + if (!WSTACK_ISEMPTY(stack)) { + UWord something = WSTACK_POP(stack); + if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */ aa = (Eterm*) something; - bb = (Eterm*) ESTACK_POP(stack); - i = ESTACK_POP(stack); + bb = (Eterm*) WSTACK_POP(stack); + i = WSTACK_POP(stack); goto term_array; } - a = something; - b = ESTACK_POP(stack); + a = (Eterm) something; + b = (Eterm) WSTACK_POP(stack); goto tailrecur; } - DESTROY_ESTACK(stack); + DESTROY_WSTACK(stack); return 0; not_equal: diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index 95510a16b2..cbd4dcb682 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -196,9 +196,9 @@ enum e_timer {timer_idle, timer_again, timer_write}; struct t_data; typedef struct { - Sint fd; + SWord fd; ErlDrvPort port; - unsigned key; /* Async queue key */ + unsigned long key; /* Async queue key */ unsigned flags; /* Original flags from FILE_OPEN. */ void (*invoke)(void *); struct t_data *d; @@ -306,7 +306,7 @@ struct t_data int result_ok; Efile_error errInfo; int flags; - Sint fd; + SWord fd; /**/ Efile_info info; EFILE_DIR_HANDLE dir_handle; /* Handle to open directory. */ @@ -605,7 +605,7 @@ file_start(ErlDrvPort port, char* command) } desc->fd = FILE_FD_INVALID; desc->port = port; - desc->key = (unsigned) (Uint) port; + desc->key = (unsigned long) (UWord) port; desc->flags = 0; desc->invoke = NULL; desc->d = NULL; @@ -630,7 +630,7 @@ static void free_data(void *data) EF_FREE(data); } -static void do_close(int flags, Sint fd) { +static void do_close(int flags, SWord fd) { if (flags & EFILE_COMPRESSED) { erts_gzclose((gzFile)(fd)); } else { @@ -709,7 +709,7 @@ static void reply_Uint_posix_error(file_descriptor *desc, Uint num, TRACE_C('N'); response[0] = FILE_RESP_NUMERR; -#if SIZEOF_VOID_P == 4 +#if SIZEOF_VOID_P == 4 || HALFWORD_HEAP put_int32(0, response+1); #else put_int32(num>>32, response+1); @@ -767,7 +767,7 @@ static int reply_Uint(file_descriptor *desc, Uint result) { TRACE_C('R'); tmp[0] = FILE_RESP_NUMBER; -#if SIZEOF_VOID_P == 4 +#if SIZEOF_VOID_P == 4 || HALFWORD_HEAP put_int32(0, tmp+1); #else put_int32(result>>32, tmp+1); @@ -1620,7 +1620,7 @@ static void invoke_open(void *data) status = efile_may_openfile(&d->errInfo, d->b); if (status || (d->errInfo.posix_errno != EISDIR)) { mode = (d->flags & EFILE_MODE_READ) ? "rb" : "wb"; - d->fd = (Sint) erts_gzopen(d->b, mode); + d->fd = (SWord) erts_gzopen(d->b, mode); if ((gzFile)d->fd) { status = 1; } else { diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index 4cd54c073f..d782b044a9 100644 --- a/erts/emulator/drivers/unix/ttsl_drv.c +++ b/erts/emulator/drivers/unix/ttsl_drv.c @@ -314,7 +314,7 @@ static ErlDrvData ttysl_start(ErlDrvPort port, char* buf) sys_sigset(SIGCONT, cont); sys_sigset(SIGWINCH, winch); - driver_select(port, (ErlDrvEvent)(Uint)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 1); + driver_select(port, (ErlDrvEvent)(UWord)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 1); ttysl_port = port; /* we need to know this when we enter the break handler */ @@ -394,7 +394,7 @@ static void ttysl_stop(ErlDrvData ttysl_data) stop_lbuf(); stop_termcap(); tty_reset(ttysl_fd); - driver_select(ttysl_port, (ErlDrvEvent)(Uint)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 0); + driver_select(ttysl_port, (ErlDrvEvent)(UWord)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 0); sys_sigset(SIGCONT, SIG_DFL); sys_sigset(SIGWINCH, SIG_DFL); } @@ -685,7 +685,7 @@ static void ttysl_from_tty(ErlDrvData ttysl_data, ErlDrvEvent fd) utf8buf_size = 0; } - if ((i = read((int)(Sint)fd, (char *) p, left)) >= 0) { + if ((i = read((int)(SWord)fd, (char *) p, left)) >= 0) { if (p != b) { i += (p - b); } diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h index 1c5aa63e90..adbfd30f0f 100644 --- a/erts/emulator/sys/common/erl_mseg.h +++ b/erts/emulator/sys/common/erl_mseg.h @@ -58,8 +58,8 @@ typedef struct { typedef struct { int cache; int preserv; - Uint abs_shrink_th; - Uint rel_shrink_th; + UWord abs_shrink_th; + UWord rel_shrink_th; } ErtsMsegOpt_t; #define ERTS_MSEG_DEFAULT_OPT_INITIALIZER \ diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops index 4a859c3094..1a76e80620 100755 --- a/erts/emulator/utils/beam_makeops +++ b/erts/emulator/utils/beam_makeops @@ -812,9 +812,10 @@ sub basic_generator { # Pack arguments if requested. # - if ($flags =~ /-pack/ && $hot) { - ($prefix, $pack_spec, @args) = &do_pack(@args); - } + # /* XXX:PaN temporarilly disabled during halfword implementation step 1 */ + #if ($flags =~ /-pack/ && $hot) { + # ($prefix, $pack_spec, @args) = &do_pack(@args); + #} # # Calculate the size of the instruction and generate each argument for @@ -916,7 +917,7 @@ sub basic_generator { } else { $code = join("\n", "{ $var_decls", - "Eterm* next;", + "UWord* next;", "PreFetch($size, next);", "$macro_code", "NextPF($size, next);", diff --git a/erts/emulator/utils/make_tables b/erts/emulator/utils/make_tables index b5391234cf..8e9e414dbe 100755 --- a/erts/emulator/utils/make_tables +++ b/erts/emulator/utils/make_tables @@ -184,7 +184,7 @@ for ($i = 0; $i < @bif; $i++) { my $arity = $bif[$i]->[2]; my $args = join(', ', 'Process*', ('Eterm') x $arity); print "Eterm $bif[$i]->[3]($args);\n"; - print "Eterm wrap_$bif[$i]->[3]($args, Uint *I);\n"; + print "Eterm wrap_$bif[$i]->[3]($args, UWord *I);\n"; } print "#endif\n"; @@ -225,15 +225,15 @@ for ($i = 0; $i < @bif; $i++) { for ($arg = 1; $arg <= $arity; $arg++) { print ", Eterm arg$arg"; } - print ", Uint *I)\n"; + print ", UWord *I)\n"; print "{\n"; print " return erts_bif_trace($i, p"; for ($arg = 1; $arg <= 3; $arg++) { if ($arg <= $arity) { print ", arg$arg"; - } elsif ($arg == ($arity + 1)) { - # Place I in correct position - print ", (Eterm) I"; + #} elsif ($arg == ($arity + 1)) { + # # Place I in correct position + # print ", (Eterm) I"; } else { print ", 0"; } -- cgit v1.2.3 From 0cbb78132f50be8ba38051963314b9722c1aba05 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 4 Feb 2010 12:15:29 +0100 Subject: Fix the BEAM dissambler for the half-word emulator --- erts/emulator/beam/beam_debug.c | 110 +++++++++++++++++++++------------------- erts/emulator/beam/big.c | 36 +++++++++++++ erts/emulator/beam/big.h | 1 + erts/emulator/beam/global.h | 2 + 4 files changed, 98 insertions(+), 51 deletions(-) diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index b381d4e546..5680a93afd 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -38,17 +38,18 @@ #include "beam_bp.h" #include "erl_binary.h" -#ifdef ARCH_64 /* XXX:PaN Halfword? */ +#ifdef ARCH_64 # define HEXF "%016bpX" #else # define HEXF "%08bpX" #endif +#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) void dbg_bt(Process* p, Eterm* sp); -void dbg_where(Eterm* addr, Eterm x0, Eterm* reg); +void dbg_where(UWord* addr, Eterm x0, Eterm* reg); static void print_big(int to, void *to_arg, Eterm* addr); -static int print_op(int to, void *to_arg, int op, int size, Eterm* addr); +static int print_op(int to, void *to_arg, int op, int size, UWord* addr); Eterm erts_debug_same_2(Process* p, Eterm term1, Eterm term2) { @@ -132,16 +133,16 @@ erts_debug_disassemble_1(Process* p, Eterm addr) Eterm* tp; Eterm bin; Eterm mfa; - Eterm* funcinfo = NULL; /* Initialized to eliminate warning. */ - Uint* code_base; - Uint* code_ptr = NULL; /* Initialized to eliminate warning. */ - Uint instr; - Uint uaddr; + UWord* funcinfo = NULL; /* Initialized to eliminate warning. */ + UWord* code_base; + UWord* code_ptr = NULL; /* Initialized to eliminate warning. */ + UWord instr; + UWord uaddr; Uint hsz; int i; - if (term_to_Uint(addr, &uaddr)) { - code_ptr = (Uint *) uaddr; + if (term_to_UWord(addr, &uaddr)) { + code_ptr = (UWord *) uaddr; if ((funcinfo = find_function_from_pc(code_ptr)) == NULL) { BIF_RET(am_false); } @@ -180,14 +181,14 @@ erts_debug_disassemble_1(Process* p, Eterm addr) * But this code_ptr will point to the start of the Export, * not the function's func_info instruction. BOOM !? */ - code_ptr = ((Eterm *) ep->address) - 5; + code_ptr = ((UWord *) ep->address) - 5; funcinfo = code_ptr+2; } else if (modp == NULL || (code_base = modp->code) == NULL) { BIF_RET(am_undef); } else { n = code_base[MI_NUM_FUNCTIONS]; for (i = 0; i < n; i++) { - code_ptr = (Uint *) code_base[MI_FUNCTIONS+i]; + code_ptr = (UWord *) code_base[MI_FUNCTIONS+i]; if (code_ptr[3] == name && code_ptr[4] == arity) { funcinfo = code_ptr+2; break; @@ -203,9 +204,9 @@ erts_debug_disassemble_1(Process* p, Eterm addr) dsbufp = erts_create_tmp_dsbuf(0); erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr); - instr = (Uint) code_ptr[0]; + instr = (UWord) code_ptr[0]; for (i = 0; i < NUM_SPECIFIC_OPS; i++) { - if (instr == (Uint) BeamOp(i) && opc[i].name[0] != '\0') { + if (instr == (UWord) 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; @@ -219,12 +220,12 @@ erts_debug_disassemble_1(Process* p, Eterm addr) bin = new_binary(p, (byte *) dsbufp->str, (int) dsbufp->str_len); erts_destroy_tmp_dsbuf(dsbufp); hsz = 4+4; - (void) erts_bld_uint(NULL, &hsz, (Uint) code_ptr); + (void) erts_bld_uword(NULL, &hsz, (UWord) code_ptr); hp = HAlloc(p, hsz); - addr = erts_bld_uint(&hp, NULL, (Uint) code_ptr); + addr = erts_bld_uword(&hp, NULL, (UWord) code_ptr); ASSERT(is_atom(funcinfo[0])); ASSERT(is_atom(funcinfo[1])); - mfa = TUPLE3(hp, funcinfo[0], funcinfo[1], make_small(funcinfo[2])); + mfa = TUPLE3(hp, (Eterm) funcinfo[0], (Eterm) funcinfo[1], make_small((Eterm) funcinfo[2])); hp += 4; return TUPLE3(hp, addr, bin, mfa); } @@ -236,20 +237,20 @@ dbg_bt(Process* p, Eterm* sp) while (sp < stack) { if (is_CP(*sp)) { - Eterm* addr = find_function_from_pc(cp_val(*sp)); + UWord* addr = find_function_from_pc(cp_val(*sp)); if (addr) erts_fprintf(stderr, HEXF ": %T:%T/%bpu\n", - addr, addr[0], addr[1], addr[2]); + addr, (Eterm) addr[0], (Eterm) addr[1], (Uint) addr[2]); } sp++; } } void -dbg_where(Eterm* addr, Eterm x0, Eterm* reg) +dbg_where(UWord* addr, Eterm x0, Eterm* reg) { - Eterm* f = find_function_from_pc(addr); + UWord* f = find_function_from_pc(addr); if (f == NULL) { erts_fprintf(stderr, "???\n"); @@ -259,7 +260,7 @@ dbg_where(Eterm* addr, Eterm x0, Eterm* reg) addr = f; arity = addr[2]; - erts_fprintf(stderr, HEXF ": %T:%T(", addr, addr[0], addr[1]); + erts_fprintf(stderr, HEXF ": %T:%T(", addr, (Eterm) addr[0], (Eterm) addr[1]); for (i = 0; i < arity; i++) erts_fprintf(stderr, i ? ", %T" : "%T", i ? reg[i] : x0); erts_fprintf(stderr, ")\n"); @@ -267,18 +268,18 @@ dbg_where(Eterm* addr, Eterm x0, Eterm* reg) } static int -print_op(int to, void *to_arg, int op, int size, Eterm* addr) +print_op(int to, void *to_arg, int op, int size, UWord* addr) { int i; - Uint tag; + UWord tag; char* sign; char* start_prog; /* Start of program for packer. */ char* prog; /* Current position in packer program. */ - Uint stack[8]; /* Stack for packer. */ - Uint* sp = stack; /* Points to next free position. */ - Uint packed = 0; /* Accumulator for packed operations. */ - Uint args[8]; /* Arguments for this instruction. */ - Uint* ap; /* Pointer to arguments. */ + UWord stack[8]; /* Stack for packer. */ + UWord* sp = stack; /* Points to next free position. */ + UWord packed = 0; /* Accumulator for packed operations. */ + UWord args[8]; /* Arguments for this instruction. */ + UWord* ap; /* Pointer to arguments. */ start_prog = opc[op].pack; @@ -288,7 +289,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) * Avoid copying because instructions containing bignum operands * are bigger than actually declared. */ - ap = (Uint *) addr; + ap = (UWord *) addr; } else { /* * Copy all arguments to a local buffer for the unpacking. @@ -390,11 +391,11 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) case 'i': /* Tagged integer */ case 'c': /* Tagged constant */ case 'q': /* Tagged literal */ - erts_print(to, to_arg, "%T", *ap); + erts_print(to, to_arg, "%T", (Eterm) *ap); ap++; break; case 'A': - erts_print(to, to_arg, "%d", arityval(ap[0])); + erts_print(to, to_arg, "%d", arityval( (Eterm) ap[0])); ap++; break; case 'd': /* Destination (x(0), x(N), y(N)) */ @@ -421,30 +422,36 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) ap++; break; case 'f': /* Destination label */ - erts_print(to, to_arg, "f(%X)", *ap); - ap++; + { + UWord* f = find_function_from_pc((UWord *)*ap); + if (f+3 != (UWord *) *ap) { + erts_print(to, to_arg, "f(" HEXF ")", *ap); + } else { + erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]); + } + ap++; + } break; case 'p': /* Pointer (to label) */ { - Eterm* f = find_function_from_pc((Eterm *)*ap); - - if (f+3 != (Eterm *) *ap) { - erts_print(to, to_arg, "p(%X)", *ap); + UWord* f = find_function_from_pc((UWord *)*ap); + if (f+3 != (UWord *) *ap) { + erts_print(to, to_arg, "p(" HEXF ")", *ap); } else { - erts_print(to, to_arg, "%T:%T/%bpu", f[0], f[1], f[2]); + erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]); } ap++; } break; case 'j': /* Pointer (to label) */ - erts_print(to, to_arg, "j(%X)", *ap); + erts_print(to, to_arg, "j(" HEXF ")", *ap); ap++; break; case 'e': /* Export entry */ { Export* ex = (Export *) *ap; erts_print(to, to_arg, - "%T:%T/%bpu", ex->code[0], ex->code[1], ex->code[2]); + "%T:%T/%bpu", (Eterm) ex->code[0], (Eterm) ex->code[1], (Uint) ex->code[2]); ap++; } break; @@ -467,7 +474,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) ap++; break; case 'P': /* Byte offset into tuple (see beam_load.c) */ - erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm*)) - 1); + erts_print(to, to_arg, "%d", (*ap / sizeof(UWord)) - 1); ap++; break; case 'l': /* fr(N) */ @@ -494,7 +501,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) int n = ap[-1]; while (n > 0) { - erts_print(to, to_arg, "%T f(%X) ", ap[0], ap[1]); + erts_print(to, to_arg, "%T f(" HEXF ") ", (Eterm) ap[0], ap[1]); ap += 2; size += 2; n--; @@ -505,7 +512,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) { int n; for (n = ap[-2]; n > 0; n--) { - erts_print(to, to_arg, "f(%X) ", ap[0]); + erts_print(to, to_arg, "f(" HEXF ") ", ap[0]); ap++; size++; } @@ -513,11 +520,12 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) break; case op_i_select_big_sf: while (ap[0]) { - int arity = thing_arityval(ap[0]); - print_big(to, to_arg, ap); - size += arity+1; - ap += arity+1; - erts_print(to, to_arg, " f(%X) ", ap[0]); + Eterm *bigp = (Eterm *) ap; + int arity = thing_arityval(*bigp); + print_big(to, to_arg, bigp); + size += TermWords(arity+1); + ap += TermWords(arity+1); + erts_print(to, to_arg, " f(" HEXF ") ", ap[0]); ap++; size++; } @@ -541,8 +549,8 @@ print_big(int to, void *to_arg, Eterm* addr) erts_print(to, to_arg, "-#integer(%d) = {", i); else erts_print(to, to_arg, "#integer(%d) = {", i); - erts_print(to, to_arg, "%d", BIG_DIGIT(addr, 0)); + erts_print(to, to_arg, "0x%x", BIG_DIGIT(addr, 0)); for (k = 1; k < i; k++) - erts_print(to, to_arg, ",%d", BIG_DIGIT(addr, k)); + erts_print(to, to_arg, ",0x%x", BIG_DIGIT(addr, k)); erts_print(to, to_arg, "}"); } diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index b8464ded28..c70044ed43 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1878,6 +1878,42 @@ term_to_Uint(Eterm term, Uint *up) } } +int +term_to_UWord(Eterm term, UWord *up) +{ + if (is_small(term)) { + Sint i = signed_val(term); + if (i < 0) { + *up = BADARG; + return 0; + } + *up = (UWord) i; + return 1; + } else if (is_big(term)) { + ErtsDigit* xr = big_v(term); + dsize_t xl = big_size(term); + UWord uval = 0; + int n = 0; + + if (big_sign(term)) { + *up = BADARG; + return 0; + } else if (xl*D_EXP > sizeof(UWord)*8) { + *up = SYSTEM_LIMIT; + return 0; + } + while (xl-- > 0) { + uval |= ((Uint)(*xr++)) << n; + n += D_EXP; + } + *up = uval; + return 1; + } else { + *up = BADARG; + return 0; + } +} + int term_to_Sint(Eterm term, Sint *sp) { if (is_small(term)) { diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h index d74da7cef7..39689189e5 100644 --- a/erts/emulator/beam/big.h +++ b/erts/emulator/beam/big.h @@ -150,6 +150,7 @@ Eterm bytes_to_big(byte*, dsize_t, int, Eterm*); byte* big_to_bytes(Eterm, byte*); int term_to_Uint(Eterm, Uint*); +int term_to_UWord(Eterm, UWord*); int term_to_Sint(Eterm, Sint*); Uint32 big_to_uint32(Eterm b); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 2afb6775b5..ebe7302373 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1570,7 +1570,9 @@ Sint cmp(Eterm, Eterm); #define CMP_EQ(a,b) ((a) == (b) || cmp_eq((a),(b))) #define CMP_NE(a,b) ((a) != (b) && cmp_ne((a),(b))) +/* duplicates from big.h */ int term_to_Uint(Eterm term, Uint *up); +int term_to_UWord(Eterm, UWord*); #ifdef HAVE_ERTS_NOW_CPU extern int erts_cpu_timestamp; -- cgit v1.2.3 From 20ba5ed3c281d3f0be587395fa66182873d229f0 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 4 Feb 2010 15:21:36 +0100 Subject: Add the BeamInstr data type for loaded BEAM code For cleanliness, use BeamInstr instead of the UWord data type to any machine-sized words that are used for BEAM instructions. Only use UWord for untyped words in general. --- erts/emulator/beam/beam_bif_load.c | 34 ++-- erts/emulator/beam/beam_bp.c | 203 +++++++++---------- erts/emulator/beam/beam_bp.h | 40 ++-- erts/emulator/beam/beam_catches.c | 8 +- erts/emulator/beam/beam_catches.h | 6 +- erts/emulator/beam/beam_debug.c | 62 +++--- erts/emulator/beam/beam_emu.c | 356 +++++++++++++++++----------------- erts/emulator/beam/beam_load.c | 203 +++++++++---------- erts/emulator/beam/beam_load.h | 12 +- erts/emulator/beam/bif.c | 4 +- erts/emulator/beam/break.c | 2 +- erts/emulator/beam/erl_alloc_util.h | 2 +- erts/emulator/beam/erl_bif_chksum.c | 4 +- erts/emulator/beam/erl_bif_info.c | 2 +- erts/emulator/beam/erl_bif_re.c | 4 +- erts/emulator/beam/erl_bif_trace.c | 32 +-- erts/emulator/beam/erl_db.c | 18 +- erts/emulator/beam/erl_db_tree.c | 4 +- erts/emulator/beam/erl_db_util.c | 4 +- erts/emulator/beam/erl_fun.c | 8 +- erts/emulator/beam/erl_fun.h | 4 +- erts/emulator/beam/erl_nif.c | 16 +- erts/emulator/beam/erl_process.c | 26 +-- erts/emulator/beam/erl_process.h | 11 +- erts/emulator/beam/erl_process_dump.c | 12 +- erts/emulator/beam/erl_term.h | 6 +- erts/emulator/beam/erl_trace.c | 18 +- erts/emulator/beam/erl_unicode.c | 20 +- erts/emulator/beam/error.h | 6 +- erts/emulator/beam/export.c | 10 +- erts/emulator/beam/export.h | 4 +- erts/emulator/beam/global.h | 12 +- erts/emulator/beam/module.h | 4 +- erts/emulator/beam/sys.h | 3 + 34 files changed, 583 insertions(+), 577 deletions(-) diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index db557c27a5..8462f1c7fd 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -39,10 +39,10 @@ static Eterm check_process_code(Process* rp, Module* modp); static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp); static void delete_export_references(Eterm module); static int purge_module(int module); -static int is_native(UWord* code); +static int is_native(BeamInstr* code); static int any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size); static int any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size); -static void remove_from_address_table(UWord* code); +static void remove_from_address_table(BeamInstr* code); Eterm load_module_2(BIF_ALIST_2) @@ -344,8 +344,8 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) modp->code[MI_ON_LOAD_FUNCTION_PTR] = 0; set_default_trace_pattern(BIF_ARG_1); } else if (BIF_ARG_2 == am_false) { - UWord* code; - UWord* end; + BeamInstr* code; + BeamInstr* end; /* * The on_load function failed. Remove the loaded code. @@ -354,7 +354,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) */ erts_total_code_size -= modp->code_length; code = modp->code; - end = (UWord *)((char *)code + modp->code_length); + end = (BeamInstr *)((char *)code + modp->code_length); erts_cleanup_funs_on_purge(code, end); beam_catches_delmod(modp->catches, code, modp->code_length); erts_free(ERTS_ALC_T_CODE, (void *) code); @@ -397,10 +397,10 @@ set_default_trace_pattern(Eterm module) static Eterm check_process_code(Process* rp, Module* modp) { - UWord* start; + BeamInstr* start; char* mod_start; Uint mod_size; - UWord* end; + BeamInstr* end; Eterm* sp; #ifndef HYBRID /* FIND ME! */ ErlFunThing* funp; @@ -418,7 +418,7 @@ check_process_code(Process* rp, Module* modp) * Pick up limits for the module. */ start = modp->old_code; - end = (UWord *)((char *)start + modp->old_code_length); + end = (BeamInstr *)((char *)start + modp->old_code_length); mod_start = (char *) start; mod_size = modp->old_code_length; @@ -472,11 +472,11 @@ check_process_code(Process* rp, Module* modp) #ifndef HYBRID /* FIND ME! */ rescan: for (funp = MSO(rp).funs; funp; funp = funp->next) { - UWord* fun_code; + BeamInstr* fun_code; fun_code = funp->fe->address; - if (INSIDE((UWord *) funp->fe->address)) { + if (INSIDE((BeamInstr *) funp->fe->address)) { if (done_gc) { return am_true; } else { @@ -617,8 +617,8 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size) static int purge_module(int module) { - UWord* code; - UWord* end; + BeamInstr* code; + BeamInstr* end; Module* modp; /* @@ -653,7 +653,7 @@ purge_module(int module) ASSERT(erts_total_code_size >= modp->old_code_length); erts_total_code_size -= modp->old_code_length; code = modp->old_code; - end = (UWord *)((char *)code + modp->old_code_length); + end = (BeamInstr *)((char *)code + modp->old_code_length); erts_cleanup_funs_on_purge(code, end); beam_catches_delmod(modp->old_catches, code, modp->old_code_length); erts_free(ERTS_ALC_T_CODE, (void *) code); @@ -665,7 +665,7 @@ purge_module(int module) } static void -remove_from_address_table(UWord* code) +remove_from_address_table(BeamInstr* code) { int i; @@ -738,11 +738,11 @@ delete_export_references(Eterm module) Export *ep = export_list(i); if (ep != NULL && (ep->code[0] == module)) { if (ep->address == ep->code+3 && - (ep->code[3] == (UWord) em_apply_bif)) { + (ep->code[3] == (BeamInstr) em_apply_bif)) { continue; } ep->address = ep->code+3; - ep->code[3] = (UWord) em_call_error_handler; + ep->code[3] = (BeamInstr) em_call_error_handler; ep->code[4] = 0; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; @@ -774,7 +774,7 @@ beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks, Eterm module) } static int -is_native(UWord* code) +is_native(BeamInstr* code) { return ((Eterm *)code[MI_FUNCTIONS])[1] != 0; } diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c index 0cdc2116ba..b21e70258e 100644 --- a/erts/emulator/beam/beam_bp.c +++ b/erts/emulator/beam/beam_bp.c @@ -109,23 +109,23 @@ do { \ */ static int set_break(Eterm mfa[3], int specified, - Binary *match_spec, Uint break_op, + Binary *match_spec, BeamInstr break_op, enum erts_break_op count_op, Eterm tracer_pid); static int set_module_break(Module *modp, Eterm mfa[3], int specified, - Binary *match_spec, Uint break_op, + Binary *match_spec, BeamInstr break_op, enum erts_break_op count_op, Eterm tracer_pid); -static int set_function_break(Module *modp, Uint *pc, - Binary *match_spec, Uint break_op, +static int set_function_break(Module *modp, BeamInstr *pc, + Binary *match_spec, BeamInstr break_op, enum erts_break_op count_op, Eterm tracer_pid); static int clear_break(Eterm mfa[3], int specified, - Uint break_op); + BeamInstr break_op); static int clear_module_break(Module *modp, Eterm mfa[3], int specified, - Uint break_op); -static int clear_function_break(Module *modp, Uint *pc, - Uint break_op); + BeamInstr break_op); +static int clear_function_break(Module *modp, BeamInstr *pc, + BeamInstr break_op); -static BpData *is_break(Uint *pc, Uint break_op); +static BpData *is_break(BeamInstr *pc, BeamInstr break_op); @@ -145,7 +145,7 @@ erts_set_trace_break(Eterm mfa[3], int specified, Binary *match_spec, Eterm tracer_pid) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return set_break(mfa, specified, match_spec, - (Uint) BeamOp(op_i_trace_breakpoint), 0, tracer_pid); + (BeamInstr) BeamOp(op_i_trace_breakpoint), 0, tracer_pid); } int @@ -153,11 +153,11 @@ erts_set_mtrace_break(Eterm mfa[3], int specified, Binary *match_spec, Eterm tracer_pid) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return set_break(mfa, specified, match_spec, - (Uint) BeamOp(op_i_mtrace_breakpoint), 0, tracer_pid); + (BeamInstr) BeamOp(op_i_mtrace_breakpoint), 0, tracer_pid); } void -erts_set_mtrace_bif(Uint *pc, Binary *match_spec, Eterm tracer_pid) { +erts_set_mtrace_bif(BeamInstr *pc, Binary *match_spec, Eterm tracer_pid) { BpDataTrace *bdt; ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); @@ -173,7 +173,7 @@ erts_set_mtrace_bif(Uint *pc, Binary *match_spec, Eterm tracer_pid) { MatchSetRef(match_spec); bdt->match_spec = match_spec; bdt->tracer_pid = tracer_pid; - pc[-4] = (Uint) bdt; + pc[-4] = (BeamInstr) bdt; } } @@ -181,14 +181,14 @@ int erts_set_debug_break(Eterm mfa[3], int specified) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return set_break(mfa, specified, NULL, - (Uint) BeamOp(op_i_debug_breakpoint), 0, NIL); + (BeamInstr) BeamOp(op_i_debug_breakpoint), 0, NIL); } int erts_set_count_break(Eterm mfa[3], int specified, enum erts_break_op count_op) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return set_break(mfa, specified, NULL, - (Uint) BeamOp(op_i_count_breakpoint), count_op, NIL); + (BeamInstr) BeamOp(op_i_count_breakpoint), count_op, NIL); } @@ -197,18 +197,18 @@ int erts_clear_trace_break(Eterm mfa[3], int specified) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return clear_break(mfa, specified, - (Uint) BeamOp(op_i_trace_breakpoint)); + (BeamInstr) BeamOp(op_i_trace_breakpoint)); } int erts_clear_mtrace_break(Eterm mfa[3], int specified) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return clear_break(mfa, specified, - (Uint) BeamOp(op_i_mtrace_breakpoint)); + (BeamInstr) BeamOp(op_i_mtrace_breakpoint)); } void -erts_clear_mtrace_bif(Uint *pc) { +erts_clear_mtrace_bif(BeamInstr *pc) { BpDataTrace *bdt; ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); @@ -219,21 +219,21 @@ erts_clear_mtrace_bif(Uint *pc) { } Free(bdt); } - pc[-4] = (Uint) NULL; + pc[-4] = (BeamInstr) NULL; } int erts_clear_debug_break(Eterm mfa[3], int specified) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return clear_break(mfa, specified, - (Uint) BeamOp(op_i_debug_breakpoint)); + (BeamInstr) BeamOp(op_i_debug_breakpoint)); } int erts_clear_count_break(Eterm mfa[3], int specified) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); return clear_break(mfa, specified, - (Uint) BeamOp(op_i_count_breakpoint)); + (BeamInstr) BeamOp(op_i_count_breakpoint)); } int @@ -250,7 +250,7 @@ erts_clear_module_break(Module *modp) { } int -erts_clear_function_break(Module *modp, Uint *pc) { +erts_clear_function_break(Module *modp, BeamInstr *pc) { ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); ASSERT(modp); return clear_function_break(modp, pc, 0); @@ -261,13 +261,13 @@ erts_clear_function_break(Module *modp, Uint *pc) { /* * SMP NOTE: Process p may have become exiting on return! */ -Uint -erts_trace_break(Process *p, UWord *pc, Eterm *args, +BeamInstr +erts_trace_break(Process *p, BeamInstr *pc, Eterm *args, Uint32 *ret_flags, Eterm *tracer_pid) { Eterm tpid1, tpid2; BpDataTrace *bdt = (BpDataTrace *) pc[-4]; - - ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); + + ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); ASSERT(bdt); bdt = (BpDataTrace *) bdt->next; ASSERT(bdt); @@ -286,7 +286,7 @@ erts_trace_break(Process *p, UWord *pc, Eterm *args, bdt->tracer_pid = tpid2; ErtsSmpBPUnlock(bdt); } - pc[-4] = (Uint) bdt; + pc[-4] = (BeamInstr) bdt; return bdt->orig_instr; } @@ -296,10 +296,10 @@ erts_trace_break(Process *p, UWord *pc, Eterm *args, * SMP NOTE: Process p may have become exiting on return! */ Uint32 -erts_bif_mtrace(Process *p, UWord *pc, Eterm *args, int local, +erts_bif_mtrace(Process *p, BeamInstr *pc, Eterm *args, int local, Eterm *tracer_pid) { BpDataTrace *bdt = (BpDataTrace *) pc[-4]; - + ASSERT(tracer_pid); if (bdt) { Eterm tpid1, tpid2; @@ -326,9 +326,9 @@ erts_bif_mtrace(Process *p, UWord *pc, Eterm *args, int local, int -erts_is_trace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { +erts_is_trace_break(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { BpDataTrace *bdt = - (BpDataTrace *) is_break(pc, (Uint) BeamOp(op_i_trace_breakpoint)); + (BpDataTrace *) is_break(pc, (BeamInstr) BeamOp(op_i_trace_breakpoint)); if (bdt) { if (match_spec_ret) { @@ -345,9 +345,9 @@ erts_is_trace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { } int -erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { +erts_is_mtrace_break(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { BpDataTrace *bdt = - (BpDataTrace *) is_break(pc, (Uint) BeamOp(op_i_mtrace_breakpoint)); + (BpDataTrace *) is_break(pc, (BeamInstr) BeamOp(op_i_mtrace_breakpoint)); if (bdt) { if (match_spec_ret) { @@ -364,7 +364,7 @@ erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { } int -erts_is_mtrace_bif(UWord *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { +erts_is_mtrace_bif(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { BpDataTrace *bdt = (BpDataTrace *) pc[-4]; if (bdt) { @@ -382,20 +382,20 @@ erts_is_mtrace_bif(UWord *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) { } int -erts_is_native_break(Uint *pc) { +erts_is_native_break(BeamInstr *pc) { #ifdef HIPE - ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); - return pc[0] == (Uint) BeamOp(op_hipe_trap_call) - || pc[0] == (Uint) BeamOp(op_hipe_trap_call_closure); + ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); + return pc[0] == (BeamInstr) BeamOp(op_hipe_trap_call) + || pc[0] == (BeamInstr) BeamOp(op_hipe_trap_call_closure); #else return 0; #endif } int -erts_is_count_break(Uint *pc, Sint *count_ret) { +erts_is_count_break(BeamInstr *pc, Sint *count_ret) { BpDataCount *bdc = - (BpDataCount *) is_break(pc, (Uint) BeamOp(op_i_count_breakpoint)); + (BpDataCount *) is_break(pc, (BeamInstr) BeamOp(op_i_count_breakpoint)); if (bdc) { if (count_ret) { @@ -408,24 +408,24 @@ erts_is_count_break(Uint *pc, Sint *count_ret) { return 0; } -Uint * +BeamInstr * erts_find_local_func(Eterm mfa[3]) { Module *modp; - Uint** code_base; - Uint* code_ptr; + BeamInstr** code_base; + BeamInstr* code_ptr; Uint i,n; if ((modp = erts_get_module(mfa[0])) == NULL) return NULL; - if ((code_base = (Uint **) modp->code) == NULL) + if ((code_base = (BeamInstr **) modp->code) == NULL) return NULL; - n = (Uint) code_base[MI_NUM_FUNCTIONS]; + n = (BeamInstr) code_base[MI_NUM_FUNCTIONS]; for (i = 0; i < n; ++i) { code_ptr = code_base[MI_FUNCTIONS+i]; - ASSERT(((Uint) BeamOp(op_i_func_info_IaaI)) == code_ptr[0]); + ASSERT(((BeamInstr) BeamOp(op_i_func_info_IaaI)) == code_ptr[0]); ASSERT(mfa[0] == ((Eterm) code_ptr[2])); if (mfa[1] == ((Eterm) code_ptr[3]) && - ((Uint) mfa[2]) == code_ptr[4]) { + ((BeamInstr) mfa[2]) == code_ptr[4]) { return code_ptr + 5; } } @@ -440,7 +440,7 @@ erts_find_local_func(Eterm mfa[3]) { static int set_break(Eterm mfa[3], int specified, - Binary *match_spec, Eterm break_op, + Binary *match_spec, BeamInstr break_op, enum erts_break_op count_op, Eterm tracer_pid) { Module *modp; @@ -470,26 +470,26 @@ static int set_break(Eterm mfa[3], int specified, } static int set_module_break(Module *modp, Eterm mfa[3], int specified, - Binary *match_spec, Uint break_op, + Binary *match_spec, BeamInstr break_op, enum erts_break_op count_op, Eterm tracer_pid) { - Uint** code_base; - Uint* code_ptr; + BeamInstr** code_base; + BeamInstr* code_ptr; int num_processed = 0; Uint i,n; ASSERT(break_op); ASSERT(modp); - code_base = (Uint **) modp->code; + code_base = (BeamInstr **) modp->code; if (code_base == NULL) { return 0; } - n = (Uint) code_base[MI_NUM_FUNCTIONS]; + n = (BeamInstr) code_base[MI_NUM_FUNCTIONS]; for (i = 0; i < n; ++i) { code_ptr = code_base[MI_FUNCTIONS+i]; - ASSERT(code_ptr[0] == (Uint) BeamOp(op_i_func_info_IaaI)); + ASSERT(code_ptr[0] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); if ((specified < 2 || mfa[1] == ((Eterm) code_ptr[3])) && (specified < 3 || ((int) mfa[2]) == ((int) code_ptr[4]))) { - Uint *pc = code_ptr+5; + BeamInstr *pc = code_ptr+5; num_processed += set_function_break(modp, pc, match_spec, @@ -499,16 +499,16 @@ static int set_module_break(Module *modp, Eterm mfa[3], int specified, return num_processed; } -static int set_function_break(Module *modp, Uint *pc, - Binary *match_spec, Uint break_op, +static int set_function_break(Module *modp, BeamInstr *pc, + Binary *match_spec, BeamInstr break_op, enum erts_break_op count_op, Eterm tracer_pid) { BpData *bd, **r; size_t size; - Uint **code_base = (Uint **)modp->code; + BeamInstr **code_base = (BeamInstr **)modp->code; ASSERT(code_base); - ASSERT(code_base <= (Uint **)pc); - ASSERT((Uint **)pc < code_base + (modp->code_length/sizeof(Uint *))); + ASSERT(code_base <= (BeamInstr **)pc); + ASSERT((BeamInstr **)pc < code_base + (modp->code_length/sizeof(BeamInstr *))); /* * Currently no trace support for native code. */ @@ -517,8 +517,8 @@ static int set_function_break(Module *modp, Uint *pc, } /* Do not allow two breakpoints of the same kind */ if ( (bd = is_break(pc, break_op))) { - if (break_op == (Uint) BeamOp(op_i_trace_breakpoint) - || break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) { + if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint) + || break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) { BpDataTrace *bdt = (BpDataTrace *) bd; Binary *old_match_spec; @@ -533,7 +533,7 @@ static int set_function_break(Module *modp, Uint *pc, } else { ASSERT(! match_spec); ASSERT(is_nil(tracer_pid)); - if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) { + if (break_op == (BeamInstr) BeamOp(op_i_count_breakpoint)) { BpDataCount *bdc = (BpDataCount *) bd; ErtsSmpBPLock(bdc); @@ -551,13 +551,13 @@ static int set_function_break(Module *modp, Uint *pc, } return 1; } - if (break_op == (Uint) BeamOp(op_i_trace_breakpoint) || - break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) { + if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint) || + break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) { size = sizeof(BpDataTrace); } else { ASSERT(! match_spec); ASSERT(is_nil(tracer_pid)); - if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) { + if (break_op == (BeamInstr) BeamOp(op_i_count_breakpoint)) { if (count_op == erts_break_reset || count_op == erts_break_stop) { /* Do not insert a new breakpoint */ @@ -566,27 +566,27 @@ static int set_function_break(Module *modp, Uint *pc, size = sizeof(BpDataCount); } else { ASSERT(! count_op); - ASSERT(break_op == (Uint) BeamOp(op_i_debug_breakpoint)); + ASSERT(break_op == (BeamInstr) BeamOp(op_i_debug_breakpoint)); size = sizeof(BpDataDebug); } } r = (BpData **) (pc-4); if (! *r) { - ASSERT(*pc != (Uint) BeamOp(op_i_trace_breakpoint)); - ASSERT(*pc != (Uint) BeamOp(op_i_mtrace_breakpoint)); - ASSERT(*pc != (Uint) BeamOp(op_i_debug_breakpoint)); - ASSERT(*pc != (Uint) BeamOp(op_i_count_breakpoint)); + ASSERT(*pc != (BeamInstr) BeamOp(op_i_trace_breakpoint)); + ASSERT(*pc != (BeamInstr) BeamOp(op_i_mtrace_breakpoint)); + ASSERT(*pc != (BeamInstr) BeamOp(op_i_debug_breakpoint)); + ASSERT(*pc != (BeamInstr) BeamOp(op_i_count_breakpoint)); /* First breakpoint; create singleton ring */ bd = Alloc(size); BpInit(bd, *pc); *pc = break_op; *r = bd; } else { - ASSERT(*pc == (Uint) BeamOp(op_i_trace_breakpoint) || - *pc == (Uint) BeamOp(op_i_mtrace_breakpoint) || - *pc == (Uint) BeamOp(op_i_debug_breakpoint) || - *pc == (Uint) BeamOp(op_i_count_breakpoint)); - if (*pc == (Uint) BeamOp(op_i_debug_breakpoint)) { + ASSERT(*pc == (BeamInstr) BeamOp(op_i_trace_breakpoint) || + *pc == (BeamInstr) BeamOp(op_i_mtrace_breakpoint) || + *pc == (BeamInstr) BeamOp(op_i_debug_breakpoint) || + *pc == (BeamInstr) BeamOp(op_i_count_breakpoint)); + if (*pc == (BeamInstr) BeamOp(op_i_debug_breakpoint)) { /* Debug bp must be last, so if it is also first; * it must be singleton. */ ASSERT(BpSingleton(*r)); @@ -595,7 +595,7 @@ static int set_function_break(Module *modp, Uint *pc, BpInitAndSpliceNext(bd, *pc, *r); *pc = break_op; } else if ((*r)->prev->orig_instr - == (Uint) BeamOp(op_i_debug_breakpoint)) { + == (BeamInstr) BeamOp(op_i_debug_breakpoint)) { /* Debug bp last in the ring; insert new second to last. */ bd = Alloc(size); BpInitAndSplicePrev(bd, (*r)->prev->orig_instr, *r); @@ -609,24 +609,24 @@ static int set_function_break(Module *modp, Uint *pc, } } /* Init the bp type specific data */ - if (break_op == (Uint) BeamOp(op_i_trace_breakpoint) || - break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) { + if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint) || + break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) { BpDataTrace *bdt = (BpDataTrace *) bd; MatchSetRef(match_spec); bdt->match_spec = match_spec; bdt->tracer_pid = tracer_pid; - } else if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) { + } else if (break_op == (BeamInstr) BeamOp(op_i_count_breakpoint)) { BpDataCount *bdc = (BpDataCount *) bd; bdc->count = 0; } - ++(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]); + ++(*(BeamInstr*)&code_base[MI_NUM_BREAKPOINTS]); return 1; } -static int clear_break(Eterm mfa[3], int specified, Uint break_op) +static int clear_break(Eterm mfa[3], int specified, BeamInstr break_op) { int num_processed = 0; Module *modp; @@ -652,23 +652,24 @@ static int clear_break(Eterm mfa[3], int specified, Uint break_op) } static int clear_module_break(Module *m, Eterm mfa[3], int specified, - Uint break_op) { - Uint** code_base; - Uint* code_ptr; + BeamInstr break_op) { + BeamInstr** code_base; + BeamInstr* code_ptr; int num_processed = 0; - Uint i,n; + Uint i; + BeamInstr n; ASSERT(m); - code_base = (Uint **) m->code; + code_base = (BeamInstr **) m->code; if (code_base == NULL) { return 0; } - n = (Uint) code_base[MI_NUM_FUNCTIONS]; + n = (BeamInstr) code_base[MI_NUM_FUNCTIONS]; for (i = 0; i < n; ++i) { code_ptr = code_base[MI_FUNCTIONS+i]; if ((specified < 2 || mfa[1] == ((Eterm) code_ptr[3])) && (specified < 3 || ((int) mfa[2]) == ((int) code_ptr[4]))) { - Uint *pc = code_ptr + 5; + BeamInstr *pc = code_ptr + 5; num_processed += clear_function_break(m, pc, break_op); @@ -677,13 +678,13 @@ static int clear_module_break(Module *m, Eterm mfa[3], int specified, return num_processed; } -static int clear_function_break(Module *m, Uint *pc, Uint break_op) { +static int clear_function_break(Module *m, BeamInstr *pc, BeamInstr break_op) { BpData *bd; - Uint **code_base = (Uint **)m->code; + BeamInstr **code_base = (BeamInstr **)m->code; ASSERT(code_base); - ASSERT(code_base <= (Uint **)pc); - ASSERT((Uint **)pc < code_base + (m->code_length/sizeof(Uint *))); + ASSERT(code_base <= (BeamInstr **)pc); + ASSERT((BeamInstr **)pc < code_base + (m->code_length/sizeof(BeamInstr *))); /* * Currently no trace support for native code. */ @@ -695,7 +696,7 @@ static int clear_function_break(Module *m, Uint *pc, Uint break_op) { * There should be only one of each type, * but break_op may be 0 which matches any type. */ - Uint op; + BeamInstr op; BpData **r = (BpData **) (pc-4); ASSERT(*r); @@ -731,16 +732,16 @@ static int clear_function_break(Module *m, Uint *pc, Uint break_op) { bd_prev->orig_instr = bd->orig_instr; } } - if (op == (Uint) BeamOp(op_i_trace_breakpoint) || - op == (Uint) BeamOp(op_i_mtrace_breakpoint)) { + if (op == (BeamInstr) BeamOp(op_i_trace_breakpoint) || + op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) { BpDataTrace *bdt = (BpDataTrace *) bd; - + MatchSetUnref(bdt->match_spec); } Free(bd); - ASSERT(((Uint) code_base[MI_NUM_BREAKPOINTS]) > 0); - --(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]); + ASSERT(((BeamInstr) code_base[MI_NUM_BREAKPOINTS]) > 0); + --(*(BeamInstr*)&code_base[MI_NUM_BREAKPOINTS]); } return 1; } @@ -754,8 +755,8 @@ static int clear_function_break(Module *m, Uint *pc, Uint break_op) { ** returned. The program counter must point to the first executable ** (breakpoint) instruction of the function. */ -static BpData *is_break(Uint *pc, Uint break_op) { - ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); +static BpData *is_break(BeamInstr *pc, BeamInstr break_op) { + ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); if (! erts_is_native_break(pc)) { BpData *bd = (BpData *) pc[-4]; diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h index 44b463d39c..52a36db339 100644 --- a/erts/emulator/beam/beam_bp.h +++ b/erts/emulator/beam/beam_bp.h @@ -48,7 +48,7 @@ typedef struct bp_data { struct bp_data *next; /* Doubly linked ring pointers */ struct bp_data *prev; /* -"- */ - Uint orig_instr; /* The original instruction to execute */ + BeamInstr orig_instr; /* The original instruction to execute */ } BpData; /* ** All the following bp_data_.. structs must begin the same way @@ -57,21 +57,21 @@ typedef struct bp_data { typedef struct bp_data_trace { struct bp_data *next; struct bp_data *prev; - Uint orig_instr; + BeamInstr orig_instr; Binary *match_spec; - Eterm tracer_pid; + Eterm tracer_pid; } BpDataTrace; typedef struct bp_data_debug { struct bp_data *next; struct bp_data *prev; - Uint orig_instr; + BeamInstr orig_instr; } BpDataDebug; typedef struct bp_data_count { /* Call count */ struct bp_data *next; struct bp_data *prev; - Uint orig_instr; + BeamInstr orig_instr; Sint count; } BpDataCount; @@ -89,11 +89,11 @@ extern erts_smp_spinlock_t erts_bp_lock; do { \ BpDataCount *bdc = (BpDataCount *) (pc)[-4]; \ \ - ASSERT((pc)[-5] == (UWord) BeamOp(op_i_func_info_IaaI)); \ + ASSERT((pc)[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); \ ASSERT(bdc); \ bdc = (BpDataCount *) bdc->next; \ ASSERT(bdc); \ - (pc)[-4] = (UWord) bdc; \ + (pc)[-4] = (BeamInstr) bdc; \ ErtsSmpBPLock(bdc); \ if (bdc->count >= 0) bdc->count++; \ ErtsSmpBPUnlock(bdc); \ @@ -104,11 +104,11 @@ do { \ do { \ BpData *bd = (BpData *) (pc)[-4]; \ \ - ASSERT((pc)[-5] == (UWord) BeamOp(op_i_func_info_IaaI)); \ + ASSERT((pc)[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); \ ASSERT(bd); \ bd = bd->next; \ ASSERT(bd); \ - (pc)[-4] = (UWord) bd; \ + (pc)[-4] = (BeamInstr) bd; \ *(instr_result) = bd->orig_instr; \ } while (0) @@ -133,9 +133,9 @@ int erts_clear_trace_break(Eterm mfa[3], int specified); int erts_set_mtrace_break(Eterm mfa[3], int specified, Binary *match_spec, Eterm tracer_pid); int erts_clear_mtrace_break(Eterm mfa[3], int specified); -void erts_set_mtrace_bif(Uint *pc, Binary *match_spec, +void erts_set_mtrace_bif(BeamInstr *pc, Binary *match_spec, Eterm tracer_pid); -void erts_clear_mtrace_bif(Uint *pc); +void erts_clear_mtrace_bif(BeamInstr *pc); int erts_set_debug_break(Eterm mfa[3], int specified); int erts_clear_debug_break(Eterm mfa[3], int specified); int erts_set_count_break(Eterm mfa[3], int specified, enum erts_break_op); @@ -144,22 +144,22 @@ int erts_clear_count_break(Eterm mfa[3], int specified); int erts_clear_break(Eterm mfa[3], int specified); int erts_clear_module_break(Module *modp); -int erts_clear_function_break(Module *modp, Uint *pc); +int erts_clear_function_break(Module *modp, BeamInstr *pc); -Uint erts_trace_break(Process *p, UWord *pc, Eterm *args, +BeamInstr erts_trace_break(Process *p, BeamInstr *pc, Eterm *args, Uint32 *ret_flags, Eterm *tracer_pid); -Uint32 erts_bif_mtrace(Process *p, UWord *pc, Eterm *args, +Uint32 erts_bif_mtrace(Process *p, BeamInstr *pc, Eterm *args, int local, Eterm *tracer_pid); -int erts_is_trace_break(Uint *pc, Binary **match_spec_ret, +int erts_is_trace_break(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret); -int erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, +int erts_is_mtrace_break(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_rte); -int erts_is_mtrace_bif(UWord *pc, Binary **match_spec_ret, +int erts_is_mtrace_bif(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret); -int erts_is_native_break(Uint *pc); -int erts_is_count_break(Uint *pc, Sint *count_ret); +int erts_is_native_break(BeamInstr *pc); +int erts_is_count_break(BeamInstr *pc, Sint *count_ret); -Uint *erts_find_local_func(Eterm mfa[3]); +BeamInstr *erts_find_local_func(Eterm mfa[3]); #endif /* _BEAM_BP_H */ diff --git a/erts/emulator/beam/beam_catches.c b/erts/emulator/beam/beam_catches.c index af99b0499a..97258e179b 100644 --- a/erts/emulator/beam/beam_catches.c +++ b/erts/emulator/beam/beam_catches.c @@ -26,7 +26,7 @@ /* XXX: should use dynamic reallocation */ #define TABSIZ (16*1024) static struct { - UWord *cp; + BeamInstr *cp; unsigned cdr; } beam_catches[TABSIZ]; @@ -39,7 +39,7 @@ void beam_catches_init(void) high_mark = 0; } -unsigned beam_catches_cons(UWord *cp, unsigned cdr) +unsigned beam_catches_cons(BeamInstr *cp, unsigned cdr) { int i; @@ -65,7 +65,7 @@ unsigned beam_catches_cons(UWord *cp, unsigned cdr) return i; } -UWord *beam_catches_car(unsigned i) +BeamInstr *beam_catches_car(unsigned i) { if( i >= TABSIZ ) { fprintf(stderr, @@ -75,7 +75,7 @@ UWord *beam_catches_car(unsigned i) return beam_catches[i].cp; } -void beam_catches_delmod(unsigned head, UWord *code, unsigned code_bytes) +void beam_catches_delmod(unsigned head, BeamInstr *code, unsigned code_bytes) { unsigned i, cdr; diff --git a/erts/emulator/beam/beam_catches.h b/erts/emulator/beam/beam_catches.h index 0769d47263..611207e968 100644 --- a/erts/emulator/beam/beam_catches.h +++ b/erts/emulator/beam/beam_catches.h @@ -23,9 +23,9 @@ #define BEAM_CATCHES_NIL (-1) void beam_catches_init(void); -unsigned beam_catches_cons(UWord* cp, unsigned cdr); -UWord *beam_catches_car(unsigned i); -void beam_catches_delmod(unsigned head, UWord* code, unsigned code_bytes); +unsigned beam_catches_cons(BeamInstr* cp, unsigned cdr); +BeamInstr *beam_catches_car(unsigned i); +void beam_catches_delmod(unsigned head, BeamInstr* code, unsigned code_bytes); #define catch_pc(x) beam_catches_car(catch_val((x))) diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 5680a93afd..43dcebd0fb 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -43,13 +43,13 @@ #else # define HEXF "%08bpX" #endif -#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) +#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm)))) void dbg_bt(Process* p, Eterm* sp); -void dbg_where(UWord* addr, Eterm x0, Eterm* reg); +void dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg); static void print_big(int to, void *to_arg, Eterm* addr); -static int print_op(int to, void *to_arg, int op, int size, UWord* addr); +static int print_op(int to, void *to_arg, int op, int size, BeamInstr* addr); Eterm erts_debug_same_2(Process* p, Eterm term1, Eterm term2) { @@ -133,16 +133,16 @@ erts_debug_disassemble_1(Process* p, Eterm addr) Eterm* tp; Eterm bin; Eterm mfa; - UWord* funcinfo = NULL; /* Initialized to eliminate warning. */ - UWord* code_base; - UWord* code_ptr = NULL; /* Initialized to eliminate warning. */ - UWord instr; - UWord uaddr; + BeamInstr* funcinfo = NULL; /* Initialized to eliminate warning. */ + BeamInstr* code_base; + BeamInstr* code_ptr = NULL; /* Initialized to eliminate warning. */ + BeamInstr instr; + BeamInstr uaddr; Uint hsz; int i; if (term_to_UWord(addr, &uaddr)) { - code_ptr = (UWord *) uaddr; + code_ptr = (BeamInstr *) uaddr; if ((funcinfo = find_function_from_pc(code_ptr)) == NULL) { BIF_RET(am_false); } @@ -181,14 +181,14 @@ erts_debug_disassemble_1(Process* p, Eterm addr) * But this code_ptr will point to the start of the Export, * not the function's func_info instruction. BOOM !? */ - code_ptr = ((UWord *) ep->address) - 5; + code_ptr = ((BeamInstr *) ep->address) - 5; funcinfo = code_ptr+2; } else if (modp == NULL || (code_base = modp->code) == NULL) { BIF_RET(am_undef); } else { n = code_base[MI_NUM_FUNCTIONS]; for (i = 0; i < n; i++) { - code_ptr = (UWord *) code_base[MI_FUNCTIONS+i]; + code_ptr = (BeamInstr *) code_base[MI_FUNCTIONS+i]; if (code_ptr[3] == name && code_ptr[4] == arity) { funcinfo = code_ptr+2; break; @@ -204,9 +204,9 @@ erts_debug_disassemble_1(Process* p, Eterm addr) dsbufp = erts_create_tmp_dsbuf(0); erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr); - instr = (UWord) code_ptr[0]; + instr = (BeamInstr) code_ptr[0]; for (i = 0; i < NUM_SPECIFIC_OPS; i++) { - if (instr == (UWord) BeamOp(i) && opc[i].name[0] != '\0') { + 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; @@ -220,9 +220,9 @@ erts_debug_disassemble_1(Process* p, Eterm addr) bin = new_binary(p, (byte *) dsbufp->str, (int) dsbufp->str_len); erts_destroy_tmp_dsbuf(dsbufp); hsz = 4+4; - (void) erts_bld_uword(NULL, &hsz, (UWord) code_ptr); + (void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr); hp = HAlloc(p, hsz); - addr = erts_bld_uword(&hp, NULL, (UWord) code_ptr); + addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr); ASSERT(is_atom(funcinfo[0])); ASSERT(is_atom(funcinfo[1])); mfa = TUPLE3(hp, (Eterm) funcinfo[0], (Eterm) funcinfo[1], make_small((Eterm) funcinfo[2])); @@ -237,7 +237,7 @@ dbg_bt(Process* p, Eterm* sp) while (sp < stack) { if (is_CP(*sp)) { - UWord* addr = find_function_from_pc(cp_val(*sp)); + BeamInstr* addr = find_function_from_pc(cp_val(*sp)); if (addr) erts_fprintf(stderr, HEXF ": %T:%T/%bpu\n", @@ -248,9 +248,9 @@ dbg_bt(Process* p, Eterm* sp) } void -dbg_where(UWord* addr, Eterm x0, Eterm* reg) +dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg) { - UWord* f = find_function_from_pc(addr); + BeamInstr* f = find_function_from_pc(addr); if (f == NULL) { erts_fprintf(stderr, "???\n"); @@ -268,18 +268,18 @@ dbg_where(UWord* addr, Eterm x0, Eterm* reg) } static int -print_op(int to, void *to_arg, int op, int size, UWord* addr) +print_op(int to, void *to_arg, int op, int size, BeamInstr* addr) { int i; - UWord tag; + BeamInstr tag; char* sign; char* start_prog; /* Start of program for packer. */ char* prog; /* Current position in packer program. */ - UWord stack[8]; /* Stack for packer. */ - UWord* sp = stack; /* Points to next free position. */ - UWord packed = 0; /* Accumulator for packed operations. */ - UWord args[8]; /* Arguments for this instruction. */ - UWord* ap; /* Pointer to arguments. */ + BeamInstr stack[8]; /* Stack for packer. */ + BeamInstr* sp = stack; /* Points to next free position. */ + BeamInstr packed = 0; /* Accumulator for packed operations. */ + BeamInstr args[8]; /* Arguments for this instruction. */ + BeamInstr* ap; /* Pointer to arguments. */ start_prog = opc[op].pack; @@ -289,7 +289,7 @@ print_op(int to, void *to_arg, int op, int size, UWord* addr) * Avoid copying because instructions containing bignum operands * are bigger than actually declared. */ - ap = (UWord *) addr; + ap = (BeamInstr *) addr; } else { /* * Copy all arguments to a local buffer for the unpacking. @@ -423,8 +423,8 @@ print_op(int to, void *to_arg, int op, int size, UWord* addr) break; case 'f': /* Destination label */ { - UWord* f = find_function_from_pc((UWord *)*ap); - if (f+3 != (UWord *) *ap) { + BeamInstr* f = find_function_from_pc((BeamInstr *)*ap); + if (f+3 != (BeamInstr *) *ap) { erts_print(to, to_arg, "f(" HEXF ")", *ap); } else { erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]); @@ -434,8 +434,8 @@ print_op(int to, void *to_arg, int op, int size, UWord* addr) break; case 'p': /* Pointer (to label) */ { - UWord* f = find_function_from_pc((UWord *)*ap); - if (f+3 != (UWord *) *ap) { + BeamInstr* f = find_function_from_pc((BeamInstr *)*ap); + if (f+3 != (BeamInstr *) *ap) { erts_print(to, to_arg, "p(" HEXF ")", *ap); } else { erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]); @@ -474,7 +474,7 @@ print_op(int to, void *to_arg, int op, int size, UWord* addr) ap++; break; case 'P': /* Byte offset into tuple (see beam_load.c) */ - erts_print(to, to_arg, "%d", (*ap / sizeof(UWord)) - 1); + erts_print(to, to_arg, "%d", (*ap / sizeof(BeamInstr)) - 1); ap++; break; case 'l': /* fr(N) */ diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index d542c56e28..8113e78583 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -117,7 +117,7 @@ do { \ #endif #define GET_BIF_ADDRESS(p) ((BifFunction) (((Export *) p)->code[4])) -#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) +#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm)))) /* @@ -182,11 +182,11 @@ do { \ #define StoreBifResult(Dst, Result) \ do { \ - UWord* stb_next; \ + BeamInstr* stb_next; \ Eterm stb_reg; \ stb_reg = Arg(Dst); \ I += (Dst) + 2; \ - stb_next = (UWord *) *I; \ + stb_next = (BeamInstr *) *I; \ CHECK_TERM(Result); \ switch (beam_reg_tag(stb_reg)) { \ case R_REG_DEF: \ @@ -206,7 +206,7 @@ do { \ c_p->cp = 0; \ } while(0) -#define RESTORE_CP(X) SET_CP(c_p, (UWord *) cp_val(*(X))) +#define RESTORE_CP(X) SET_CP(c_p, (BeamInstr *) cp_val(*(X))) #define ISCATCHEND(instr) ((Eterm *) *(instr) == OpCode(catch_end_y)) @@ -214,13 +214,13 @@ do { \ * Special Beam instructions. */ -UWord beam_apply[2]; -UWord beam_exit[1]; -UWord beam_continue_exit[1]; +BeamInstr beam_apply[2]; +BeamInstr beam_exit[1]; +BeamInstr beam_continue_exit[1]; -UWord* em_call_error_handler; -UWord* em_apply_bif; -UWord* em_call_traced_function; +BeamInstr* em_call_error_handler; +BeamInstr* em_apply_bif; +BeamInstr* em_call_traced_function; /* NOTE These should be the only variables containing trace instructions. @@ -228,9 +228,9 @@ UWord* em_call_traced_function; ** for the refering variable (one of these), and rouge references ** will most likely cause chaos. */ -UWord beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */ -UWord beam_return_trace[1]; /* OpCode(i_return_trace) */ -UWord beam_exception_trace[1]; /* UGLY also OpCode(i_return_trace) */ +BeamInstr beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */ +BeamInstr beam_return_trace[1]; /* OpCode(i_return_trace) */ +BeamInstr beam_exception_trace[1]; /* UGLY also OpCode(i_return_trace) */ /* * All Beam instructions in numerical order. @@ -523,8 +523,8 @@ extern int count_instructions; #define DispatchMacro() \ do { \ - UWord* dis_next; \ - dis_next = (UWord *) *I; \ + BeamInstr* dis_next; \ + dis_next = (BeamInstr *) *I; \ CHECK_ARGS(I); \ if (FCALLS > 0 || FCALLS > neg_o_reds) { \ FCALLS--; \ @@ -536,8 +536,8 @@ extern int count_instructions; #define DispatchMacroFun() \ do { \ - UWord* dis_next; \ - dis_next = (UWord *) *I; \ + BeamInstr* dis_next; \ + dis_next = (BeamInstr *) *I; \ CHECK_ARGS(I); \ if (FCALLS > 0 || FCALLS > neg_o_reds) { \ FCALLS--; \ @@ -591,7 +591,7 @@ extern int count_instructions; ASSERT(VALID_INSTR(*I)); \ Goto(*I) -#define PreFetch(N, Dst) do { Dst = (UWord *) *(I + N + 1); } while (0) +#define PreFetch(N, Dst) do { Dst = (BeamInstr *) *(I + N + 1); } while (0) #define NextPF(N, Dst) \ I += N + 1; \ ASSERT(VALID_INSTR(Dst)); \ @@ -645,7 +645,7 @@ extern int count_instructions; #define DeallocateReturn(Deallocate) \ do { \ int words_to_pop = (Deallocate); \ - SET_I((UWord *) cp_val(*E)); \ + SET_I((BeamInstr *) cp_val(*E)); \ E = ADD_BYTE_OFFSET(E, words_to_pop); \ CHECK_TERM(r(0)); \ Goto(*I); \ @@ -658,19 +658,19 @@ extern int count_instructions; #define MoveCall(Src, Dest, CallDest, Size) \ (Dest) = (Src); \ SET_CP(c_p, I+Size+1); \ - SET_I((UWord *) CallDest); \ + SET_I((BeamInstr *) CallDest); \ Dispatch(); #define MoveCallLast(Src, Dest, CallDest, Deallocate) \ (Dest) = (Src); \ RESTORE_CP(E); \ E = ADD_BYTE_OFFSET(E, (Deallocate)); \ - SET_I((UWord *) CallDest); \ + SET_I((BeamInstr *) CallDest); \ Dispatch(); #define MoveCallOnly(Src, Dest, CallDest) \ (Dest) = (Src); \ - SET_I((UWord *) CallDest); \ + SET_I((BeamInstr *) CallDest); \ Dispatch(); #define GetList(Src, H, T) do { \ @@ -984,23 +984,23 @@ extern int count_instructions; #define IsRef(Src, Fail) if (is_not_ref(Src)) { Fail; } static BifFunction translate_gc_bif(void* gcf); -static UWord* handle_error(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf); -static UWord* next_catch(Process* c_p, Eterm *reg); +static BeamInstr* handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf); +static BeamInstr* next_catch(Process* c_p, Eterm *reg); static void terminate_proc(Process* c_p, Eterm Value); static Eterm add_stacktrace(Process* c_p, Eterm Value, Eterm exc); -static void save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, +static void save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf, Eterm args); static struct StackTrace * get_trace_from_exc(Eterm exc); static Eterm make_arglist(Process* c_p, Eterm* reg, int a); -static Eterm call_error_handler(Process* p, UWord* ip, Eterm* reg); -static Eterm call_breakpoint_handler(Process* p, UWord* fi, Eterm* reg); -static UWord* fixed_apply(Process* p, Eterm* reg, Uint arity); -static UWord* apply(Process* p, Eterm module, Eterm function, +static Eterm call_error_handler(Process* p, BeamInstr* ip, Eterm* reg); +static Eterm call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg); +static BeamInstr* fixed_apply(Process* p, Eterm* reg, Uint arity); +static BeamInstr* apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg); static int hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg); -static UWord* call_fun(Process* p, int arity, Eterm* reg, Eterm args); -static UWord* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg); +static BeamInstr* call_fun(Process* p, int arity, Eterm* reg, Eterm args); +static BeamInstr* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg); static Eterm new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free); #if defined(_OSE_) || defined(VXWORKS) @@ -1088,7 +1088,7 @@ void process_main(void) /* * Pointer to next threaded instruction. */ - register UWord *I REG_I = NULL; + register BeamInstr *I REG_I = NULL; /* Number of reductions left. This function * returns to the scheduler when FCALLS reaches zero. @@ -1194,7 +1194,7 @@ void process_main(void) { int reds; Eterm* argp; - UWord *next; + BeamInstr *next; int i; argp = c_p->arg_reg; @@ -1221,7 +1221,7 @@ void process_main(void) FCALLS = REDS_IN(c_p) = reds; } - next = (UWord *) *I; + next = (BeamInstr *) *I; r(0) = c_p->arg_reg[0]; #ifdef HARDDEBUG if (c_p->arity > 0) { @@ -1313,7 +1313,7 @@ void process_main(void) } /* FALL THROUGH */ OpCase(i_call_only_f): { - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Dispatch(); } @@ -1324,7 +1324,7 @@ void process_main(void) OpCase(i_call_last_fP): { RESTORE_CP(E); E = ADD_BYTE_OFFSET(E, Arg(1)); - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Dispatch(); } @@ -1335,7 +1335,7 @@ void process_main(void) /* FALL THROUGH */ OpCase(i_call_f): { SET_CP(c_p, I+2); - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Dispatch(); } @@ -1371,7 +1371,7 @@ void process_main(void) Dispatchx(); OpCase(init_y): { - UWord *next; + BeamInstr *next; PreFetch(1, next); make_blank(yb(Arg(0))); @@ -1379,7 +1379,7 @@ void process_main(void) } OpCase(i_trim_I): { - UWord *next; + BeamInstr *next; Uint words; Uint cp; @@ -1405,7 +1405,7 @@ void process_main(void) } OpCase(test_heap_1_put_list_Iy): { - UWord *next; + BeamInstr *next; PreFetch(2, next); TestHeap(Arg(0), 1); @@ -1436,7 +1436,7 @@ void process_main(void) */ OpCase(send): { - UWord *next; + BeamInstr *next; Eterm result; PRE_BIF_SWAPOUT(c_p); @@ -1451,7 +1451,7 @@ void process_main(void) NextPF(0, next); } else if (c_p->freason == TRAP) { SET_CP(c_p, I+1); - SET_I(*((UWord **) (UWord) ((c_p)->def_arg_reg + 3))); + SET_I(*((BeamInstr **) (BeamInstr) ((c_p)->def_arg_reg + 3))); SWAPIN; r(0) = c_p->def_arg_reg[0]; x(1) = c_p->def_arg_reg[1]; @@ -1577,7 +1577,7 @@ void process_main(void) */ OpCase(i_loop_rec_fr): { - UWord *next; + BeamInstr *next; ErlMessage* msgp; loop_rec__: @@ -1601,7 +1601,7 @@ void process_main(void) erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE); else { #endif - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Goto(*I); /* Jump to a wait or wait_timeout instruction */ #ifdef ERTS_SMP } @@ -1637,7 +1637,7 @@ void process_main(void) * Remove a (matched) message from the message queue. */ OpCase(remove_message): { - UWord *next; + BeamInstr *next; ErlMessage* msgp; PROCESS_MAIN_CHK_LOCKS(c_p); @@ -1682,7 +1682,7 @@ void process_main(void) * message didn't match), then jump to the loop_rec instruction. */ OpCase(loop_rec_end_f): { - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); SAVE_MESSAGE(c_p); goto loop_rec__; } @@ -1731,13 +1731,13 @@ void process_main(void) * Note that for the halfword emulator, the two first elements * of the array are used. */ - *((UWord **) (UWord) c_p->def_arg_reg) = I+3; + *((BeamInstr **) (UWord) c_p->def_arg_reg) = I+3; set_timer(c_p, unsigned_val(timeout_value)); } else if (timeout_value == am_infinity) { c_p->flags |= F_TIMO; #if !defined(ARCH_64) || HALFWORD_HEAP } else if (term_to_Uint(timeout_value, &time_val)) { - *((UWord **) (UWord) c_p->def_arg_reg) = I+3; + *((BeamInstr **) (UWord) c_p->def_arg_reg) = I+3; set_timer(c_p, time_val); #endif } else { /* Wrong time */ @@ -1766,7 +1766,7 @@ void process_main(void) wait2: { ASSERT(!ERTS_PROC_IS_EXITING(c_p)); - c_p->i = (UWord *) Arg(0); /* L1 */ + c_p->i = (BeamInstr *) Arg(0); /* L1 */ SWAPOUT; c_p->arity = 0; c_p->status = P_WAITING; @@ -1794,7 +1794,7 @@ void process_main(void) * we must test the F_INSLPQUEUE flag as well as the F_TIMO flag. */ if ((c_p->flags & (F_INSLPQUEUE | F_TIMO)) == 0) { - *((UWord **) (UWord) c_p->def_arg_reg) = I+3; + *((BeamInstr **) (UWord) c_p->def_arg_reg) = I+3; set_timer(c_p, Arg(1)); } goto wait2; @@ -1809,7 +1809,7 @@ void process_main(void) } OpCase(timeout): { - UWord *next; + BeamInstr *next; PreFetch(0, next); if (IS_TRACED_FL(c_p, F_TRACE_RECEIVE)) { @@ -1829,8 +1829,8 @@ void process_main(void) do_binary_search: { struct Pairs { - UWord val; - UWord* addr; + BeamInstr val; + BeamInstr* addr; }; struct Pairs* low; struct Pairs* high; @@ -1870,7 +1870,7 @@ void process_main(void) Goto(*I); } } - SET_I((UWord *) Arg(1)); + SET_I((BeamInstr *) Arg(1)); Goto(*I); } @@ -1882,11 +1882,11 @@ void process_main(void) if (is_small(index)) { index = signed_val(index); if (index < Arg(2)) { - SET_I((UWord *) (&Arg(3))[index]); + SET_I((BeamInstr *) (&Arg(3))[index]); Goto(*I); } } - SET_I((UWord *) Arg(1)); + SET_I((BeamInstr *) Arg(1)); Goto(*I); } @@ -1898,11 +1898,11 @@ void process_main(void) if (is_small(index)) { index = (Uint) (signed_val(index) - Arg(3)); if (index < Arg(2)) { - SET_I((UWord *) (&Arg(4))[index]); + SET_I((BeamInstr *) (&Arg(4))[index]); Goto(*I); } } - SET_I((UWord *) Arg(1)); + SET_I((BeamInstr *) Arg(1)); Goto(*I); } @@ -1939,7 +1939,7 @@ void process_main(void) if (is_value(result)) { StoreBifResult(3, result); } - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Goto(*I); } @@ -1979,7 +1979,7 @@ void process_main(void) GcBifFunction bf; Eterm arg; Eterm result; - Uint live = Arg(3); + Uint live = (Uint) Arg(3); GetArg1(2, arg); reg[0] = r(0); @@ -2000,7 +2000,7 @@ void process_main(void) StoreBifResult(4, result); } if (Arg(0) != 0) { - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Goto(*I); } reg[0] = arg; @@ -2028,7 +2028,7 @@ void process_main(void) if (is_value(result)) { StoreBifResult(2, result); } - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Goto(*I); } @@ -2064,7 +2064,7 @@ void process_main(void) */ OpCase(call_bif0_e): { - Eterm (*bf)(Process*, UWord*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, BeamInstr*) = GET_BIF_ADDRESS(Arg(0)); PRE_BIF_SWAPOUT(c_p); c_p->fcalls = FCALLS - 1; @@ -2097,9 +2097,9 @@ void process_main(void) OpCase(call_bif1_e): { - Eterm (*bf)(Process*, Eterm, UWord*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, Eterm, BeamInstr*) = GET_BIF_ADDRESS(Arg(0)); Eterm result; - UWord *next; + BeamInstr *next; c_p->fcalls = FCALLS - 1; if (FCALLS <= 0) { @@ -2132,9 +2132,9 @@ void process_main(void) OpCase(call_bif2_e): { - Eterm (*bf)(Process*, Eterm, Eterm, UWord*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, Eterm, Eterm, BeamInstr*) = GET_BIF_ADDRESS(Arg(0)); Eterm result; - UWord *next; + BeamInstr *next; PRE_BIF_SWAPOUT(c_p); c_p->fcalls = FCALLS - 1; @@ -2169,9 +2169,9 @@ void process_main(void) OpCase(call_bif3_e): { - Eterm (*bf)(Process*, Eterm, Eterm, Eterm, UWord*) = GET_BIF_ADDRESS(Arg(0)); + Eterm (*bf)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = GET_BIF_ADDRESS(Arg(0)); Eterm result; - UWord *next; + BeamInstr *next; PRE_BIF_SWAPOUT(c_p); c_p->fcalls = FCALLS - 1; @@ -2192,7 +2192,7 @@ void process_main(void) } else if (c_p->freason == TRAP) { call_bif_trap3: SET_CP(c_p, I+2); - SET_I(*((UWord **) (UWord) ((c_p)->def_arg_reg + 3))); + SET_I(*((BeamInstr **) (UWord) ((c_p)->def_arg_reg + 3))); SWAPIN; r(0) = c_p->def_arg_reg[0]; x(1) = c_p->def_arg_reg[1]; @@ -2300,7 +2300,7 @@ void process_main(void) lb_Cl_error: { if (Arg(0) != 0) { OpCase(jump_f): { - SET_I((UWord *) Arg(0)); + SET_I((BeamInstr *) Arg(0)); Goto(*I); } } @@ -2492,7 +2492,7 @@ void process_main(void) goto lb_Cl_error; OpCase(i_apply): { - UWord *next; + BeamInstr *next; SWAPOUT; next = apply(c_p, r(0), x(1), x(2), reg); SWAPIN; @@ -2507,13 +2507,13 @@ void process_main(void) } OpCase(i_apply_last_P): { - UWord *next; + BeamInstr *next; SWAPOUT; next = apply(c_p, r(0), x(1), x(2), reg); SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); + SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(0)); SET_I(next); Dispatch(); @@ -2523,7 +2523,7 @@ void process_main(void) } OpCase(i_apply_only): { - UWord *next; + BeamInstr *next; SWAPOUT; next = apply(c_p, r(0), x(1), x(2), reg); SWAPIN; @@ -2537,7 +2537,7 @@ void process_main(void) } OpCase(apply_I): { - UWord *next; + BeamInstr *next; reg[0] = r(0); SWAPOUT; @@ -2554,7 +2554,7 @@ void process_main(void) } OpCase(apply_last_IP): { - UWord *next; + BeamInstr *next; reg[0] = r(0); SWAPOUT; @@ -2562,7 +2562,7 @@ void process_main(void) SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); + SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(1)); SET_I(next); Dispatch(); @@ -2572,7 +2572,7 @@ void process_main(void) } OpCase(i_apply_fun): { - UWord *next; + BeamInstr *next; SWAPOUT; next = apply_fun(c_p, r(0), x(1), reg); @@ -2587,14 +2587,14 @@ void process_main(void) } OpCase(i_apply_fun_last_P): { - UWord *next; + BeamInstr *next; SWAPOUT; next = apply_fun(c_p, r(0), x(1), reg); SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); + SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(0)); SET_I(next); Dispatchfun(); @@ -2603,7 +2603,7 @@ void process_main(void) } OpCase(i_apply_fun_only): { - UWord *next; + BeamInstr *next; SWAPOUT; next = apply_fun(c_p, r(0), x(1), reg); @@ -2617,7 +2617,7 @@ void process_main(void) } OpCase(i_call_fun_I): { - UWord *next; + BeamInstr *next; SWAPOUT; reg[0] = r(0); @@ -2633,7 +2633,7 @@ void process_main(void) } OpCase(i_call_fun_last_IP): { - UWord *next; + BeamInstr *next; SWAPOUT; reg[0] = r(0); @@ -2641,7 +2641,7 @@ void process_main(void) SWAPIN; if (next != NULL) { r(0) = reg[0]; - SET_CP(c_p, (UWord *) EXPAND_POINTER(E[0])); + SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0])); E = ADD_BYTE_OFFSET(E, Arg(1)); SET_I(next); Dispatchfun(); @@ -2746,7 +2746,7 @@ void process_main(void) tmp_arg1 = *tuple_val(tmp_arg1); goto do_binary_search; } - SET_I((UWord *) Arg(1)); + SET_I((BeamInstr *) Arg(1)); Goto(*I); } @@ -2778,9 +2778,9 @@ void process_main(void) } while (bigp[0] == given_arity) { if (memcmp(bigp+1, given+1, sizeof(Eterm)*given_size) == 0) { - UWord *tmp = - ((UWord *) (UWord) bigp) + TermWords(given_size + 1); - SET_I((UWord *) *tmp); + BeamInstr *tmp = + ((BeamInstr *) (UWord) bigp) + TermWords(given_size + 1); + SET_I((BeamInstr *) *tmp); Goto(*I); } bigp += thing_arityval(arity) + 2; @@ -2791,7 +2791,7 @@ void process_main(void) * Failed. */ - SET_I((UWord *) Arg(1)); + SET_I((BeamInstr *) Arg(1)); Goto(*I); } @@ -2802,7 +2802,7 @@ void process_main(void) int n; struct ValLabel { Uint f; - UWord* addr; + BeamInstr* addr; }; struct ValLabel* ptr; @@ -2830,7 +2830,7 @@ void process_main(void) struct ValLabel { Uint fpart1; Uint fpart2; - UWord* addr; + BeamInstr* addr; }; struct ValLabel* ptr; @@ -2848,7 +2848,7 @@ void process_main(void) } ptr++; } - SET_I((UWord *) Arg(1)); + SET_I((BeamInstr *) Arg(1)); Goto(*I); } #endif @@ -2856,7 +2856,7 @@ void process_main(void) OpCase(set_tuple_element_sdP): { Eterm element; Eterm tuple; - UWord *next; + BeamInstr *next; Eterm* p; PreFetch(3, next); @@ -3051,7 +3051,7 @@ void process_main(void) switch (tmp_arg2) { case 3: { - Eterm (*bf)(Process*, Eterm, Eterm, Eterm, UWord*) = vbf; + Eterm (*bf)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, r(0), x(1), x(2), I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3060,7 +3060,7 @@ void process_main(void) break; case 2: { - Eterm (*bf)(Process*, Eterm, Eterm, UWord*) = vbf; + Eterm (*bf)(Process*, Eterm, Eterm, BeamInstr*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, r(0), x(1), I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3069,7 +3069,7 @@ void process_main(void) break; case 1: { - Eterm (*bf)(Process*, Eterm, UWord*) = vbf; + Eterm (*bf)(Process*, Eterm, BeamInstr*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, r(0), I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3078,7 +3078,7 @@ void process_main(void) break; case 0: { - Eterm (*bf)(Process*, UWord*) = vbf; + Eterm (*bf)(Process*, BeamInstr*) = vbf; ASSERT(!ERTS_PROC_IS_EXITING(c_p)); tmp_arg1 = (*bf)(c_p, I); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); @@ -3102,7 +3102,7 @@ apply_bif_or_nif_epilogue: SET_I(c_p->cp); Goto(*I); } else if (c_p->freason == TRAP) { - SET_I(*((UWord **) (UWord) ((c_p)->def_arg_reg + 3))); + 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]; @@ -3560,7 +3560,7 @@ apply_bif_or_nif_epilogue: OpCase(bs_put_string_II): { - UWord *next; + BeamInstr *next; PreFetch(2, next); erts_new_bs_put_string(ERL_BITS_ARGS_2((byte *) Arg(1), Arg(0))); NextPF(2, next); @@ -3731,7 +3731,7 @@ apply_bif_or_nif_epilogue: { Eterm header; - UWord *next; + BeamInstr *next; Uint slots; OpCase(i_bs_start_match2_rfIId): { @@ -3797,7 +3797,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_zero_tail2_fr): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(1, next); @@ -3809,7 +3809,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_zero_tail2_fx): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); @@ -3821,7 +3821,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_tail_imm2_frI): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); _mb = ms_matchbuffer(r(0)); @@ -3831,7 +3831,7 @@ apply_bif_or_nif_epilogue: NextPF(2, next); } OpCase(bs_test_tail_imm2_fxI): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(3, next); _mb = ms_matchbuffer(xb(Arg(1))); @@ -3842,7 +3842,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_unit_frI): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); _mb = ms_matchbuffer(r(0)); @@ -3852,7 +3852,7 @@ apply_bif_or_nif_epilogue: NextPF(2, next); } OpCase(bs_test_unit_fxI): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(3, next); _mb = ms_matchbuffer(xb(Arg(1))); @@ -3863,7 +3863,7 @@ apply_bif_or_nif_epilogue: } OpCase(bs_test_unit8_fr): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(1, next); _mb = ms_matchbuffer(r(0)); @@ -3873,7 +3873,7 @@ apply_bif_or_nif_epilogue: NextPF(1, next); } OpCase(bs_test_unit8_fx): { - UWord *next; + BeamInstr *next; ErlBinMatchBuffer *_mb; PreFetch(2, next); _mb = ms_matchbuffer(xb(Arg(1))); @@ -4198,7 +4198,7 @@ apply_bif_or_nif_epilogue: do_bs_match_string: { - UWord *next; + BeamInstr *next; byte* bytes; Uint bits; ErlBinMatchBuffer* mb; @@ -4225,7 +4225,7 @@ apply_bif_or_nif_epilogue: } OpCase(i_bs_save2_rI): { - UWord *next; + BeamInstr *next; ErlBinMatchState *_ms; PreFetch(1, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) r(0)); @@ -4233,7 +4233,7 @@ apply_bif_or_nif_epilogue: NextPF(1, next); } OpCase(i_bs_save2_xI): { - UWord *next; + BeamInstr *next; ErlBinMatchState *_ms; PreFetch(2, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) xb(Arg(0))); @@ -4242,7 +4242,7 @@ apply_bif_or_nif_epilogue: } OpCase(i_bs_restore2_rI): { - UWord *next; + BeamInstr *next; ErlBinMatchState *_ms; PreFetch(1, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) r(0)); @@ -4250,7 +4250,7 @@ apply_bif_or_nif_epilogue: NextPF(1, next); } OpCase(i_bs_restore2_xI): { - UWord *next; + BeamInstr *next; ErlBinMatchState *_ms; PreFetch(2, next); _ms = (ErlBinMatchState*) boxed_val((Eterm) xb(Arg(0))); @@ -4267,7 +4267,7 @@ apply_bif_or_nif_epilogue: * deallocate not followed by a return, and that should work. */ OpCase(deallocate_I): { - UWord *next; + BeamInstr *next; PreFetch(1, next); D(Arg(0)); @@ -4317,7 +4317,7 @@ apply_bif_or_nif_epilogue: } E -= 3; ASSERT(c_p->htop <= E && E <= c_p->hend); - ASSERT(is_CP((UWord)(ep->code))); + ASSERT(is_CP((BeamInstr)(ep->code))); ASSERT(is_internal_pid(c_p->tracer_proc) || is_internal_port(c_p->tracer_proc)); E[2] = make_cp(c_p->cp); /* XXX:PaN - code in lower range on halfword */ @@ -4330,12 +4330,12 @@ apply_bif_or_nif_epilogue: erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_ALL_MINOR); } } - SET_I((UWord *)Arg(0)); + SET_I((BeamInstr *)Arg(0)); Dispatch(); } OpCase(return_trace): { - UWord* code = (UWord *) (UWord) E[0]; + BeamInstr* code = (BeamInstr *) (UWord) E[0]; SWAPOUT; /* Needed for shared heap */ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p); @@ -4343,24 +4343,24 @@ apply_bif_or_nif_epilogue: ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p); SWAPIN; c_p->cp = NULL; - SET_I((UWord *) cp_val(E[2])); + SET_I((BeamInstr *) cp_val(E[2])); E += 3; Goto(*I); } OpCase(i_count_breakpoint): { - UWord real_I; + BeamInstr real_I; - ErtsCountBreak((UWord *) I, &real_I); + ErtsCountBreak((BeamInstr *) I, &real_I); ASSERT(VALID_INSTR(real_I)); Goto(real_I); } OpCase(i_trace_breakpoint): if (! IS_TRACED_FL(c_p, F_TRACE_CALLS)) { - UWord real_I; + BeamInstr real_I; - ErtsBreakSkip((UWord *) I, &real_I); + ErtsBreakSkip((BeamInstr *) I, &real_I); Goto(real_I); } /* Fall through to next case */ @@ -4374,10 +4374,10 @@ apply_bif_or_nif_epilogue: SWAPOUT; reg[0] = r(0); - if (*(c_p->cp) == (UWord) OpCode(return_trace)) { + if (*(c_p->cp) == (BeamInstr) OpCode(return_trace)) { cpp = (Uint*)&E[2]; } else if (*(c_p->cp) - == (UWord) OpCode(i_return_to_trace)) { + == (BeamInstr) OpCode(i_return_to_trace)) { return_to_trace = !0; cpp = (Uint*)&E[0]; } else { @@ -4388,18 +4388,18 @@ apply_bif_or_nif_epilogue: * return_trace and/or i_return_to_trace stackframes * on the stack, they are not intermixed with y registers */ - UWord *cp_save = c_p->cp; + BeamInstr *cp_save = c_p->cp; for (;;) { ASSERT(is_CP(*cpp)); - if (*cp_val(*cpp) == (UWord) OpCode(return_trace)) { + if (*cp_val(*cpp) == (BeamInstr) OpCode(return_trace)) { cpp += 3; - } else if (*cp_val(*cpp) == (UWord) OpCode(i_return_to_trace)) { + } else if (*cp_val(*cpp) == (BeamInstr) OpCode(i_return_to_trace)) { return_to_trace = !0; cpp += 1; } else break; } - c_p->cp = (UWord *) cp_val(*cpp); + c_p->cp = (BeamInstr *) cp_val(*cpp); ASSERT(is_CP(*cpp)); ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p); real_I = erts_trace_break(c_p, I, reg, &flags, &tracer_pid); @@ -4436,7 +4436,7 @@ apply_bif_or_nif_epilogue: E -= 1; ASSERT(c_p->htop <= E && E <= c_p->hend); E[0] = make_cp(c_p->cp); - c_p->cp = (UWord *) beam_return_to_trace; + c_p->cp = (BeamInstr *) beam_return_to_trace; } if (flags & MATCH_SET_RX_TRACE) { E -= 3; @@ -4464,10 +4464,10 @@ apply_bif_or_nif_epilogue: Uint *cpp = (Uint*) E; for(;;) { ASSERT(is_CP(*cpp)); - if (*cp_val(*cpp) == (UWord) OpCode(return_trace)) { + if (*cp_val(*cpp) == (BeamInstr) OpCode(return_trace)) { do ++cpp; while(is_not_CP(*cpp)); cpp += 2; - } else if (*cp_val(*cpp) == (UWord) OpCode(i_return_to_trace)) { + } else if (*cp_val(*cpp) == (BeamInstr) OpCode(i_return_to_trace)) { do ++cpp; while(is_not_CP(*cpp)); } else break; } @@ -4478,7 +4478,7 @@ apply_bif_or_nif_epilogue: SWAPIN; } c_p->cp = NULL; - SET_I((UWord *) cp_val(E[0])); + SET_I((BeamInstr *) cp_val(E[0])); E += 1; Goto(*I); } @@ -4489,7 +4489,7 @@ apply_bif_or_nif_epilogue: OpCase(i_global_cons): { - UWord *next; + BeamInstr *next; #ifdef HYBRID Eterm *hp; @@ -4511,7 +4511,7 @@ apply_bif_or_nif_epilogue: OpCase(i_global_tuple): { - UWord *next; + BeamInstr *next; int len; #ifdef HYBRID Eterm list; @@ -4546,7 +4546,7 @@ apply_bif_or_nif_epilogue: OpCase(i_global_copy): { - UWord *next; + BeamInstr *next; PreFetch(0,next); #ifdef HYBRID if (!IS_CONST(r(0))) @@ -4575,7 +4575,7 @@ apply_bif_or_nif_epilogue: OpCase(fmove_ql): { Eterm fr = Arg(1); - UWord *next; + BeamInstr *next; PreFetch(2, next); GET_DOUBLE(Arg(0), *(FloatDef*)ADD_BYTE_OFFSET(freg, fr)); @@ -4585,7 +4585,7 @@ apply_bif_or_nif_epilogue: OpCase(fmove_dl): { Eterm targ1; Eterm fr = Arg(1); - UWord *next; + BeamInstr *next; PreFetch(2, next); GetR(0, targ1); @@ -4606,7 +4606,7 @@ apply_bif_or_nif_epilogue: OpCase(fconv_dl): { Eterm targ1; Eterm fr = Arg(1); - UWord *next; + BeamInstr *next; GetR(0, targ1); PreFetch(2, next); @@ -4635,7 +4635,7 @@ apply_bif_or_nif_epilogue: erl_exit(1, "fclearerror/i_fcheckerror without fpe signals (beam_emu)"); #else OpCase(fclearerror): { - UWord *next; + BeamInstr *next; PreFetch(0, next); ERTS_FP_CHECK_INIT(c_p); @@ -4643,7 +4643,7 @@ apply_bif_or_nif_epilogue: } OpCase(i_fcheckerror): { - UWord *next; + BeamInstr *next; PreFetch(0, next); ERTS_FP_ERROR(c_p, freg[0].fd, goto fbadarith); @@ -4657,7 +4657,7 @@ apply_bif_or_nif_epilogue: OpCase(i_fadd_lll): { - UWord *next; + BeamInstr *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4666,7 +4666,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fsub_lll): { - UWord *next; + BeamInstr *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4675,7 +4675,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fmul_lll): { - UWord *next; + BeamInstr *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4684,7 +4684,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fdiv_lll): { - UWord *next; + BeamInstr *next; PreFetch(3, next); ERTS_FP_CHECK_INIT(c_p); @@ -4693,7 +4693,7 @@ apply_bif_or_nif_epilogue: NextPF(3, next); } OpCase(i_fnegate_ll): { - UWord *next; + BeamInstr *next; PreFetch(2, next); ERTS_FP_CHECK_INIT(c_p); @@ -4772,7 +4772,7 @@ apply_bif_or_nif_epilogue: /* This can be used to call any function value, but currently it's only used to call closures referring to unloaded modules. */ { - UWord *next; + BeamInstr *next; next = call_fun(c_p, c_p->arity - 1, reg, THE_NON_VALUE); SWAPIN; @@ -4921,8 +4921,8 @@ apply_bif_or_nif_epilogue: bif_table[i].name, bif_table[i].arity); bif_export[i] = ep; - ep->code[3] = (UWord) OpCode(apply_bif); - ep->code[4] = (UWord) bif_table[i].f; + ep->code[3] = (BeamInstr) OpCode(apply_bif); + ep->code[4] = (BeamInstr) bif_table[i].f; } return; @@ -5025,8 +5025,8 @@ Eterm error_atom[NUMBER_EXIT_CODES] = { * at the point of the original exception. */ -static UWord* -handle_error(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf) +static BeamInstr* +handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf) { Eterm* hp; Eterm Value = c_p->fvalue; @@ -5080,7 +5080,7 @@ handle_error(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf) /* Find a handler or die */ if ((c_p->catches > 0 || IS_TRACED_FL(c_p, F_EXCEPTION_TRACE)) && !(c_p->freason & EXF_PANIC)) { - UWord *new_pc; + BeamInstr *new_pc; /* The Beam handler code (catch_end or try_end) checks reg[0] for THE_NON_VALUE to see if the previous code finished abnormally. If so, reg[1], reg[2] and reg[3] should hold the @@ -5106,13 +5106,13 @@ handle_error(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf) /* * Find the nearest catch handler */ -static UWord* +static BeamInstr* next_catch(Process* c_p, Eterm *reg) { int active_catches = c_p->catches > 0; int have_return_to_trace = 0; Eterm *ptr, *prev, *return_to_trace_ptr = NULL; - UWord i_return_trace = beam_return_trace[0]; - UWord i_return_to_trace = beam_return_to_trace[0]; + BeamInstr i_return_trace = beam_return_trace[0]; + BeamInstr i_return_to_trace = beam_return_to_trace[0]; ptr = prev = c_p->stop; ASSERT(is_CP(*ptr)); ASSERT(ptr <= STACK_START(c_p)); @@ -5121,7 +5121,7 @@ next_catch(Process* c_p, Eterm *reg) { *cp_val(*ptr) != i_return_to_trace)) && c_p->cp) { /* Can not follow cp here - code may be unloaded */ - UWord *cpp = c_p->cp; + BeamInstr *cpp = c_p->cp; if (cpp == beam_exception_trace) { erts_trace_exception(c_p, cp_val(ptr[0]), reg[1], reg[2], ptr+1); @@ -5276,7 +5276,7 @@ expand_error_value(Process* c_p, Uint freason, Eterm Value) { */ static void -save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, +save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf, Eterm args) { struct StackTrace* s; int sz; @@ -5287,7 +5287,7 @@ save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, } /* Create a container for the exception data */ - sz = (offsetof(struct StackTrace, trace) + sizeof(UWord *)*depth + sz = (offsetof(struct StackTrace, trace) + sizeof(BeamInstr *)*depth + sizeof(Eterm) - 1) / sizeof(Eterm); s = (struct StackTrace *) HAlloc(c_p, 1 + sz); /* The following fields are inside the bignum */ @@ -5375,9 +5375,9 @@ save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, /* Save the actual stack trace */ if (depth > 0) { Eterm *ptr; - UWord *prev = s->depth ? s->trace[s->depth-1] : NULL; - UWord i_return_trace = beam_return_trace[0]; - UWord i_return_to_trace = beam_return_to_trace[0]; + BeamInstr *prev = s->depth ? s->trace[s->depth-1] : NULL; + BeamInstr i_return_trace = beam_return_trace[0]; + BeamInstr i_return_to_trace = beam_return_to_trace[0]; /* * Traverse the stack backwards and add all unique continuation * pointers to the buffer, up to the maximum stack trace size. @@ -5390,7 +5390,7 @@ save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, *cp_val(*ptr) != i_return_to_trace)) && c_p->cp) { /* Can not follow cp here - code may be unloaded */ - UWord *cpp = c_p->cp; + BeamInstr *cpp = c_p->cp; if (cpp == beam_exception_trace || cpp == beam_return_trace) { /* Skip return_trace parameters */ ptr += 2; @@ -5410,7 +5410,7 @@ save_stacktrace(Process* c_p, UWord* pc, Eterm* reg, BifFunction bf, /* Skip stack frame variables */ do ++ptr; while (is_not_CP(*ptr)); } else { - UWord *cp = cp_val(*ptr); + BeamInstr *cp = cp_val(*ptr); if (cp != prev) { /* Record non-duplicates only */ prev = cp; @@ -5482,9 +5482,9 @@ build_stacktrace(Process* c_p, Eterm exc) { struct StackTrace* s; Eterm args; int depth; - UWord* current; + BeamInstr* current; #if HALFWORD_HEAP - UWord current_buff[3]; + BeamInstr current_buff[3]; #endif Eterm Where = NIL; Eterm *next_p = &Where; @@ -5517,9 +5517,9 @@ build_stacktrace(Process* c_p, Eterm exc) { if (current == NULL) { #if HALFWORD_HEAP current = current_buff; - current[0] = (UWord) c_p->initial[0]; - current[1] = (UWord) c_p->initial[1]; - current[2] = (UWord) c_p->initial[2]; + current[0] = (BeamInstr) c_p->initial[0]; + current[1] = (BeamInstr) c_p->initial[1]; + current[2] = (BeamInstr) c_p->initial[2]; #else current = c_p->initial; #endif @@ -5558,7 +5558,7 @@ build_stacktrace(Process* c_p, Eterm exc) { * Finally, we go through the saved continuation pointers. */ for (i = 0; i < depth; i++) { - UWord *fi = find_function_from_pc((UWord *) s->trace[i]); + BeamInstr *fi = find_function_from_pc((BeamInstr *) s->trace[i]); if (fi == NULL) continue; mfa = TUPLE3(hp, fi[0], fi[1], make_small(fi[2])); hp += 4; @@ -5575,7 +5575,7 @@ build_stacktrace(Process* c_p, Eterm exc) { static Eterm -call_error_handler(Process* p, UWord* fi, Eterm* reg) +call_error_handler(Process* p, BeamInstr* fi, Eterm* reg) { Eterm* hp; Export* ep; @@ -5623,7 +5623,7 @@ call_error_handler(Process* p, UWord* fi, Eterm* reg) } static Eterm -call_breakpoint_handler(Process* p, UWord* fi, Eterm* reg) +call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg) { Eterm* hp; Export* ep; @@ -5716,7 +5716,7 @@ apply_setup_error_handler(Process* p, Eterm module, Eterm function, Uint arity, return ep; } -static UWord* +static BeamInstr* apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg) { int arity; @@ -5798,7 +5798,7 @@ apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg) return ep->address; } -static UWord* +static BeamInstr* fixed_apply(Process* p, Eterm* reg, Uint arity) { Export* ep; @@ -5904,7 +5904,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg) c_p->stop = STACK_START(c_p); c_p->catches = 0; c_p->i = beam_apply; - c_p->cp = (UWord *) beam_apply+1; + c_p->cp = (BeamInstr *) beam_apply+1; /* * If there are no waiting messages, garbage collect and @@ -5934,7 +5934,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg) return 1; } -static UWord* +static BeamInstr* call_fun(Process* p, /* Current process. */ int arity, /* Number of arguments for Fun. */ Eterm* reg, /* Contents of registers. */ @@ -5954,7 +5954,7 @@ call_fun(Process* p, /* Current process. */ if (is_fun_header(hdr)) { ErlFunThing* funp = (ErlFunThing *) fun_val(fun); ErlFunEntry* fe; - UWord* code_ptr; + BeamInstr* code_ptr; Eterm* var_ptr; int actual_arity; unsigned num_free; @@ -6117,7 +6117,7 @@ call_fun(Process* p, /* Current process. */ } } -static UWord* +static BeamInstr* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg) { int arity; @@ -6211,7 +6211,7 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity) if ((ep = export_get(&e)) == NULL) { return 0; } - return ep->address == ep->code+3 && (ep->code[3] == (UWord) em_apply_bif); + return ep->address == ep->code+3 && (ep->code[3] == (BeamInstr) em_apply_bif); } diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index b928b04210..5b56002d3b 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -51,9 +51,9 @@ ErlDrvBinary* erts_gzinflate_buffer(char*, int); #define EXPORTED 2 #ifdef NO_JUMP_TABLE -# define BeamOpCode(Op) ((UWord)(Op)) +# define BeamOpCode(Op) ((BeamInstr)(Op)) #else -# define BeamOpCode(Op) ((UWord)beam_ops[Op]) +# define BeamOpCode(Op) ((BeamInstr)beam_ops[Op]) #endif #if defined(WORDS_BIGENDIAN) @@ -94,7 +94,7 @@ typedef struct { typedef struct { unsigned type; /* Type of operand. */ - UWord val; /* Value of operand. */ + BeamInstr val; /* Value of operand. */ Uint bigarity; /* Arity for bignumbers (only). */ } GenOpArg; @@ -142,7 +142,7 @@ typedef struct { typedef struct { Eterm function; /* Tagged atom for function. */ int arity; /* Arity. */ - UWord* address; /* Address to function in code. */ + BeamInstr* address; /* Address to function in code. */ } ExportEntry; #define MakeIffId(a, b, c, d) \ @@ -274,13 +274,13 @@ typedef struct { int num_functions; /* Number of functions in module. */ int num_labels; /* Number of labels. */ int code_buffer_size; /* Size of code buffer in words. */ - UWord* code; /* Loaded code. */ + BeamInstr* code; /* Loaded code. */ int ci; /* Current index into loaded code. */ Label* labels; - UWord put_strings; /* Linked list of put_string instructions. */ - UWord new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */ + BeamInstr put_strings; /* Linked list of put_string instructions. */ + BeamInstr new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */ StringPatch* string_patches; /* Linked list of position into string table to patch. */ - UWord catches; /* Linked list of catch_yf instructions. */ + BeamInstr catches; /* Linked list of catch_yf instructions. */ unsigned loaded_size; /* Final size of code when loaded. */ byte mod_md5[16]; /* MD5 for module code. */ int may_load_nif; /* true if NIFs may later be loaded for this module */ @@ -341,7 +341,7 @@ typedef struct { #define GetTagAndValue(Stp, Tag, Val) \ do { \ - UWord __w; \ + BeamInstr __w; \ GetByte(Stp, __w); \ Tag = __w & 0x07; \ if ((__w & 0x08) == 0) { \ @@ -388,7 +388,7 @@ typedef struct { goto load_error; \ } else { \ int __n = (N); \ - UWord __result = 0; \ + BeamInstr __result = 0; \ Stp->file_left -= (unsigned) __n; \ while (__n-- > 0) { \ __result = __result << 8 | *Stp->file_p++; \ @@ -465,7 +465,7 @@ static int bin_load(Process *c_p, ErtsProcLocks c_p_locks, static void init_state(LoaderState* stp); static int insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, Eterm group_leader, Eterm module, - UWord* code, Uint size, UWord catches); + BeamInstr* code, Uint size, BeamInstr catches); static int scan_iff_file(LoaderState* stp, Uint* chunk_types, Uint num_types, Uint num_mandatory); static int load_atom_table(LoaderState* stp); @@ -499,8 +499,8 @@ static void load_printf(int line, LoaderState* context, char *fmt, ...); static int transform_engine(LoaderState* st); static void id_to_string(Uint id, char* s); static void new_genop(LoaderState* stp); -static int get_int_val(LoaderState* stp, Uint len_code, UWord* result); -static int get_erlang_integer(LoaderState* stp, Uint len_code, UWord* result); +static int get_int_val(LoaderState* stp, Uint len_code, BeamInstr* result); +static int get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result); static int new_label(LoaderState* stp); static void new_literal_patch(LoaderState* stp, int pos); static void new_string_patch(LoaderState* stp, int pos); @@ -592,7 +592,8 @@ erts_load_module(Process *c_p, return result; } -#ifdef DEBUG +#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG) +/* Requires allocators ERTS_ALLOC_UTIL_HARD_DEBUG also set in erl_alloc_util.h */ extern void check_allocators(void); extern void check_allocated_block(Uint type, void *blk); #define CHKALLOC() check_allocators() @@ -617,8 +618,8 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, * Scan the IFF file. */ -#ifdef DEBUG - fprintf(stderr,"Loading a module\r\n"); +#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG) + erts_fprintf(stderr,"Loading a module\n"); #endif CHKALLOC(); @@ -785,8 +786,8 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.genop_blocks); state.genop_blocks = next; } -#ifdef DEBUG - erts_fprintf(stderr,"Loaded %T\r\n",*modp); +#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG) + erts_fprintf(stderr,"Loaded %T\n",*modp); #endif return rval; @@ -824,7 +825,7 @@ init_state(LoaderState* stp) static int insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, - Eterm group_leader, Eterm module, UWord* code, Uint size, UWord catches) + Eterm group_leader, Eterm module, BeamInstr* code, Uint size, BeamInstr catches) { Module* modp; int rval; @@ -866,7 +867,7 @@ insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, modules[i] = modules[i-1]; } modules[i].start = code; - modules[i].end = (UWord *) (((byte *)code) + size); + modules[i].end = (BeamInstr *) (((byte *)code) + size); num_loaded_modules++; mid_module = &modules[num_loaded_modules/2]; return 0; @@ -1116,7 +1117,7 @@ load_import_table(LoaderState* stp) * the BIF function. */ if ((e = erts_find_export_entry(mod, func, arity)) != NULL) { - if (e->code[3] == (UWord) em_apply_bif) { + if (e->code[3] == (BeamInstr) em_apply_bif) { stp->import[i].bf = (BifFunction) e->code[4]; if (func == am_load_nif && mod == am_erlang && arity == 2) { stp->may_load_nif = 1; @@ -1184,7 +1185,7 @@ read_export_table(LoaderState* stp) * redefine). */ if ((e = erts_find_export_entry(stp->module, func, arity)) != NULL) { - if (e->code[3] == (UWord) em_apply_bif) { + if (e->code[3] == (BeamInstr) em_apply_bif) { int j; for (j = 0; j < sizeof(allow_redef)/sizeof(allow_redef[0]); j++) { @@ -1253,7 +1254,7 @@ static int read_literal_table(LoaderState* stp) { int i; - UWord uncompressed_sz; + BeamInstr uncompressed_sz; byte* uncompressed = 0; GetInt(stp, 4, uncompressed_sz); @@ -1371,8 +1372,8 @@ read_code_header(LoaderState* stp) * Initialize code area. */ stp->code_buffer_size = erts_next_heap_size(2048 + stp->num_functions, 0); - stp->code = (UWord *) erts_alloc(ERTS_ALC_T_CODE, - sizeof(UWord) * stp->code_buffer_size); + stp->code = (BeamInstr *) erts_alloc(ERTS_ALC_T_CODE, + sizeof(BeamInstr) * stp->code_buffer_size); stp->code[MI_NUM_FUNCTIONS] = stp->num_functions; stp->ci = MI_FUNCTIONS + stp->num_functions + 1; @@ -1403,13 +1404,13 @@ read_code_header(LoaderState* stp) if (code_buffer_size < ci+(w)) { \ code_buffer_size = erts_next_heap_size(ci+(w), 0); \ stp->code = code \ - = (UWord *) erts_realloc(ERTS_ALC_T_CODE, \ + = (BeamInstr *) erts_realloc(ERTS_ALC_T_CODE, \ (void *) code, \ - code_buffer_size * sizeof(UWord)); \ + code_buffer_size * sizeof(BeamInstr)); \ } \ } while (0) -#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) +#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm)))) static int @@ -1422,7 +1423,7 @@ load_code(LoaderState* stp) char* sign; int arg; /* Number of current argument. */ int num_specific; /* Number of specific ops for current. */ - UWord* code; + BeamInstr* code; int code_buffer_size; int specific; Uint last_label = 0; /* Number of last label. */ @@ -1481,7 +1482,7 @@ load_code(LoaderState* stp) if (((First) & 0x08) == 0) { \ Val = (First) >> 4; \ } else if (((First) & 0x10) == 0) { \ - UWord __w; \ + BeamInstr __w; \ GetByte(Stp, __w); \ Val = (((First) >> 5) << 8) | __w; \ } else { \ @@ -1490,7 +1491,7 @@ load_code(LoaderState* stp) } while (0) for (arg = 0; arg < arity; arg++) { - UWord first; + BeamInstr first; GetByte(stp, first); last_op->a[arg].type = first & 0x07; @@ -1499,7 +1500,7 @@ load_code(LoaderState* stp) if ((first & 0x08) == 0) { last_op->a[arg].val = first >> 4; } else if ((first & 0x10) == 0) { - UWord w; + BeamInstr w; GetByte(stp, w); ASSERT(first < 0x800); last_op->a[arg].val = ((first >> 5) << 8) | w; @@ -1558,7 +1559,7 @@ load_code(LoaderState* stp) break; case TAG_z: { - UWord ext_tag; + BeamInstr ext_tag; unsigned tag; GetValue(stp, first, ext_tag); @@ -1610,10 +1611,10 @@ load_code(LoaderState* stp) break; case 3: /* Allocation list. */ { - UWord n; - UWord type; - UWord val; - UWord words = 0; + BeamInstr n; + BeamInstr type; + BeamInstr val; + BeamInstr words = 0; stp->new_float_instructions = 1; GetTagAndValue(stp, tag, n); @@ -1642,7 +1643,7 @@ load_code(LoaderState* stp) } case 4: /* Literal. */ { - UWord val; + BeamInstr val; GetTagAndValue(stp, tag, val); VerifyTag(stp, tag, TAG_u); @@ -1807,7 +1808,7 @@ load_code(LoaderState* stp) case 'c': /* Tagged constant */ switch (tag) { case TAG_i: - code[ci++] = (UWord) make_small((Uint) tmp_op->a[arg].val); + code[ci++] = (BeamInstr) make_small((Uint) tmp_op->a[arg].val); break; case TAG_a: code[ci++] = tmp_op->a[arg].val; @@ -1837,7 +1838,7 @@ load_code(LoaderState* stp) code[ci++] = make_yreg(tmp_op->a[arg].val); break; case TAG_i: - code[ci++] = (UWord) make_small((Uint)tmp_op->a[arg].val); + code[ci++] = (BeamInstr) make_small((Uint)tmp_op->a[arg].val); break; case TAG_a: code[ci++] = tmp_op->a[arg].val; @@ -1931,12 +1932,12 @@ load_code(LoaderState* stp) if (stp->import[i].bf == NULL) { LoadError1(stp, "not a BIF: import table index %d", i); } - code[ci++] = (UWord) stp->import[i].bf; + code[ci++] = (BeamInstr) stp->import[i].bf; break; case 'P': /* Byte offset into tuple */ /* XXX:PaN - * sizeof(Eterm or Eterm *) ? */ VerifyTag(stp, tag, TAG_u); tmp = tmp_op->a[arg].val; - code[ci++] = (UWord) ((tmp_op->a[arg].val+1) * sizeof(Eterm)); + code[ci++] = (BeamInstr) ((tmp_op->a[arg].val+1) * sizeof(Eterm)); break; case 'l': /* Floating point register. */ VerifyTag(stp, tag_to_letter[tag], *sign); @@ -2090,8 +2091,8 @@ load_code(LoaderState* stp) int pad = MIN_FUNC_SZ - (finfo_ix - last_func_start); ASSERT(pad > 0 && pad < MIN_FUNC_SZ); CodeNeed(pad); - sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FINFO_SZ*sizeof(UWord)); - sys_memset(&code[finfo_ix], 0, pad*sizeof(UWord)); + sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FINFO_SZ*sizeof(BeamInstr)); + sys_memset(&code[finfo_ix], 0, pad*sizeof(BeamInstr)); ci += pad; stp->labels[last_label].value += pad; } @@ -2910,7 +2911,7 @@ gen_literal_timeout(LoaderState* stp, GenOpArg Fail, GenOpArg Time) } else { Uint u; (void) term_to_Uint(big, &u); - op->a[1].val = (UWord) u; + op->a[1].val = (BeamInstr) u; } #endif } else { @@ -2957,7 +2958,7 @@ gen_literal_timeout_locked(LoaderState* stp, GenOpArg Fail, GenOpArg Time) } else { Uint u; (void) term_to_Uint(big, &u); - op->a[1].val = (UWord) u; + op->a[1].val = (BeamInstr) u; } #endif } else { @@ -3377,7 +3378,7 @@ gen_make_fun2(LoaderState* stp, GenOpArg idx) op->op = genop_i_make_fun_2; op->arity = 2; op->a[0].type = TAG_u; - op->a[0].val = (UWord) fe; + op->a[0].val = (BeamInstr) fe; op->a[1].type = TAG_u; op->a[1].val = stp->lambdas[idx.val].num_free; op->next = NULL; @@ -3432,7 +3433,7 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif, static int freeze_code(LoaderState* stp) { - UWord* code = stp->code; + BeamInstr* code = stp->code; Uint *literal_end = NULL; Uint index; int i; @@ -3458,21 +3459,21 @@ freeze_code(LoaderState* stp) * Calculate the final size of the code. */ - size = (stp->ci * sizeof(UWord)) + (stp->total_literal_size * sizeof(Eterm)) + + size = (stp->ci * sizeof(BeamInstr)) + (stp->total_literal_size * sizeof(Eterm)) + strtab_size + attr_size + compile_size; /* * Move the code to its final location. */ - code = (UWord *) erts_realloc(ERTS_ALC_T_CODE, (void *) code, size); + code = (BeamInstr *) erts_realloc(ERTS_ALC_T_CODE, (void *) code, size); CHKBLK(ERTS_ALC_T_CODE,code); /* * Place a pointer to the op_int_code_end instruction in the * function table in the beginning of the file. */ - code[MI_FUNCTIONS+stp->num_functions] = (UWord) (code + stp->ci - 1); + code[MI_FUNCTIONS+stp->num_functions] = (BeamInstr) (code + stp->ci - 1); CHKBLK(ERTS_ALC_T_CODE,code); /* @@ -3480,7 +3481,7 @@ freeze_code(LoaderState* stp) */ if (stp->on_load) { - code[MI_ON_LOAD_FUNCTION_PTR] = (UWord) (code + stp->on_load); + code[MI_ON_LOAD_FUNCTION_PTR] = (BeamInstr) (code + stp->on_load); } else { code[MI_ON_LOAD_FUNCTION_PTR] = 0; } @@ -3499,8 +3500,8 @@ freeze_code(LoaderState* stp) low = (Uint *) (code+stp->ci); high = low + stp->total_literal_size; - code[MI_LITERALS_START] = (UWord) low; - code[MI_LITERALS_END] = (UWord) high; + code[MI_LITERALS_START] = (BeamInstr) low; + code[MI_LITERALS_END] = (BeamInstr) high; ptr = low; for (i = 0; i < stp->num_literals; i++) { Uint offset; @@ -3532,7 +3533,7 @@ freeze_code(LoaderState* stp) } lp = stp->literal_patches; while (lp != 0) { - UWord* op_ptr; + BeamInstr* op_ptr; Uint literal; Literal* lit; @@ -3559,8 +3560,8 @@ freeze_code(LoaderState* stp) if (attr_size) { byte* attr = str_table + strtab_size; sys_memcpy(attr, stp->chunks[ATTR_CHUNK].start, stp->chunks[ATTR_CHUNK].size); - code[MI_ATTR_PTR] = (UWord) attr; - code[MI_ATTR_SIZE] = (UWord) stp->chunks[ATTR_CHUNK].size; + code[MI_ATTR_PTR] = (BeamInstr) attr; + code[MI_ATTR_SIZE] = (BeamInstr) stp->chunks[ATTR_CHUNK].size; decoded_size = erts_decode_ext_size(attr, attr_size, 0); if (decoded_size < 0) { LoadError0(stp, "bad external term representation of module attributes"); @@ -3574,9 +3575,9 @@ freeze_code(LoaderState* stp) sys_memcpy(compile_info, stp->chunks[COMPILE_CHUNK].start, stp->chunks[COMPILE_CHUNK].size); CHKBLK(ERTS_ALC_T_CODE,code); - code[MI_COMPILE_PTR] = (UWord) compile_info; + code[MI_COMPILE_PTR] = (BeamInstr) compile_info; CHKBLK(ERTS_ALC_T_CODE,code); - code[MI_COMPILE_SIZE] = (UWord) stp->chunks[COMPILE_CHUNK].size; + code[MI_COMPILE_SIZE] = (BeamInstr) stp->chunks[COMPILE_CHUNK].size; CHKBLK(ERTS_ALC_T_CODE,code); decoded_size = erts_decode_ext_size(compile_info, compile_size, 0); CHKBLK(ERTS_ALC_T_CODE,code); @@ -3599,7 +3600,7 @@ freeze_code(LoaderState* stp) while (index != 0) { Uint next = code[index]; code[index] = BeamOpCode(op_put_string_IId); - code[index+2] = (UWord) (str_table + code[index+2] + code[index+1] - 1); + code[index+2] = (BeamInstr) (str_table + code[index+2] + code[index+1] - 1); index = next; } CHKBLK(ERTS_ALC_T_CODE,code); @@ -3614,7 +3615,7 @@ freeze_code(LoaderState* stp) while (index != 0) { Uint next = code[index]; code[index] = BeamOpCode(op_bs_put_string_II); - code[index+2] = (UWord) (str_table + code[index+2]); + code[index+2] = (BeamInstr) (str_table + code[index+2]); index = next; } CHKBLK(ERTS_ALC_T_CODE,code); @@ -3623,12 +3624,12 @@ freeze_code(LoaderState* stp) StringPatch* sp = stp->string_patches; while (sp != 0) { - UWord* op_ptr; + BeamInstr* op_ptr; byte* strp; op_ptr = code + sp->pos; strp = str_table + op_ptr[0]; - op_ptr[0] = (UWord) strp; + op_ptr[0] = (BeamInstr) strp; sp = sp->next; } } @@ -3652,7 +3653,7 @@ freeze_code(LoaderState* stp) ASSERT(this_patch < stp->ci); next_patch = code[this_patch]; ASSERT(next_patch < stp->ci); - code[this_patch] = (UWord) (code + value); + code[this_patch] = (BeamInstr) (code + value); this_patch = next_patch; } } @@ -3664,9 +3665,9 @@ freeze_code(LoaderState* stp) index = stp->catches; catches = BEAM_CATCHES_NIL; while (index != 0) { - UWord next = code[index]; + BeamInstr next = code[index]; code[index] = BeamOpCode(op_catch_yf); - catches = beam_catches_cons((UWord *)code[index+2], catches); + catches = beam_catches_cons((BeamInstr *)code[index+2], catches); code[index+2] = make_catch(catches); index = next; } @@ -3714,7 +3715,7 @@ final_touch(LoaderState* stp) * callable yet. */ ep->address = ep->code+3; - ep->code[4] = (UWord) stp->export[i].address; + ep->code[4] = (BeamInstr) stp->export[i].address; } } @@ -3726,14 +3727,14 @@ final_touch(LoaderState* stp) Eterm mod; Eterm func; Uint arity; - UWord import; + BeamInstr import; Uint current; Uint next; mod = stp->import[i].module; func = stp->import[i].function; arity = stp->import[i].arity; - import = (UWord) erts_export_put(mod, func, arity); + import = (BeamInstr) erts_export_put(mod, func, arity); current = stp->import[i].patches; while (current != 0) { ASSERT(current < stp->ci); @@ -3751,7 +3752,7 @@ final_touch(LoaderState* stp) for (i = 0; i < stp->num_lambdas; i++) { unsigned entry_label = stp->lambdas[i].label; ErlFunEntry* fe = stp->lambdas[i].fe; - UWord* code_ptr = (UWord *) (stp->code + stp->labels[entry_label].value); + BeamInstr* code_ptr = (BeamInstr *) (stp->code + stp->labels[entry_label].value); if (fe->address[0] != 0) { /* @@ -3883,7 +3884,7 @@ transform_engine(LoaderState* st) if (i >= st->num_imports || st->import[i].bf == NULL) goto restart; if (bif_number != -1 && - bif_export[bif_number]->code[4] != (UWord) st->import[i].bf) { + bif_export[bif_number]->code[4] != (BeamInstr) st->import[i].bf) { goto restart; } } @@ -4147,7 +4148,7 @@ load_printf(int line, LoaderState* context, char *fmt,...) static int -get_int_val(LoaderState* stp, Uint len_code, UWord* result) +get_int_val(LoaderState* stp, Uint len_code, BeamInstr* result) { Uint count; Uint val; @@ -4179,7 +4180,7 @@ get_int_val(LoaderState* stp, Uint len_code, UWord* result) static int -get_erlang_integer(LoaderState* stp, Uint len_code, UWord* result) +get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result) { Uint count; Sint val; @@ -4453,7 +4454,7 @@ functions_in_module(Process* p, /* Process whose heap to use. */ Eterm mod) /* Tagged atom for module. */ { Module* modp; - UWord* code; + BeamInstr* code; int i; Uint num_functions; Eterm* hp; @@ -4471,7 +4472,7 @@ functions_in_module(Process* p, /* Process whose heap to use. */ num_functions = code[MI_NUM_FUNCTIONS]; hp = HAlloc(p, 5*num_functions); for (i = num_functions-1; i >= 0 ; i--) { - UWord* func_info = (UWord *) code[MI_FUNCTIONS+i]; + BeamInstr* func_info = (BeamInstr *) code[MI_FUNCTIONS+i]; Eterm name = (Eterm) func_info[3]; int arity = (int) func_info[4]; Eterm tuple; @@ -4496,7 +4497,7 @@ static Eterm native_addresses(Process* p, Eterm mod) { Module* modp; - UWord* code; + BeamInstr* code; int i; Eterm* hp; Uint num_functions; @@ -4519,7 +4520,7 @@ native_addresses(Process* p, Eterm mod) hp = HAlloc(p, need); hp_end = hp + need; for (i = num_functions-1; i >= 0 ; i--) { - UWord* func_info = (UWord *) code[MI_FUNCTIONS+i]; + BeamInstr* func_info = (BeamInstr *) code[MI_FUNCTIONS+i]; Eterm name = (Eterm) func_info[3]; int arity = (int) func_info[4]; Eterm tuple; @@ -4563,7 +4564,7 @@ exported_from_module(Process* p, /* Process whose heap to use. */ Eterm tuple; if (ep->address == ep->code+3 && - ep->code[3] == (UWord) em_call_error_handler) { + ep->code[3] == (BeamInstr) em_call_error_handler) { /* There is a call to the function, but it does not exist. */ continue; } @@ -4596,7 +4597,7 @@ attributes_for_module(Process* p, /* Process whose heap to use. */ { Module* modp; - UWord* code; + BeamInstr* code; Eterm* hp; byte* ext; Eterm result = NIL; @@ -4636,7 +4637,7 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ Eterm mod) /* Tagged atom for module. */ { Module* modp; - UWord* code; + BeamInstr* code; Eterm* hp; byte* ext; Eterm result = NIL; @@ -4668,8 +4669,8 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ /* * Returns a pointer to {module, function, arity}, or NULL if not found. */ -UWord * -find_function_from_pc(UWord* pc) +BeamInstr * +find_function_from_pc(BeamInstr* pc) { Range* low = modules; Range* high = low + num_loaded_modules; @@ -4681,9 +4682,9 @@ find_function_from_pc(UWord* pc) } else if (pc > mid->end) { low = mid + 1; } else { - UWord** low1 = (UWord **) (mid->start + MI_FUNCTIONS); - UWord** high1 = low1 + mid->start[MI_NUM_FUNCTIONS]; - UWord** mid1; + BeamInstr** low1 = (BeamInstr **) (mid->start + MI_FUNCTIONS); + BeamInstr** high1 = low1 + mid->start[MI_NUM_FUNCTIONS]; + BeamInstr** mid1; while (low1 < high1) { mid1 = low1 + (high1-low1) / 2; @@ -4796,10 +4797,10 @@ code_module_md5_1(Process* p, Eterm Bin) #define WORDS_PER_FUNCTION 6 -static UWord* -make_stub(UWord* fp, Eterm mod, Eterm func, Uint arity, Uint native, UWord OpCode) +static BeamInstr* +make_stub(BeamInstr* fp, Eterm mod, Eterm func, Uint arity, Uint native, BeamInstr OpCode) { - fp[0] = (UWord) BeamOp(op_i_func_info_IaaI); + fp[0] = (BeamInstr) BeamOp(op_i_func_info_IaaI); fp[1] = native; fp[2] = mod; fp[3] = func; @@ -4818,14 +4819,14 @@ static byte* stub_copy_info(LoaderState* stp, int chunk, /* Chunk: ATTR_CHUNK or COMPILE_CHUNK */ byte* info, /* Where to store info. */ - UWord* ptr_word, /* Where to store pointer into info. */ - UWord* size_word) /* Where to store size of info. */ + BeamInstr* ptr_word, /* Where to store pointer into info. */ + BeamInstr* size_word) /* Where to store size of info. */ { Sint decoded_size; Uint size = stp->chunks[chunk].size; if (size != 0) { memcpy(info, stp->chunks[chunk].start, size); - *ptr_word = (UWord) info; + *ptr_word = (BeamInstr) info; decoded_size = erts_decode_ext_size(info, size, 0); if (decoded_size < 0) { return 0; @@ -4868,7 +4869,7 @@ stub_read_export_table(LoaderState* stp) } static void -stub_final_touch(LoaderState* stp, UWord* fp) +stub_final_touch(LoaderState* stp, BeamInstr* fp) { int i; int n = stp->num_exps; @@ -5055,12 +5056,12 @@ Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) { LoaderState state; - UWord Funcs; - UWord Patchlist; + BeamInstr Funcs; + BeamInstr Patchlist; Eterm* tp; - UWord* code = NULL; - UWord* ptrs; - UWord* fp; + BeamInstr* code = NULL; + BeamInstr* ptrs; + BeamInstr* fp; byte* info; Uint ci; int n; @@ -5149,7 +5150,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Allocate memory for the stub module. */ - code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(UWord); + code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(BeamInstr); code_size += state.chunks[ATTR_CHUNK].size; code_size += state.chunks[COMPILE_CHUNK].size; code = erts_alloc_fnf(ERTS_ALC_T_CODE, code_size); @@ -5218,7 +5219,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Set the pointer and make the stub. Put a return instruction * as the body until we know what kind of trap we should put there. */ - ptrs[i] = (UWord) fp; + ptrs[i] = (BeamInstr) fp; #ifdef HIPE op = (Eterm) BeamOpCode(op_hipe_trap_call); /* Might be changed later. */ #else @@ -5231,8 +5232,8 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Insert the last pointer and the int_code_end instruction. */ - ptrs[i] = (UWord) fp; - *fp++ = (UWord) BeamOp(op_int_code_end); + ptrs[i] = (BeamInstr) fp; + *fp++ = (BeamInstr) BeamOp(op_int_code_end); /* * Copy attributes and compilation information. diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h index a24460d2a5..ce6bd5b678 100644 --- a/erts/emulator/beam/beam_load.h +++ b/erts/emulator/beam/beam_load.h @@ -44,13 +44,13 @@ extern void** beam_ops; #endif -extern UWord beam_debug_apply[]; -extern UWord* em_call_error_handler; -extern UWord* em_apply_bif; -extern UWord* em_call_traced_function; +extern BeamInstr beam_debug_apply[]; +extern BeamInstr* em_call_error_handler; +extern BeamInstr* em_apply_bif; +extern BeamInstr* em_call_traced_function; typedef struct { - UWord* start; /* Pointer to start of module. */ - UWord* end; /* Points one word beyond last function in module. */ + BeamInstr* start; /* Pointer to start of module. */ + BeamInstr* end; /* Points one word beyond last function in module. */ } Range; /* diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 3aa258b675..c06d92ed45 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -4125,8 +4125,8 @@ void erts_init_bif(void) #else bif_return_trap_export.code[2] = 1; #endif - bif_return_trap_export.code[3] = (UWord) em_apply_bif; - bif_return_trap_export.code[4] = (UWord) &bif_return_trap; + bif_return_trap_export.code[3] = (BeamInstr) em_apply_bif; + bif_return_trap_export.code[4] = (BeamInstr) &bif_return_trap; flush_monitor_message_trap = erts_export_put(am_erlang, am_flush_monitor_message, diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index 0b7afcac02..c5aa00bc07 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -381,7 +381,7 @@ loaded(int to, void *to_arg) int i; int old = 0; int cur = 0; - UWord* code; + BeamInstr* code; /* * Calculate and print totals. diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index e805883ddc..79f0348dd2 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -150,7 +150,7 @@ void erts_alcu_current_size(Allctr_t *, AllctrSize_t *); #undef ERTS_ALLOC_UTIL_HARD_DEBUG #ifdef DEBUG -# if 1 +# if 0 # define ERTS_ALLOC_UTIL_HARD_DEBUG # endif #endif diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c index e76b0b9252..a5c9944789 100644 --- a/erts/emulator/beam/erl_bif_chksum.c +++ b/erts/emulator/beam/erl_bif_chksum.c @@ -49,9 +49,9 @@ void erts_init_bif_chksum(void) chksum_md5_2_exp.code[1] = am_atom_put("md5_trap",8); chksum_md5_2_exp.code[2] = 2; chksum_md5_2_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; chksum_md5_2_exp.code[4] = - (UWord) &md5_2; + (BeamInstr) &md5_2; } diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 40f8b7f23a..fc8d876bc4 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -1010,7 +1010,7 @@ process_info_aux(Process *BIF_P, hp = HAlloc(BIF_P, 3); res = am_undefined; } else { - UWord* current; + BeamInstr* current; if (rp->current[0] == am_erlang && rp->current[1] == am_process_info && diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c index 4b527ce215..d4a8a3aaa7 100644 --- a/erts/emulator/beam/erl_bif_re.c +++ b/erts/emulator/beam/erl_bif_re.c @@ -76,8 +76,8 @@ void erts_init_bif_re(void) re_exec_trap_export.code[0] = am_erlang; re_exec_trap_export.code[1] = am_re_run_trap; re_exec_trap_export.code[2] = 3; - re_exec_trap_export.code[3] = (UWord) em_apply_bif; - re_exec_trap_export.code[4] = (UWord) &re_exec_trap; + re_exec_trap_export.code[3] = (BeamInstr) em_apply_bif; + re_exec_trap_export.code[4] = (BeamInstr) &re_exec_trap; grun_trap_exportp = erts_export_put(am_re,am_grun,3); urun_trap_exportp = erts_export_put(am_re,am_urun,3); diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index c46a0074fc..76e6a74112 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -954,7 +954,7 @@ static int function_is_traced(Eterm mfa[3], Export e; Export* ep; int i; - Uint *code; + BeamInstr *code; /* First look for an export entry */ e.code[0] = mfa[0]; @@ -962,12 +962,12 @@ static int function_is_traced(Eterm mfa[3], e.code[2] = mfa[2]; if ((ep = export_get(&e)) != NULL) { if (ep->address == ep->code+3 && - ep->code[3] != (UWord) em_call_error_handler) { - if (ep->code[3] == (UWord) em_call_traced_function) { + ep->code[3] != (BeamInstr) em_call_error_handler) { + if (ep->code[3] == (BeamInstr) em_call_traced_function) { *ms = ep->match_prog_set; return FUNC_TRACE_GLOBAL_TRACE; } - if (ep->code[3] == (UWord) em_apply_bif) { + if (ep->code[3] == (BeamInstr) em_apply_bif) { for (i = 0; i < BIF_SIZE; ++i) { if (bif_export[i] == ep) { int r = 0; @@ -1321,7 +1321,7 @@ erts_set_trace_pattern(Eterm* mfa, int specified, if (erts_bif_trace_flags[i] & BIF_TRACE_AS_META) { ASSERT(ExportIsBuiltIn(bif_export[i])); erts_clear_mtrace_bif - ((Uint *)bif_export[i]->code + 3); + ((BeamInstr *)bif_export[i]->code + 3); erts_bif_trace_flags[i] &= ~BIF_TRACE_AS_META; } set_trace_bif(i, match_prog_set); @@ -1350,7 +1350,7 @@ erts_set_trace_pattern(Eterm* mfa, int specified, } if (flags.meta) { erts_set_mtrace_bif - ((Uint *)bif_export[i]->code + 3, + ((BeamInstr *)bif_export[i]->code + 3, meta_match_prog_set, meta_tracer_pid); erts_bif_trace_flags[i] |= BIF_TRACE_AS_META; erts_bif_trace_flags[i] &= ~BIF_TRACE_AS_GLOBAL; @@ -1370,7 +1370,7 @@ erts_set_trace_pattern(Eterm* mfa, int specified, if (flags.meta) { if (erts_bif_trace_flags[i] & BIF_TRACE_AS_META) { erts_clear_mtrace_bif - ((Uint *)bif_export[i]->code + 3); + ((BeamInstr *)bif_export[i]->code + 3); erts_bif_trace_flags[i] &= ~BIF_TRACE_AS_META; } m = 1; @@ -1439,9 +1439,9 @@ static int setup_func_trace(Export* ep, void* match_prog) { if (ep->address == ep->code+3) { - if (ep->code[3] == (UWord) em_call_error_handler) { + if (ep->code[3] == (BeamInstr) em_call_error_handler) { return 0; - } else if (ep->code[3] == (UWord) em_call_traced_function) { + } else if (ep->code[3] == (BeamInstr) em_call_traced_function) { MatchSetUnref(ep->match_prog_set); ep->match_prog_set = match_prog; MatchSetRef(ep->match_prog_set); @@ -1461,8 +1461,8 @@ setup_func_trace(Export* ep, void* match_prog) return 0; } - ep->code[3] = (UWord) em_call_traced_function; - ep->code[4] = (UWord) ep->address; + ep->code[3] = (BeamInstr) em_call_traced_function; + ep->code[4] = (BeamInstr) ep->address; ep->address = ep->code+3; ep->match_prog_set = match_prog; MatchSetRef(ep->match_prog_set); @@ -1474,7 +1474,7 @@ static void setup_bif_trace(int bif_index) { ASSERT(ExportIsBuiltIn(ep)); ASSERT(ep->code[4]); - ep->code[4] = (UWord) bif_table[bif_index].traced; + ep->code[4] = (BeamInstr) bif_table[bif_index].traced; } static void set_trace_bif(int bif_index, void* match_prog) { @@ -1501,9 +1501,9 @@ static int reset_func_trace(Export* ep) { if (ep->address == ep->code+3) { - if (ep->code[3] == (UWord) em_call_error_handler) { + if (ep->code[3] == (BeamInstr) em_call_error_handler) { return 0; - } else if (ep->code[3] == (UWord) em_call_traced_function) { + } else if (ep->code[3] == (BeamInstr) em_call_traced_function) { ep->address = (Uint *) ep->code[4]; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; @@ -1536,8 +1536,8 @@ static void reset_bif_trace(int bif_index) { ASSERT(ExportIsBuiltIn(ep)); ASSERT(ep->code[4]); ASSERT(! ep->match_prog_set); - ASSERT(! erts_is_mtrace_bif((UWord *)ep->code+3, NULL, NULL)); - ep->code[4] = (UWord) bif_table[bif_index].f; + ASSERT(! erts_is_mtrace_bif((BeamInstr *)ep->code+3, NULL, NULL)); + ep->code[4] = (BeamInstr) bif_table[bif_index].f; } static void clear_trace_bif(int bif_index) { diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 959f7fa37c..88a9e56854 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -2624,7 +2624,7 @@ void init_db(void) { DbTable init_tb; int i; - extern UWord* em_apply_bif; + extern BeamInstr* em_apply_bif; Eterm *hp; unsigned bits; size_t size; @@ -2753,9 +2753,9 @@ void init_db(void) ets_select_delete_continue_exp.code[1] = am_atom_put("delete_trap",11); ets_select_delete_continue_exp.code[2] = 1; ets_select_delete_continue_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; ets_select_delete_continue_exp.code[4] = - (UWord) &ets_select_delete_1; + (BeamInstr) &ets_select_delete_1; /* Non visual BIF to trap to. */ memset(&ets_select_count_continue_exp, 0, sizeof(Export)); @@ -2765,9 +2765,9 @@ void init_db(void) ets_select_count_continue_exp.code[1] = am_atom_put("count_trap",11); ets_select_count_continue_exp.code[2] = 1; ets_select_count_continue_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; ets_select_count_continue_exp.code[4] = - (UWord) &ets_select_count_1; + (BeamInstr) &ets_select_count_1; /* Non visual BIF to trap to. */ memset(&ets_select_continue_exp, 0, sizeof(Export)); @@ -2777,9 +2777,9 @@ void init_db(void) ets_select_continue_exp.code[1] = am_atom_put("select_trap",11); ets_select_continue_exp.code[2] = 1; ets_select_continue_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; ets_select_continue_exp.code[4] = - (UWord) &ets_select_trap_1; + (BeamInstr) &ets_select_trap_1; /* Non visual BIF to trap to. */ memset(&ets_delete_continue_exp, 0, sizeof(Export)); @@ -2787,8 +2787,8 @@ void init_db(void) ets_delete_continue_exp.code[0] = am_ets; ets_delete_continue_exp.code[1] = am_atom_put("delete_trap",11); ets_delete_continue_exp.code[2] = 1; - ets_delete_continue_exp.code[3] = (UWord) em_apply_bif; - ets_delete_continue_exp.code[4] = (UWord) &ets_delete_trap; + ets_delete_continue_exp.code[3] = (BeamInstr) em_apply_bif; + ets_delete_continue_exp.code[4] = (BeamInstr) &ets_delete_trap; hp = ms_delete_all_buff; ms_delete_all = CONS(hp, am_true, NIL); diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 71c594854b..f9ed5fe292 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -443,9 +443,9 @@ void db_initialize_tree(void) ets_select_reverse_exp.code[1] = am_reverse; ets_select_reverse_exp.code[2] = 3; ets_select_reverse_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; ets_select_reverse_exp.code[4] = - (UWord) &ets_select_reverse; + (BeamInstr) &ets_select_reverse; return; }; diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index c565e1ee89..f8baf44e10 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -1601,7 +1601,7 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term, Eterm **sp; Eterm *esp; Eterm *hp; - UWord *cp; + BeamInstr *cp; UWord *pc = prog->text; Eterm *ehp; Eterm ret; @@ -4235,7 +4235,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) Eterm l; Uint32 ret_flags; Uint sz; - UWord *save_cp; + BeamInstr *save_cp; if (trace && !(is_list(against) || against == NIL)) { return THE_NON_VALUE; diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c index e6884c1179..5dea774cd0 100644 --- a/erts/emulator/beam/erl_fun.c +++ b/erts/emulator/beam/erl_fun.c @@ -50,8 +50,8 @@ static void fun_free(ErlFunEntry* obj); * to unloaded_fun[]. The -1 in unloaded_fun[0] will be interpreted * as an illegal arity when attempting to call a fun. */ -static UWord unloaded_fun_code[3] = {NIL, -1, 0}; -static UWord* unloaded_fun = unloaded_fun_code + 2; +static BeamInstr unloaded_fun_code[3] = {NIL, -1, 0}; +static BeamInstr* unloaded_fun = unloaded_fun_code + 2; void erts_init_fun_table(void) @@ -207,7 +207,7 @@ erts_cleanup_funs(ErlFunThing* funp) #endif void -erts_cleanup_funs_on_purge(UWord* start, UWord* end) +erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end) { int limit; HashBucket** bucket; @@ -222,7 +222,7 @@ erts_cleanup_funs_on_purge(UWord* start, UWord* end) while (b) { ErlFunEntry* fe = (ErlFunEntry *) b; - UWord* addr = fe->address; + BeamInstr* addr = fe->address; if (start <= addr && addr < end) { fe->address = unloaded_fun; diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h index 980cdd414a..781e3c764c 100644 --- a/erts/emulator/beam/erl_fun.h +++ b/erts/emulator/beam/erl_fun.h @@ -33,7 +33,7 @@ typedef struct erl_fun_entry { int index; /* New style index. */ int old_uniq; /* Unique number (old_style) */ int old_index; /* Old style index */ - UWord* address; /* Pointer to code for fun */ + BeamInstr* address; /* Pointer to code for fun */ #ifdef HIPE UWord* native_address; /* Native entry code for fun. */ @@ -86,7 +86,7 @@ void erts_erase_fun_entry(ErlFunEntry* fe); #ifndef HYBRID /* FIND ME! */ void erts_cleanup_funs(ErlFunThing* funp); #endif -void erts_cleanup_funs_on_purge(UWord* start, UWord* end); +void erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end); void erts_dump_fun_entries(int, void *); #endif diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 7c62bcb016..f0c4d81f0b 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -975,17 +975,17 @@ unsigned enif_sizeof_resource(ErlNifEnv* env, void* obj) ***************************************************************************/ -static UWord** get_func_pp(UWord* mod_code, Eterm f_atom, unsigned arity) +static BeamInstr** get_func_pp(BeamInstr* mod_code, Eterm f_atom, unsigned arity) { int n = (int) mod_code[MI_NUM_FUNCTIONS]; int j; for (j = 0; j < n; ++j) { - UWord* code_ptr = (UWord*) mod_code[MI_FUNCTIONS+j]; - ASSERT(code_ptr[0] == (UWord) BeamOp(op_i_func_info_IaaI)); + BeamInstr* code_ptr = (BeamInstr*) mod_code[MI_FUNCTIONS+j]; + ASSERT(code_ptr[0] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); if (f_atom == ((Eterm) code_ptr[3]) && arity == ((unsigned) code_ptr[4])) { - return (UWord**) &mod_code[MI_FUNCTIONS+j]; + return (BeamInstr**) &mod_code[MI_FUNCTIONS+j]; } } return NULL; @@ -1002,7 +1002,7 @@ static UWord** get_func_pp(UWord* mod_code, Eterm f_atom, unsigned arity) erts_atom_get(func->name, sys_strlen(func->name), &f_atom); code_ptr = *get_func_pp(mod_code, f_atom, func->arity); - code_ptr[5+2] = (UWord) mod_nif->priv_data; + code_ptr[5+2] = ((BeamInstr) mod_nif->priv_data; } }*/ @@ -1106,7 +1106,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) Module* mod; Eterm mod_atom; Eterm f_atom; - UWord* caller; + BeamInstr* caller; ErtsSysDdllError errdesc = ERTS_SYS_DDLL_ERROR_INIT; Eterm ret = am_ok; int veto; @@ -1173,7 +1173,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) /*erts_fprintf(stderr, "Found module %T\r\n", mod_atom);*/ for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) { - UWord** code_pp; + BeamInstr** code_pp; ErlNifFunc* f = &entry->funcs[i]; if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom) || (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) { @@ -1291,7 +1291,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) code_ptr[5+2] = (BeamInstr) lib; } } - else { + else { error: ASSERT(ret != am_ok); if (lib != NULL) { diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 429bdd74fb..b12402600b 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -91,9 +91,9 @@ do { \ #define ERTS_EMPTY_RUNQ(RQ) \ ((RQ)->len == 0 && (RQ)->misc.start == NULL) -extern UWord beam_apply[]; -extern UWord beam_exit[]; -extern UWord beam_continue_exit[]; +extern BeamInstr beam_apply[]; +extern BeamInstr beam_exit[]; +extern BeamInstr beam_continue_exit[]; static Sint p_last; static Sint p_next; @@ -334,7 +334,7 @@ do { \ static void init_processes_bif(void); static void save_terminating_process(Process *p); static void exec_misc_ops(ErtsRunQueue *); -static void print_function_from_pc(int to, void *to_arg, UWord* x); +static void print_function_from_pc(int to, void *to_arg, BeamInstr* x); static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg); #ifdef ERTS_SMP @@ -6769,8 +6769,8 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). p->current = p->initial+INITIAL_MOD; - p->i = (UWord *) beam_apply; - p->cp = (UWord *) beam_apply+1; + p->i = (BeamInstr *) beam_apply; + p->cp = (BeamInstr *) beam_apply+1; p->arg_reg = p->def_arg_reg; p->max_arg_reg = sizeof(p->def_arg_reg)/sizeof(p->def_arg_reg[0]); @@ -7355,7 +7355,7 @@ set_proc_exiting(Process *p, Eterm reason, ErlHeapFragment *bp) p->freason = EXTAG_EXIT; KILL_CATCHES(p); cancel_timer(p); - p->i = (UWord *) beam_exit; + p->i = (BeamInstr *) beam_exit; } @@ -8283,7 +8283,7 @@ continue_exit_process(Process *p ASSERT(p->status == P_EXITING); - p->i = (UWord *) beam_continue_exit; + p->i = (BeamInstr *) beam_continue_exit; if (!(curr_locks & ERTS_PROC_LOCK_STATUS)) { erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS); @@ -8303,7 +8303,7 @@ continue_exit_process(Process *p static void timeout_proc(Process* p) { - p->i = *((UWord **) (UWord) p->def_arg_reg); + p->i = *((BeamInstr **) (UWord) p->def_arg_reg); p->flags |= F_TIMO; p->flags &= ~F_INSLPQUEUE; @@ -8402,9 +8402,9 @@ erts_program_counter_info(int to, void *to_arg, Process *p) } static void -print_function_from_pc(int to, void *to_arg, UWord* x) +print_function_from_pc(int to, void *to_arg, BeamInstr* x) { - UWord* addr = find_function_from_pc(x); + BeamInstr* addr = find_function_from_pc(x); if (addr == NULL) { if (x == beam_exit) { erts_print(to, to_arg, ""); @@ -9267,8 +9267,8 @@ init_processes_bif(void) processes_trap_export.code[0] = am_erlang; processes_trap_export.code[1] = am_processes_trap; processes_trap_export.code[2] = 2; - processes_trap_export.code[3] = (UWord) em_apply_bif; - processes_trap_export.code[4] = (UWord) &processes_trap; + processes_trap_export.code[3] = (BeamInstr) em_apply_bif; + processes_trap_export.code[4] = (BeamInstr) &processes_trap; #if ERTS_PROCESSES_BIF_DEBUGLEVEL >= ERTS_PROCS_DBGLVL_CHK_TERM_PROC_LIST erts_get_emu_time(&debug_tv_start); diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index df08f2474c..de9664398d 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -529,8 +529,8 @@ struct process { unsigned max_arg_reg; /* Maximum number of argument registers available. */ Eterm def_arg_reg[6]; /* Default array for argument registers. */ - UWord* cp; /* Continuation pointer (for threaded code). */ - UWord* i; /* Program counter for threaded code. */ + BeamInstr* cp; /* (untagged) Continuation pointer (for threaded code). */ + BeamInstr* i; /* Program counter for threaded code. */ Sint catches; /* Number of catches on stack */ Sint fcalls; /* * Number of reductions left to execute. @@ -577,11 +577,12 @@ struct process { Uint seq_trace_lastcnt; Eterm seq_trace_token; /* Sequential trace token (tuple size 5 see below) */ - UWord initial[3]; /* Initial module(0), function(1), arity(2) */ - UWord* current; /* Current Erlang function, part of the funcinfo: + BeamInstr initial[3]; /* Initial module(0), function(1), arity(2), often used instead + of pointer to funcinfo instruction, hence the BeamInstr datatype */ + BeamInstr* current; /* Current Erlang function, part of the funcinfo: * module(0), function(1), arity(2) * (module and functions are tagged atoms; - * arity an untagged integer). UWord * because it references code + * arity an untagged integer). BeamInstr * because it references code */ /* diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c index 0b776367ed..a79612568e 100644 --- a/erts/emulator/beam/erl_process_dump.c +++ b/erts/emulator/beam/erl_process_dump.c @@ -45,16 +45,16 @@ static void dump_dist_ext(int to, void *to_arg, ErtsDistExternal *edep); static void dump_element_nl(int to, void *to_arg, Eterm x); static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg); -static void print_function_from_pc(int to, void *to_arg, UWord* x); +static void print_function_from_pc(int to, void *to_arg, BeamInstr* x); static void heap_dump(int to, void *to_arg, Eterm x); static void dump_binaries(int to, void *to_arg, Binary* root); static void dump_externally(int to, void *to_arg, Eterm term); static Binary* all_binaries; -extern UWord beam_apply[]; -extern UWord beam_exit[]; -extern UWord beam_continue_exit[]; +extern BeamInstr beam_apply[]; +extern BeamInstr beam_exit[]; +extern BeamInstr beam_continue_exit[]; void @@ -239,9 +239,9 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg) } static void -print_function_from_pc(int to, void *to_arg, UWord* x) +print_function_from_pc(int to, void *to_arg, BeamInstr* x) { - UWord* addr = find_function_from_pc(x); + BeamInstr* addr = find_function_from_pc(x); if (addr == NULL) { if (x == beam_exit) { erts_print(to, to_arg, ""); diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 8e74502022..25d12bf16e 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -987,14 +987,14 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm) #endif #define _unchecked_make_cp(x) ((Eterm) COMPRESS_POINTER(x)) -_ET_DECLARE_CHECKED(Eterm,make_cp,UWord*); +_ET_DECLARE_CHECKED(Eterm,make_cp,BeamInstr*); #define make_cp(x) _ET_APPLY(make_cp,(x)) #define is_not_CP(x) ((x) & _CPMASK) #define is_CP(x) (!is_not_CP(x)) -#define _unchecked_cp_val(x) ((UWord*) EXPAND_POINTER(x)) -_ET_DECLARE_CHECKED(UWord*,cp_val,Eterm); +#define _unchecked_cp_val(x) ((BeamInstr*) EXPAND_POINTER(x)) +_ET_DECLARE_CHECKED(BeamInstr*,cp_val,Eterm); #define cp_val(x) _ET_APPLY(cp_val,(x)) #define make_catch(x) (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH) diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index eb61c72e90..8addfcf5ad 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -1182,7 +1182,7 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type, * or {trace, Pid, return_to, {Mod, Func, Arity}} */ void -erts_trace_return_to(Process *p, UWord *pc) +erts_trace_return_to(Process *p, BeamInstr *pc) { #define LOCAL_HEAP_SIZE (4+5+5) Eterm* hp; @@ -1190,7 +1190,7 @@ erts_trace_return_to(Process *p, UWord *pc) Eterm mess; DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); - UWord *code_ptr = find_function_from_pc(pc); + BeamInstr *code_ptr = find_function_from_pc(pc); UseTmpHeapNoproc(LOCAL_HEAP_SIZE); @@ -1249,7 +1249,7 @@ erts_trace_return_to(Process *p, UWord *pc) * or {trace, Pid, return_from, {Mod, Name, Arity}, Retval} */ void -erts_trace_return(Process* p, UWord* fi, Eterm retval, Eterm *tracer_pid) +erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid) { Eterm* hp; Eterm mfa; @@ -1380,7 +1380,7 @@ erts_trace_return(Process* p, UWord* fi, Eterm retval, Eterm *tracer_pid) * Where Class is atomic but Value is any term. */ void -erts_trace_exception(Process* p, UWord mfa[3], Eterm class, Eterm value, +erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value, Eterm *tracer_pid) { Eterm* hp; @@ -1522,7 +1522,7 @@ erts_trace_exception(Process* p, UWord mfa[3], Eterm class, Eterm value, * if it is a pid or port we do a meta trace. */ Uint32 -erts_call_trace(Process* p, UWord mfa[3], Binary *match_spec, +erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec, Eterm* args, int local, Eterm *tracer_pid) { Eterm* hp; @@ -2092,7 +2092,7 @@ void save_calls(Process *p, Export *e) */ Eterm erts_bif_trace(int bif_index, Process* p, - Eterm arg1, Eterm arg2, Eterm arg3, UWord *I) + Eterm arg1, Eterm arg2, Eterm arg3, BeamInstr *I) { Eterm result; int meta = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_META); @@ -2106,10 +2106,10 @@ erts_bif_trace(int bif_index, Process* p, * no tracing will occur. Doing the whole else branch will * also do nothing, only slower. */ - Eterm (*func)(Process*, Eterm, Eterm, Eterm, UWord*) = bif_table[bif_index].f; + Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = bif_table[bif_index].f; result = func(p, arg1, arg2, arg3, I); } else { - Eterm (*func)(Process*, Eterm, Eterm, Eterm, UWord*); + Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*); Export* ep = bif_export[bif_index]; Uint32 flags = 0, flags_meta = 0; int global = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_GLOBAL); @@ -2118,7 +2118,7 @@ erts_bif_trace(int bif_index, Process* p, int applying = (I == &(ep->code[3])); /* Yup, the apply code for a bif * is actually in the * export entry */ - UWord *cp = p->cp; + BeamInstr *cp = p->cp; Eterm args[3] = {arg1, arg2, arg3}; diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index 8f16f7338f..ca800dbe8d 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -90,9 +90,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_utf8_trap",23); characters_to_utf8_trap_exp.code[2] = 3; characters_to_utf8_trap_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; characters_to_utf8_trap_exp.code[4] = - (UWord) &characters_to_utf8_trap; + (BeamInstr) &characters_to_utf8_trap; memset(&characters_to_list_trap_1_exp, 0, sizeof(Export)); characters_to_list_trap_1_exp.address = @@ -102,9 +102,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_1",25); characters_to_list_trap_1_exp.code[2] = 3; characters_to_list_trap_1_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; characters_to_list_trap_1_exp.code[4] = - (UWord) &characters_to_list_trap_1; + (BeamInstr) &characters_to_list_trap_1; memset(&characters_to_list_trap_2_exp, 0, sizeof(Export)); characters_to_list_trap_2_exp.address = @@ -114,9 +114,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_2",25); characters_to_list_trap_2_exp.code[2] = 3; characters_to_list_trap_2_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; characters_to_list_trap_2_exp.code[4] = - (UWord) &characters_to_list_trap_2; + (BeamInstr) &characters_to_list_trap_2; memset(&characters_to_list_trap_3_exp, 0, sizeof(Export)); @@ -127,9 +127,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_3",25); characters_to_list_trap_3_exp.code[2] = 3; characters_to_list_trap_3_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; characters_to_list_trap_3_exp.code[4] = - (UWord) &characters_to_list_trap_3; + (BeamInstr) &characters_to_list_trap_3; memset(&characters_to_list_trap_4_exp, 0, sizeof(Export)); characters_to_list_trap_4_exp.address = @@ -139,9 +139,9 @@ void erts_init_unicode(void) am_atom_put("characters_to_list_trap_4",25); characters_to_list_trap_4_exp.code[2] = 1; characters_to_list_trap_4_exp.code[3] = - (UWord) em_apply_bif; + (BeamInstr) em_apply_bif; characters_to_list_trap_4_exp.code[4] = - (UWord) &characters_to_list_trap_4; + (BeamInstr) &characters_to_list_trap_4; c_to_b_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_binary_int,2); c_to_l_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_list_int,2); diff --git a/erts/emulator/beam/error.h b/erts/emulator/beam/error.h index 8f95140864..bbccb5e529 100644 --- a/erts/emulator/beam/error.h +++ b/erts/emulator/beam/error.h @@ -187,10 +187,10 @@ extern Eterm exception_tag[NUMBER_EXC_TAGS]; struct StackTrace { Eterm header; /* bignum header - must be first in struct */ Eterm freason; /* original exception reason is saved in the struct */ - UWord* pc; - UWord* current; + BeamInstr* pc; + BeamInstr* current; int depth; /* number of saved pointers in trace[] */ - UWord *trace[1]; /* varying size - must be last in struct */ + BeamInstr *trace[1]; /* varying size - must be last in struct */ }; #endif /* __ERROR_H__ */ diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c index c39f610924..d251a0e375 100644 --- a/erts/emulator/beam/export.c +++ b/erts/emulator/beam/export.c @@ -46,8 +46,8 @@ static erts_smp_rwmtx_t export_table_lock; /* Locks the secondary export table. #define export_init_lock() erts_smp_rwmtx_init(&export_table_lock, \ "export_tab") -extern UWord* em_call_error_handler; -extern UWord* em_call_traced_function; +extern BeamInstr* em_call_error_handler; +extern BeamInstr* em_call_traced_function; void export_info(int to, void *to_arg) @@ -93,7 +93,7 @@ export_alloc(Export* tmpl) obj->code[2] = tmpl->code[2]; obj->slot.index = -1; obj->address = obj->code+3; - obj->code[3] = (UWord) em_call_error_handler; + obj->code[3] = (BeamInstr) em_call_error_handler; obj->code[4] = 0; obj->match_prog_set = NULL; return obj; @@ -140,7 +140,7 @@ init_export_table(void) Export* erts_find_export_entry(Eterm m, Eterm f, unsigned int a) { - HashValue hval = EXPORT_HASH((UWord) m, (UWord) f, (UWord) a); + HashValue hval = EXPORT_HASH((BeamInstr) m, (BeamInstr) f, (BeamInstr) a); int ix; HashBucket* b; @@ -185,7 +185,7 @@ erts_find_function(Eterm m, Eterm f, unsigned int a) ep = hash_get(&export_table.htable, (void*) &e); if (ep != NULL && ep->address == ep->code+3 && - ep->code[3] != (UWord) em_call_traced_function) { + ep->code[3] != (BeamInstr) em_call_traced_function) { ep = NULL; } return ep; diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h index 57b6a7afcf..2758d71a3c 100644 --- a/erts/emulator/beam/export.h +++ b/erts/emulator/beam/export.h @@ -53,7 +53,7 @@ typedef struct export * Otherwise: 0. */ #if HALFWORD_HEAP - UWord code[5]; + BeamInstr code[5]; #else Eterm code[5]; #endif @@ -78,6 +78,6 @@ Export *export_get(Export*); #include "beam_load.h" /* For em_* extern declarations */ #define ExportIsBuiltIn(EntryPtr) \ (((EntryPtr)->address == (EntryPtr)->code + 3) && \ - ((EntryPtr)->code[3] == (UWord) em_apply_bif)) + ((EntryPtr)->code[3] == (BeamInstr) em_apply_bif)) #endif diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index ebe7302373..cefdf80fb4 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -856,7 +856,7 @@ void erts_system_profile_clear(Process *c_p); int erts_load_module(Process *c_p, ErtsProcLocks c_p_locks, Eterm group_leader, Eterm* mod, byte* code, int size); void init_load(void); -UWord* find_function_from_pc(UWord* pc); +BeamInstr* find_function_from_pc(BeamInstr* pc); Eterm erts_module_info_0(Process* p, Eterm module); Eterm erts_module_info_1(Process* p, Eterm module, Eterm what); Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info); @@ -1611,12 +1611,12 @@ void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *); void erts_send_sys_msg_proc(Eterm, Eterm, Eterm, ErlHeapFragment *); void trace_send(Process*, Eterm, Eterm); void trace_receive(Process*, Eterm); -Uint32 erts_call_trace(Process *p, UWord mfa[], Binary *match_spec, Eterm* args, +Uint32 erts_call_trace(Process *p, BeamInstr mfa[], Binary *match_spec, Eterm* args, int local, Eterm *tracer_pid); -void erts_trace_return(Process* p, UWord* fi, Eterm retval, Eterm *tracer_pid); -void erts_trace_exception(Process* p, UWord mfa[], Eterm class, Eterm value, +void erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid); +void erts_trace_exception(Process* p, BeamInstr mfa[], Eterm class, Eterm value, Eterm *tracer); -void erts_trace_return_to(Process *p, UWord *pc); +void erts_trace_return_to(Process *p, BeamInstr *pc); void trace_sched(Process*, Eterm); void trace_proc(Process*, Process*, Eterm, Eterm); void trace_proc_spawn(Process*, Eterm pid, Eterm mod, Eterm func, Eterm args); @@ -1646,7 +1646,7 @@ Uint erts_trace_flag2bit(Eterm flag); int erts_trace_flags(Eterm List, Uint *pMask, Eterm *pTracer, int *pCpuTimestamp); Eterm erts_bif_trace(int bif_index, Process* p, - Eterm arg1, Eterm arg2, Eterm arg3, UWord *I); + Eterm arg1, Eterm arg2, Eterm arg3, BeamInstr *I); #ifdef ERTS_SMP void erts_send_pending_trace_msgs(ErtsSchedulerData *esdp); diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h index a09d5985db..694e4ab72f 100644 --- a/erts/emulator/beam/module.h +++ b/erts/emulator/beam/module.h @@ -29,8 +29,8 @@ typedef struct erl_module { IndexSlot slot; /* Must be located at top of struct! */ int module; /* Atom index for module (not tagged). */ - UWord* code; - UWord* old_code; + BeamInstr* code; + BeamInstr* old_code; int code_length; /* Length of loaded code in bytes. */ int old_code_length; /* Length of old loaded code in bytes */ unsigned catches, old_catches; diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index b48b147953..7ddf1d8278 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -231,6 +231,7 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...)); ** Data types: ** ** Eterm: A tagged erlang term (possibly 64 bits) +** BeamInstr: A beam code instruction unit, possibly larger than Eterm, not smaller. ** UInt: An unsigned integer exactly as large as an Eterm. ** SInt: A signed integer exactly as large as an eterm and therefor large ** enough to hold the return value of the signed_val() macro. @@ -314,6 +315,8 @@ typedef Sint SWord; #endif /* HALFWORD_HEAP */ +typedef UWord BeamInstr; + #ifndef HAVE_INT64 #if SIZEOF_LONG == 8 #define HAVE_INT64 1 -- cgit v1.2.3 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 From c591f7b2a78b44ab321d0b99c100b349c8606c15 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Tue, 9 Feb 2010 17:21:28 +0100 Subject: Make tracing and distribution work Rewrite trace code and external coding. Also slightly correct the interface to the match-spec engine to make tracing work. That will make the test suites runnable. --- erts/emulator/beam/beam_emu.c | 9 ++++-- erts/emulator/beam/bif.c | 8 ++++-- erts/emulator/beam/erl_db.c | 2 +- erts/emulator/beam/erl_db_hash.c | 12 ++++---- erts/emulator/beam/erl_db_tree.c | 8 +++--- erts/emulator/beam/erl_db_util.c | 21 +++++++------- erts/emulator/beam/erl_db_util.h | 2 +- erts/emulator/beam/erl_term.h | 5 ++++ erts/emulator/beam/external.c | 18 +++++++----- lib/runtime_tools/src/dbg.erl | 61 ++++++++++++++++++++++++++++++++-------- 10 files changed, 101 insertions(+), 45 deletions(-) diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 8113e78583..1078478ed9 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -2621,6 +2621,7 @@ void process_main(void) SWAPOUT; reg[0] = r(0); + next = call_fun(c_p, Arg(0), reg, THE_NON_VALUE); SWAPIN; if (next != NULL) { @@ -6049,8 +6050,12 @@ call_fun(Process* p, /* Current process. */ } } } else if (is_export_header(hdr)) { - Export* ep = *((Export **) (export_val(fun) + 1)); - int actual_arity = (int) ep->code[2]; + Export *ep; + int actual_arity; + + ep = *((Export **) (export_val(fun) + 1)); + actual_arity = (int) ep->code[2]; + if (arity == actual_arity) { return ep->address; } else { diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index c06d92ed45..85bf584337 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3468,12 +3468,14 @@ BIF_RETTYPE make_fun_3(BIF_ALIST_3) if (arity < 0) { goto error; } - hp = HAlloc(BIF_P, 2); - hp[0] = HEADER_EXPORT; #if HALFWORD_HEAP + hp = HAlloc(BIF_P, 3); + hp[0] = HEADER_EXPORT; /* Yes, May be misaligned, but X86_64 will fix it... */ - memcpy(hp+1,erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity),sizeof(Export *)); + *((Export **) (hp+1)) = erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity); #else + hp = HAlloc(BIF_P, 2); + hp[0] = HEADER_EXPORT; hp[1] = (Eterm) erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity); #endif BIF_RET(make_export(hp)); diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 88a9e56854..4c75659246 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -2597,7 +2597,7 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3) BIF_TRAP3(bif_export[BIF_ets_match_spec_run_r_3], BIF_P,lst,BIF_ARG_2,ret); } - res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), 0, &dummy); + res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), NULL, 0, &dummy); if (is_value(res)) { sz = size_object(res); hp = HAlloc(BIF_P, sz + 2); diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 4141f9766b..124129a371 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -1284,7 +1284,7 @@ static int db_select_continue_hash(Process *p, (match_res = db_prog_match(p,mp, make_tuple(current->dbterm.tpl), - 0,&dummy), + NULL,0,&dummy), is_value(match_res))) { if (all_objects) { hp = HAlloc(p, current->dbterm.size + 2); @@ -1462,7 +1462,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl, if (current->hvalue != INVALID_HASH) { match_res = db_prog_match(p,mpi.mp, make_tuple(current->dbterm.tpl), - 0,&dummy); + NULL,0,&dummy); if (is_value(match_res)) { if (mpi.all_objects) { hp = HAlloc(p, current->dbterm.size + 2); @@ -1641,7 +1641,7 @@ static int db_select_count_hash(Process *p, if (current != NULL) { if (current->hvalue != INVALID_HASH) { if (db_prog_match(p, mpi.mp, make_tuple(current->dbterm.tpl), - 0, &dummy) == am_true) { + NULL,0, &dummy) == am_true) { ++got; } --num_left; @@ -1792,7 +1792,7 @@ static int db_select_delete_hash(Process *p, int did_erase = 0; if ((db_prog_match(p,mpi.mp, make_tuple((*current)->dbterm.tpl), - 0,&dummy)) == am_true) { + NULL,0,&dummy)) == am_true) { if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */ if (slot_ix != last_pseudo_delete) { add_fixed_deletion(tb, slot_ix); @@ -1904,7 +1904,7 @@ static int db_select_delete_continue_hash(Process *p, else { int did_erase = 0; if ((db_prog_match(p,mp,make_tuple((*current)->dbterm.tpl), - 0,&dummy)) == am_true) { + NULL,0,&dummy)) == am_true) { if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */ if (slot_ix != last_pseudo_delete) { add_fixed_deletion(tb, slot_ix); @@ -2005,7 +2005,7 @@ static int db_select_count_continue_hash(Process *p, continue; } if (db_prog_match(p, mp, make_tuple(current->dbterm.tpl), - 0,&dummy) == am_true) { + NULL,0,&dummy) == am_true) { ++got; } --num_left; diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index f9ed5fe292..b6b3cabafe 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -3023,7 +3023,7 @@ static int doit_select(DbTableTree *tb, TreeDbTerm *this, void *ptr, } ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (is_value(ret)) { Uint sz; Eterm *hp; @@ -3072,7 +3072,7 @@ static int doit_select_count(DbTableTree *tb, TreeDbTerm *this, void *ptr, } ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (ret == am_true) { ++(sc->got); } @@ -3105,7 +3105,7 @@ static int doit_select_chunk(DbTableTree *tb, TreeDbTerm *this, void *ptr, ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (is_value(ret)) { Uint sz; Eterm *hp; @@ -3158,7 +3158,7 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr, return 0; ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (ret == am_true) { key = GETKEY(sc->tb, this->dbterm.tpl); linkout_tree(sc->tb, key); diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index f8baf44e10..165c56cbf1 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -1185,7 +1185,7 @@ Eterm erts_match_set_run(Process *p, Binary *mpsp, Eterm ret; ret = db_prog_match(p, mpsp, - (Eterm) COMPRESS_POINTER(args), + NIL, args, num_args, return_flags); #if defined(HARDDEBUG) if (is_non_value(ret)) { @@ -1380,7 +1380,7 @@ restart: /* ** There is one single top variable in the match expression - ** iff the text is tho Uint's and the single instruction + ** iff the text is two Uint's and the single instruction ** is 'matchBind' or it is only a skip. */ context.special = @@ -1591,6 +1591,7 @@ static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity) ** i.e. 'DCOMP_TRACE' was specified */ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term, + Eterm *termp, int arity, Uint32 *return_flags) { @@ -1710,12 +1711,12 @@ restart: n = *pc++; if ((int) n != arity) FAIL(); - ep = (Eterm *) EXPAND_POINTER(*ep); + ep = termp; break; case matchArrayBind: /* When the array size is unknown. */ /* XXX:PaN - where does this array come from? */ n = *pc++; - hp[n] = dpm_array_to_list(psp, (Eterm *) EXPAND_POINTER(term), arity); + hp[n] = dpm_array_to_list(psp, termp, arity); break; case matchTuple: /* *ep is a tuple of arity n */ if (!is_tuple(*ep)) @@ -2101,13 +2102,13 @@ restart: *esp++ = am_undefined; } else { *esp++ = make_tuple(ehp); - ehp[0] = make_arityval(3); + ehp[0] = make_arityval(3); ehp[1] = cp[0]; ehp[2] = cp[1]; - ehp[3] = make_small((Uint) hp[2]); - ehp += 4; - } - break; + ehp[3] = make_small((Uint) cp[2]); + ehp += 4; + } + break; case matchSilent: --esp; if (*esp == am_true) { @@ -4278,7 +4279,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) } } else { n = 0; - arr = (Eterm *) EXPAND_POINTER(against); + arr = tuple_val(against); } /* We are in the context of a BIF, diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index fbc25aaf2b..5959e62025 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -366,7 +366,7 @@ Binary *db_match_compile(Eterm *matchexpr, Eterm *guards, Uint flags, DMCErrInfo *err_info); /* Returns newly allocated MatchProg binary with refc == 0*/ -Eterm db_prog_match(Process *p, Binary *prog, Eterm term, int arity, +Eterm db_prog_match(Process *p, Binary *prog, Eterm term, Eterm *termp, int arity, Uint32 *return_flags /* Zeroed on enter */); /* returns DB_ERROR_NONE if matches, 1 if not matches and some db error on error. */ diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 25d12bf16e..3a8c30fe6a 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -849,6 +849,11 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm) * */ +/* XXX:PaN - this structure is not perfect for halfword heap, it takes + a lot of memory due to padding, and the array will not begin at the end of the + structure, as otherwise expected. Be sure to access data.ui32 array and not try + to do pointer manipulation on an Eterm * to reach the actual data... */ + typedef struct external_thing_ { /* ----+ */ Eterm header; /* | */ diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 7f39f8eb12..ac8dd27b15 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2260,18 +2260,25 @@ dec_term_atom_common: node = erts_find_or_insert_node(sysname, cre); if(node == erts_this_node) { RefThing *rtp = (RefThing *) hp; - hp += REF_THING_HEAD_SIZE; + ref_num = (Uint32 *) (hp + REF_THING_HEAD_SIZE); + #if defined(ARCH_64) && !HALFWORD_HEAP + hp += REF_THING_HEAD_SIZE + ref_words/2 + 1; rtp->header = make_ref_thing_header(ref_words/2 + 1); #else + hp += REF_THING_HEAD_SIZE + ref_words; rtp->header = make_ref_thing_header(ref_words); #endif *objp = make_internal_ref(rtp); } else { ExternalThing *etp = (ExternalThing *) hp; - hp += EXTERNAL_THING_HEAD_SIZE; - +#if defined(ARCH_64) && !HALFWORD_HEAP + hp += EXTERNAL_THING_HEAD_SIZE + ref_words/2 + 1; +#else + hp += EXTERNAL_THING_HEAD_SIZE + ref_words; +#endif + #if defined(ARCH_64) && !HALFWORD_HEAP etp->header = make_external_ref_header(ref_words/2 + 1); #else @@ -2282,9 +2289,9 @@ dec_term_atom_common: off_heap->externals = etp; *objp = make_external_ref(etp); + ref_num = &(etp->data.ui32[0]); } - ref_num = (Uint32 *) hp; #if defined(ARCH_64) && !HALFWORD_HEAP *(ref_num++) = ref_words /* 32-bit arity */; #endif @@ -2296,9 +2303,6 @@ dec_term_atom_common: #if defined(ARCH_64) && !HALFWORD_HEAP if ((1 + ref_words) % 2) ref_num[ref_words] = 0; - hp += ref_words/2 + 1; -#else - hp += ref_words; #endif break; } diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl index 66ac0422eb..7fed34afdc 100644 --- a/lib/runtime_tools/src/dbg.erl +++ b/lib/runtime_tools/src/dbg.erl @@ -945,7 +945,7 @@ dhandler(end_of_trace, Out) -> dhandler(Trace, Out) when element(1, Trace) == trace, tuple_size(Trace) >= 3 -> dhandler1(Trace, tuple_size(Trace), Out); dhandler(Trace, Out) when element(1, Trace) == trace_ts, tuple_size(Trace) >= 4 -> - dhandler1(Trace, tuple_size(Trace)-1, Out); + dhandler1(Trace, tuple_size(Trace)-1, element(tuple_size(Trace),Trace), Out); dhandler(Trace, Out) when element(1, Trace) == drop, tuple_size(Trace) =:= 2 -> io:format(Out, "*** Dropped ~p messages.~n", [element(2,Trace)]), Out; @@ -978,24 +978,18 @@ dhandler(_Trace, Out) -> Out. dhandler1(Trace, Size, Out) -> -%%%! Self = self(), From = element(2, Trace), case element(3, Trace) of 'receive' -> case element(4, Trace) of {dbg,ok} -> ok; - Message -> io:format(Out, "(~p) << ~p~n", [From,Message]) + Message -> + io:format(Out, "(~p) << ~p~n", [From,Message]) end; 'send' -> Message = element(4, Trace), - case element(5, Trace) of -%%%! This causes messages to disappear when used by ttb (observer). Tests -%%%! so far show that there is no difference in results with dbg even if I -%%%! comment it out, so I hope this is only some old code which isn't -%%%! needed anymore... /siri -%%%! Self -> ok; - To -> io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message]) - end; + To = element(5, Trace), + io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message]); call -> case element(4, Trace) of MFA when Size == 5 -> @@ -1028,6 +1022,51 @@ dhandler1(Trace, Size, Out) -> end, Out. +dhandler1(Trace, Size, TS, Out) -> + From = element(2, Trace), + case element(3, Trace) of + 'receive' -> + case element(4, Trace) of + {dbg,ok} -> ok; + Message -> + io:format(Out, "(~p) << ~p (Timestamp: ~p)~n", [From,Message,TS]) + end; + 'send' -> + Message = element(4, Trace), + To = element(5, Trace), + io:format(Out, "(~p) ~p ! ~p (Timestamp: ~p)~n", [From,To,Message,TS]); + call -> + case element(4, Trace) of + MFA when Size == 5 -> + Message = element(5, Trace), + io:format(Out, "(~p) call ~s (~p) (Timestamp: ~p)~n", [From,ffunc(MFA),Message,TS]); + MFA -> + io:format(Out, "(~p) call ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]) + end; + return -> %% To be deleted... + case element(4, Trace) of + MFA when Size == 5 -> + Ret = element(5, Trace), + io:format(Out, "(~p) old_ret ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]); + MFA -> + io:format(Out, "(~p) old_ret ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]) + end; + return_from -> + MFA = element(4, Trace), + Ret = element(5, Trace), + io:format(Out, "(~p) returned from ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]); + return_to -> + MFA = element(4, Trace), + io:format(Out, "(~p) returning to ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]); + spawn when Size == 5 -> + Pid = element(4, Trace), + MFA = element(5, Trace), + io:format(Out, "(~p) spawn ~p as ~s (Timestamp: ~p)~n", [From,Pid,ffunc(MFA),TS]); + Op -> + io:format(Out, "(~p) ~p ~s (Timestamp: ~p)~n", [From,Op,ftup(Trace,4,Size),TS]) + end, + Out. + %%% These f* functions returns non-flat strings -- cgit v1.2.3 From 3ddf0126dfcb60f0554e2d52187fa012f378e428 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 11 Feb 2010 10:15:53 +0100 Subject: Teach {wordsize,internal|external} to system_info/1 Some test suites need to differentiate between 32-bit terms and 32-bit pointers. While at it, remove some more warnings in process.c for SMP and debug. --- erts/doc/src/erlang.xml | 20 +++++++++++++++++--- erts/emulator/beam/atom.names | 1 + erts/emulator/beam/erl_bif_info.c | 8 ++++++++ erts/emulator/beam/erl_process.c | 2 +- erts/emulator/beam/erl_process.h | 6 +++--- erts/emulator/beam/sys.h | 4 ++-- erts/emulator/test/obsolete_SUITE.erl | 4 ++-- 7 files changed, 34 insertions(+), 11 deletions(-) diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 46f8df4683..0128855def 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -5850,9 +5850,23 @@ true wordsize -

Returns the word size in bytes as an integer, i.e. on a - 32-bit architecture 4 is returned, and on a 64-bit - architecture 8 is returned.

+

Same as {wordsize, internal}

+
+ {wordsize, internal} + +

Returns the size of Erlang term words in bytes as an + integer, i.e. on a 32-bit architecture 4 is returned, + and on a pure 64-bit architecture 8 is returned. On a + halfword 64-bit emulator, 4 is returned, as the Erlang + terms are stored using a virtual wordsize of half the + systems wordsize.

+
+ {wordsize, external} + +

Returns the true wordsize of the emulator, i.e. the size + of a pointer, in bytes as an integer. On a pure 32-bit + architecture 4 is returned, on both a halfword and pure + 64-bit architecture, 8 is returned.

diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index 57c8b08223..9ce21089ba 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -256,6 +256,7 @@ atom info atom info_msg atom initial_call atom input +atom internal atom internal_error atom internal_status atom instruction_counts diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index fc8d876bc4..de4d6f9109 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -1634,6 +1634,14 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */ if (sel == am_allocator_sizes && arity == 2) { return erts_allocator_info_term(BIF_P, *tp, 1); + } else if (sel == am_wordsize && arity == 2) { + if (tp[0] == am_internal) { + return make_small(sizeof(Eterm)); + } + if (tp[0] == am_external) { + return make_small(sizeof(UWord)); + } + goto badarg; } else if (sel == am_allocated) { if (arity == 2) { Eterm res = THE_NON_VALUE; diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 436d81f791..11ca85a41c 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -6241,7 +6241,7 @@ Process *schedule(Process *p, int calls) UWord old = ERTS_PROC_SCHED_ID(p, (ERTS_PROC_LOCK_MAIN | ERTS_PROC_LOCK_STATUS), - esdp->no); + (UWord) esdp->no); int migrated = old && old != esdp->no; erts_smp_spin_lock(&erts_sched_stat.lock); diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index de9664398d..cbcdec4ba7 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -194,8 +194,8 @@ do { \ # define ERTS_DBG_VERIFY_VALID_RUNQP(RQP) \ do { \ ASSERT((RQP) != NULL); \ - ASSERT(((((Uint) (RQP)) & ((Uint) 1))) == ((Uint) 0)); \ - ASSERT((((Uint) (RQP)) & ~((Uint) 0xffff)) != ((Uint) 0xdead0000)); \ + ASSERT(((((UWord) (RQP)) & ((UWord) 1))) == ((UWord) 0)); \ + ASSERT((((UWord) (RQP)) & ~((UWord) 0xffff)) != ((UWord) 0xdead0000)); \ } while (0) # endif #else @@ -1196,7 +1196,7 @@ erts_psd_set(Process *p, ErtsProcLocks plocks, int ix, void *data) #endif #define ERTS_PROC_SCHED_ID(P, L, ID) \ - ((Uint) erts_psd_set((P), (L), ERTS_PSD_SCHED_ID, (void *) (ID))) + ((UWord) erts_psd_set((P), (L), ERTS_PSD_SCHED_ID, (void *) (ID))) #define ERTS_PROC_GET_DIST_ENTRY(P) \ ((DistEntry *) erts_psd_get((P), ERTS_PSD_DIST_ENTRY)) diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 7ddf1d8278..86570af96e 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -262,10 +262,10 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...)); #ifdef ARCH_64 # ifdef HALFWORD_HEAP_EMULATOR # define HALFWORD_HEAP 1 -# define HALFWORD_ASSERT 1 +# define HALFWORD_ASSERT 0 # else # define HALFWORD_HEAP 0 -# define HALFWORD_ASSERT 1 +# define HALFWORD_ASSERT 0 # endif #endif diff --git a/erts/emulator/test/obsolete_SUITE.erl b/erts/emulator/test/obsolete_SUITE.erl index 33c4726699..eb7e34ad6b 100644 --- a/erts/emulator/test/obsolete_SUITE.erl +++ b/erts/emulator/test/obsolete_SUITE.erl @@ -32,9 +32,9 @@ all(doc) -> []; all(suite) -> - case catch erlang:system_info(wordsize) of + case catch erlang:system_info({wordsize,external}) of 4 -> [erl_threads]; - _ -> {skip, "Only expected to work on 32-bit architectures"} + _ -> {skip, "Only expected to work on true 32-bit architectures"} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From ac0b3f0a64705717d21e4a3d84d91d9c44f3baf7 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 11 Feb 2010 11:00:47 +0100 Subject: Correct the VM to work for more test suites The following test suites now work: send_term_SUITE trace_nif_SUITE binary_SUITE match_spec_SUITE node_container_SUITE beam_literals_SUITE Also add a testcases for system_info({wordsize,internal|external}). --- erts/emulator/beam/beam_emu.c | 6 +- erts/emulator/beam/big.c | 4 +- erts/emulator/beam/big.h | 2 +- erts/emulator/beam/erl_db.c | 5 +- erts/emulator/beam/erl_db_util.c | 184 +++++++++++++++++++++++-------- erts/emulator/beam/erl_node_tables.c | 6 +- erts/emulator/beam/external.c | 4 + erts/emulator/test/system_info_SUITE.erl | 24 +++- 8 files changed, 180 insertions(+), 55 deletions(-) diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 1078478ed9..0d1cce52ca 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -2775,7 +2775,7 @@ void process_main(void) given_size = thing_arityval(given_arity); bigp = (Eterm *) &Arg(2); while ((arity = bigp[0]) > given_arity) { - bigp += thing_arityval(arity) + 2; + bigp += (TermWords(thing_arityval(arity) + 1) + 1) * (sizeof(BeamInstr)/sizeof(Eterm)); } while (bigp[0] == given_arity) { if (memcmp(bigp+1, given+1, sizeof(Eterm)*given_size) == 0) { @@ -2784,7 +2784,7 @@ void process_main(void) SET_I((BeamInstr *) *tmp); Goto(*I); } - bigp += thing_arityval(arity) + 2; + bigp += (TermWords(thing_arityval(arity) + 1) + 1) * (sizeof(BeamInstr)/sizeof(Eterm)); } } @@ -4291,7 +4291,7 @@ apply_bif_or_nif_epilogue: */ OpCase(call_traced_function): { if (IS_TRACED_FL(c_p, F_TRACE_CALLS)) { - unsigned offset = offsetof(Export, code) + 3*sizeof(Eterm); + unsigned offset = offsetof(Export, code) + 3*sizeof(BeamInstr); Export* ep = (Export *) (((char *)I)-offset); Uint32 flags; diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index c70044ed43..40c8e15436 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1504,7 +1504,7 @@ Eterm small_to_big(Sint x, Eterm *y) Eterm erts_uint64_to_big(Uint64 x, Eterm **hpp) { Eterm *hp = *hpp; -#ifdef ARCH_32 +#if defined(ARCH_32) || HALFWORD_HEAP if (x >= (((Uint64) 1) << 32)) { *hp = make_pos_bignum_header(2); BIG_DIGIT(hp, 0) = (Uint) (x & ((Uint) 0xffffffff)); @@ -1531,7 +1531,7 @@ Eterm erts_sint64_to_big(Sint64 x, Eterm **hpp) neg = 1; x = -x; } -#ifdef ARCH_32 +#if defined(ARCH_32) || HALFWORD_HEAP if (x >= (((Uint64) 1) << 32)) { if (neg) *hp = make_neg_bignum_header(2); diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h index 39689189e5..4047bd3fe3 100644 --- a/erts/emulator/beam/big.h +++ b/erts/emulator/beam/big.h @@ -94,7 +94,7 @@ typedef Uint dsize_t; /* Vector size type */ #define BIG_UWORD_HEAP_SIZE(UW) BIG_UINT_HEAP_SIZE #endif -#ifdef ARCH_32 +#if defined(ARCH_32) || HALFWORD_HEAP #define ERTS_UINT64_BIG_HEAP_SIZE__(X) \ ((X) >= (((Uint64) 1) << 32) ? (1 + 2) : (1 + 1)) diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 4c75659246..cbdaa459de 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -3359,8 +3359,11 @@ static BIF_RETTYPE ets_delete_trap(Process *p, Eterm cont) Eterm* ptr = big_val(cont); DbTable *tb = *((DbTable **) (UWord) (ptr + 1)); +#if HALFWORD_HEAP + ASSERT(*ptr == make_pos_bignum_header(2)); +#else ASSERT(*ptr == make_pos_bignum_header(1)); - +#endif db_lock(tb, LCK_WRITE); trap = free_table_cont(p, tb, 0, 1); db_unlock(tb, LCK_WRITE); diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 165c56cbf1..288f1f6d12 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -117,6 +117,10 @@ do { \ erts_free(ERTS_ALC_T_DB_MC_STK, (Name).data); \ } while (0) + +#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm)))) + + static ERTS_INLINE Process * get_proc(Process *cp, Uint32 cp_locks, Eterm id, Uint32 id_locks) { @@ -1204,6 +1208,32 @@ Eterm erts_match_set_run(Process *p, Binary *mpsp, */ } +static Eterm erts_match_set_run_ets(Process *p, Binary *mpsp, + Eterm args, int num_args, + Uint32 *return_flags) +{ + Eterm ret; + + ret = db_prog_match(p, mpsp, + args, NULL, + num_args, return_flags); +#if defined(HARDDEBUG) + if (is_non_value(ret)) { + erts_fprintf(stderr, "Failed\n"); + } else { + erts_fprintf(stderr, "Returning : %T\n", ret); + } +#endif + return ret; + /* Returns + * THE_NON_VALUE if no match + * am_false if {message,false} has been called, + * am_true if {message,_} has not been called or + * if {message,true} has been called, + * Msg if {message,Msg} has been called. + */ +} + /* ** API Used by other erl_db modules. */ @@ -1773,29 +1803,34 @@ restart: FAIL(); if (memcmp(float_val(*ep) + 1, pc, sizeof(double))) FAIL(); - pc += 2; + pc += TermWords(2); ++ep; break; case matchEqRef: if (!is_ref(*ep)) FAIL(); - if (!eq(*ep, make_internal_ref(pc))) + if (!eq(*ep, make_internal_ref((Uint *) pc))) FAIL(); - i = thing_arityval(*pc); - pc += i+1; + i = thing_arityval(*((Uint *) pc)); + pc += TermWords(i+1); ++ep; break; case matchEqBig: if (!is_big(*ep)) FAIL(); tp = big_val(*ep); - if (*tp != *pc) - FAIL(); - i = BIG_ARITY(pc); - while(i--) - if (*++tp != *++pc) + { + Eterm *epc = (Eterm *) pc; + if (*tp != *epc) FAIL(); - ++pc; + i = BIG_ARITY(epc); + pc += TermWords(i+1); + while(i--) { + if (*++tp != *++epc) { + FAIL(); + } + } + } ++ep; break; case matchEq: @@ -1887,7 +1922,7 @@ restart: break; case matchPushArrayAsList: n = arity; /* Only happens when 'term' is an array */ - tp = (Eterm *) EXPAND_POINTER(term); + tp = termp; *esp++ = make_list(ehp); while (n--) { *ehp++ = *tp++; @@ -1900,7 +1935,7 @@ restart: break; case matchPushArrayAsListU: /* This instruction is NOT efficient. */ - *esp++ = dpm_array_to_list(psp, (Eterm *) EXPAND_POINTER(term), arity); + *esp++ = dpm_array_to_list(psp, termp, arity); break; case matchTrue: if (*--esp != am_true) @@ -2710,27 +2745,80 @@ static DMCRet dmc_one_term(DMCContext *context, DMC_PUSH(*stack, c); break; case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE): - n = thing_arityval(*internal_ref_val(c)); DMC_PUSH(*text, matchEqRef); +#if HALFWORD_HEAP + { + union { + UWord u; + Uint t[2]; + } fiddle; + ASSERT(thing_arityval(*internal_ref_val(c)) == 3); + fiddle.t[0] = *internal_ref_val(c); + fiddle.t[1] = (Uint) internal_ref_val(c)[1]; + DMC_PUSH(*text, fiddle.u); + fiddle.t[0] = (Uint) internal_ref_val(c)[2]; + fiddle.t[1] = (Uint) internal_ref_val(c)[3]; + DMC_PUSH(*text, fiddle.u); + } +#else + n = thing_arityval(*internal_ref_val(c)); DMC_PUSH(*text, *internal_ref_val(c)); for (i = 1; i <= n; ++i) { DMC_PUSH(*text, (Uint) internal_ref_val(c)[i]); } +#endif break; case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE): case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE): n = thing_arityval(*big_val(c)); DMC_PUSH(*text, matchEqBig); +#if HALFWORD_HEAP + { + union { + UWord u; + Uint t[2]; + } fiddle; + ASSERT(n >= 1); + fiddle.t[0] = *big_val(c); + fiddle.t[1] = big_val(c)[1]; + DMC_PUSH(*text, fiddle.u); + for (i = 2; i <= n; ++i) { + fiddle.t[0] = big_val(c)[i]; + if (++i <= n) { + fiddle.t[1] = big_val(c)[i]; + } else { + fiddle.t[1] = (Uint) 0; + } + DMC_PUSH(*text, fiddle.u); + } + } +#else DMC_PUSH(*text, *big_val(c)); for (i = 1; i <= n; ++i) { DMC_PUSH(*text, (Uint) big_val(c)[i]); } +#endif break; case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE): DMC_PUSH(*text,matchEqFloat); +#if HALFWORD_HEAP + { + union { + UWord u; + Uint t[2]; + } fiddle; + fiddle.t[0] = float_val(c)[1]; + fiddle.t[1] = float_val(c)[2]; + DMC_PUSH(*text, fiddle.u); + } +#else DMC_PUSH(*text, (Uint) float_val(c)[1]); - /* XXX: this reads and pushes random junk on ARCH_64 */ +#ifdef ARCH_64 + DMC_PUSH(*text, (Uint) 0); +#else DMC_PUSH(*text, (Uint) float_val(c)[2]); +#endif +#endif break; default: /* BINARY, FUN, VECTOR, or EXTERNAL */ /* @@ -4277,17 +4365,18 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) ++n; l = CDR(list_val(l)); } + save_cp = p->cp; + p->cp = NULL; + res = erts_match_set_run(p, mps, arr, n, &ret_flags); + p->cp = save_cp; } else { n = 0; - arr = tuple_val(against); + arr = NULL; + res = erts_match_set_run_ets(p, mps, against, n, &ret_flags); } /* We are in the context of a BIF, {caller} should return 'undefined' */ - save_cp = p->cp; - p->cp = NULL; - res = erts_match_set_run(p, mps, arr, n, &ret_flags); - p->cp = save_cp; if (is_non_value(res)) { res = am_false; } @@ -4396,41 +4485,48 @@ static void db_match_dis(Binary *bp) break; case matchEqRef: ++t; - n = thing_arityval(*t); - ++t; - erts_printf("EqRef\t(%d) {", (int) n); - first = 1; - while (n--) { - if (first) - first = 0; - else - erts_printf(", "); + { + RefThing *rt = (RefThing *) t; + int ri; + n = thing_arityval(rt->header); + erts_printf("EqRef\t(%d) {", (int) n); + first = 1; + for (ri = 0; ri < n; ++ri) { + if (first) + first = 0; + else + erts_printf(", "); #if defined(ARCH_64) && !HALFWORD_HEAP - erts_printf("0x%016bpx", *t); + erts_printf("0x%016bpx", rt->data.ui[ri]); #else - erts_printf("0x%08bpx", *t); + erts_printf("0x%08bpx", rt->data.ui[ri]); #endif - ++t; + } } + t += TermWords(REF_THING_SIZE); erts_printf("}\n"); break; case matchEqBig: ++t; n = thing_arityval(*t); - ++t; - erts_printf("EqBig\t(%d) {", (int) n); - first = 1; - while (n--) { - if (first) - first = 0; - else - erts_printf(", "); + { + Eterm *et = (Eterm *) t; + t += TermWords(n+1); + erts_printf("EqBig\t(%d) {", (int) n); + first = 1; + ++n; + while (n--) { + if (first) + first = 0; + else + erts_printf(", "); #if defined(ARCH_64) && !HALFWORD_HEAP - erts_printf("0x%016bpx", *t); + erts_printf("0x%016bpx", *et); #else - erts_printf("0x%08bpx", *t); + erts_printf("0x%08bpx", *et); #endif - ++t; + ++et; + } } erts_printf("}\n"); break; @@ -4438,8 +4534,8 @@ static void db_match_dis(Binary *bp) ++t; { double num; - memcpy(&num,t, 2 * sizeof(*t)); - t += 2; + memcpy(&num,t,sizeof(double)); + t += TermWords(2); erts_printf("EqFloat\t%f\n", num); } break; diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 6960844e99..de4c4e353e 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -1118,7 +1118,9 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) Uint *hp = &id_heap[0]; InsertedBin *nib; #if HALFWORD_HEAP - UseTmpHeapNoproc(BIG_UWORD_HEAP_SIZE(val)); + int actual_need = BIG_UWORD_HEAP_SIZE(val); + ASSERT(actual_need <= (BIG_UINT_HEAP_SIZE*2)); + UseTmpHeapNoproc(actual_need); a.id = erts_bld_uword(&hp, NULL, (UWord) val); #else UseTmpHeapNoproc(BIG_UINT_HEAP_SIZE); @@ -1132,7 +1134,7 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) nib->next = inserted_bins; inserted_bins = nib; #if HALFWORD_HEAP - UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE*2); + UnUseTmpHeapNoproc(actual_need); #else UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE); #endif diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index ac8dd27b15..badefb728d 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -3011,7 +3011,11 @@ decoded_size(byte *ep, byte* endp, int no_refc_bins) break; case EXPORT_EXT: terms += 3; +#if HALFWORD_HEAP + heap_size += 3; +#else heap_size += 2; +#endif break; case NEW_FUN_EXT: { diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index e782d2f293..ba433d4e11 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -35,12 +35,12 @@ %-compile(export_all). -export([all/1, init_per_testcase/2, fin_per_testcase/2]). --export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1]). +-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1]). -define(DEFAULT_TIMEOUT, ?t:minutes(2)). all(doc) -> []; -all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size]. +all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size, wordsize]. init_per_testcase(_Case, Config) when is_list(Config) -> Dog = ?t:timetrap(?DEFAULT_TIMEOUT), @@ -145,3 +145,23 @@ heap_size(Config) when is_list(Config) -> ?line Hmin = proplists:get_value(min_heap_size, GCinf), ok. +wordsize(suite) -> + []; +wordsize(doc) -> + ["Tests the various wordsize variants"]; +wordsize(Config) when is_list(Config) -> + ?line A = erlang:system_info(wordsize), + ?line true = is_integer(A), + ?line A = erlang:system_info({wordsize,internal}), + ?line B = erlang:system_info({wordsize,external}), + ?line true = A =< B, + case {B,A} of + {4,4} -> + {comment, "True 32-bit emulator"}; + {8,8} -> + {comment, "True 64-bit emulator"}; + {8,4} -> + {comment, "Halfword 64-bit emulator"}; + Other -> + exit({unexpected_wordsizes,Other}) + end. -- cgit v1.2.3 From 37950725305fb8e911556608402cba6e4e17b87d Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 12 Feb 2010 16:17:25 +0100 Subject: Fix further test-suite problems Fix safe_mul in the loader, which caused failures in the bit syntax test cases. Fix yet another Uint in erl_alloc.h (ERTS_CACHE_LINE_SIZE) causing segmentation fault when we have many schedulers (why only in that situation?). Clean up erl_mseg (remove old code for the Linux 32-bit mmap flag). While at it, also remove compilation warnings. --- erts/emulator/beam/beam_emu.c | 14 +++++++------- erts/emulator/beam/beam_load.c | 18 +++++++++--------- erts/emulator/beam/binary.c | 2 +- erts/emulator/beam/erl_alloc.h | 2 +- erts/emulator/beam/erl_bif_info.c | 9 +++++---- erts/emulator/beam/external.c | 2 +- erts/emulator/sys/common/erl_mseg.c | 31 +++---------------------------- 7 files changed, 27 insertions(+), 51 deletions(-) diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 0d1cce52ca..834cc8df61 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -4906,13 +4906,13 @@ apply_bif_or_nif_epilogue: em_call_error_handler = OpCode(call_error_handler); em_call_traced_function = OpCode(call_traced_function); em_apply_bif = OpCode(apply_bif); - beam_apply[0] = (Eterm) OpCode(i_apply); - beam_apply[1] = (Eterm) OpCode(normal_exit); - beam_exit[0] = (Eterm) OpCode(error_action_code); - beam_continue_exit[0] = (Eterm) OpCode(continue_exit); - beam_return_to_trace[0] = (Eterm) OpCode(i_return_to_trace); - beam_return_trace[0] = (Eterm) OpCode(return_trace); - beam_exception_trace[0] = (Eterm) OpCode(return_trace); /* UGLY */ + beam_apply[0] = (BeamInstr) OpCode(i_apply); + beam_apply[1] = (BeamInstr) OpCode(normal_exit); + beam_exit[0] = (BeamInstr) OpCode(error_action_code); + beam_continue_exit[0] = (BeamInstr) OpCode(continue_exit); + beam_return_to_trace[0] = (BeamInstr) OpCode(i_return_to_trace); + beam_return_trace[0] = (BeamInstr) OpCode(return_trace); + beam_exception_trace[0] = (BeamInstr) OpCode(return_trace); /* UGLY */ /* * Enter all BIFs into the export table. diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 22c6c39cf5..e4313e6a44 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -3403,21 +3403,21 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif, op->a[1].type = TAG_u; bf = stp->import[Bif.val].bf; if (bf == length_1) { - op->a[1].val = (Uint) (void *) erts_gc_length_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_length_1; } else if (bf == size_1) { - op->a[1].val = (Uint) (void *) erts_gc_size_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_size_1; } else if (bf == bit_size_1) { - op->a[1].val = (Uint) (void *) erts_gc_bit_size_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_bit_size_1; } else if (bf == byte_size_1) { - op->a[1].val = (Uint) (void *) erts_gc_byte_size_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_byte_size_1; } else if (bf == abs_1) { - op->a[1].val = (Uint) (void *) erts_gc_abs_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_abs_1; } else if (bf == float_1) { - op->a[1].val = (Uint) (void *) erts_gc_float_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_float_1; } else if (bf == round_1) { - op->a[1].val = (Uint) (void *) erts_gc_round_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_round_1; } else if (bf == trunc_1) { - op->a[1].val = (Uint) (void *) erts_gc_trunc_1; + op->a[1].val = (BeamInstr) (void *) erts_gc_trunc_1; } else { abort(); } @@ -5306,7 +5306,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) static int safe_mul(UWord a, UWord b, UWord* resp) { - UWord res = a * b; + Uint res = a * b; /* XXX:Pan - used in bit syntax, the multiplication has to be stored in Uint */ *resp = res; if (b == 0) { diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c index 08c64610a2..59c20398d5 100644 --- a/erts/emulator/beam/binary.c +++ b/erts/emulator/beam/binary.c @@ -42,7 +42,7 @@ void erts_init_binary(void) { /* Verify Binary alignment... */ - if ((((Uint) &((Binary *) 0)->orig_bytes[0]) % ((Uint) 8)) != 0) { + if ((((UWord) &((Binary *) 0)->orig_bytes[0]) % ((UWord) 8)) != 0) { /* I assume that any compiler should be able to optimize this away. If not, this test is not very expensive... */ erl_exit(ERTS_ABORT_EXIT, diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h index 1080a24214..b7d6674a8a 100644 --- a/erts/emulator/beam/erl_alloc.h +++ b/erts/emulator/beam/erl_alloc.h @@ -238,7 +238,7 @@ void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size) #ifndef ERTS_CACHE_LINE_SIZE /* Assume a cache line size of 64 bytes */ -# define ERTS_CACHE_LINE_SIZE ((Uint) 64) +# define ERTS_CACHE_LINE_SIZE ((UWord) 64) # define ERTS_CACHE_LINE_MASK (ERTS_CACHE_LINE_SIZE - 1) #endif diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index de4d6f9109..18cb09d8cd 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -59,18 +59,19 @@ /* Keep erts_system_version as a global variable for easy access from a core */ static char erts_system_version[] = ("Erlang " ERLANG_OTP_RELEASE " (erts-" ERLANG_VERSION ")" -#if HALFWORD_HEAP - " [halfword]" -#endif -#if !HEAP_ON_C_STACK +#if !HEAP_ON_C_STACK && !HALFWORD_HEAP " [no-c-stack-objects]" #endif #ifndef OTP_RELEASE " [source]" #endif #ifdef ARCH_64 +#if HALFWORD_HEAP + " [64-bit halfword]" +#else " [64-bit]" #endif +#endif #ifdef ERTS_SMP " [smp:%bpu:%bpu]" #endif diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index badefb728d..f41b61d73d 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -1974,7 +1974,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et register Eterm* hp = *hpp; /* Please don't take the address of hp */ Eterm* next = objp; - *next = (Eterm) NULL; + *next = (Eterm) (UWord) NULL; while (next != NULL) { objp = next; diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c index 747c2e2a80..7b42c3e829 100644 --- a/erts/emulator/sys/common/erl_mseg.c +++ b/erts/emulator/sys/common/erl_mseg.c @@ -96,21 +96,12 @@ static void *pmremap(void *old_address, size_t old_size, #define MMAP_PROT (PROT_READ|PROT_WRITE) -#if HALFWORD_HEAP -# ifdef MAP_32BIT -# define RANGE_FLAG (MAP_32BIT) -# else -# error "Cannot have halfword heap if unable to restrict mmap areas -# endif -#else -# define RANGE_FLAG (0) -#endif #ifdef MAP_ANON -# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE|RANGE_FLAG) +# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE) # define MMAP_FD (-1) #else -# define MMAP_FLAGS (MAP_PRIVATE|RANGE_FLAG) +# define MMAP_FLAGS (MAP_PRIVATE) # define MMAP_FD mmap_fd static int mmap_fd; #endif @@ -1342,20 +1333,6 @@ erts_mseg_unit_size(void) { return page_size; } -#if HAVE_MMAP && HALFWORD_HEAP -#ifdef MAP_NORESERVE -#define RESERVE_FLAGS (MMAP_FLAGS | MAP_NORESERVE) -#else -#define RESERVE_FLAGS (MMAP_FLAGS) -#endif -static void halfword_reserve(void) -{ -#if HALFWORD_HEAP - initialize_pmmap(); -#endif - return; -} -#endif void erts_mseg_init(ErtsMsegInit_t *init) @@ -1385,7 +1362,7 @@ erts_mseg_init(ErtsMsegInit_t *init) #endif #if HAVE_MMAP && HALFWORD_HEAP - halfword_reserve(); + initialize_pmmap(); #endif page_size = GET_PAGE_SIZE; @@ -1740,8 +1717,6 @@ static void *pmmap(size_t size) /* nice, perfect fit */ res = *block; *block = (*block)->next; - //fprintf(stderr,"***** %p,%p,%ld,%p\n",res,*block,num_pages,first); - //dump_freelist(); } else { tail = (FreeBlock *) (((char *) ((void *) (*block))) + real_size); if (!do_map(tail,pagsz)) { -- cgit v1.2.3 From 42c8a5ab9bdcf8c139f1c5a558e64d39716a6582 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 19 Feb 2010 16:25:54 +0100 Subject: Support monitoring and demonitoring from driver threads The driver in the wx application does monitoring (and demonitoring) from non-scheduler threads. In the non-half-word emulators, data will be modified without the protection of a lock (which is potentially bad), but the half-word emulator will crash in that situation. While at it, also correct an old bug which make assertions fail in the Kernel test suite. --- erts/emulator/beam/io.c | 232 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 210 insertions(+), 22 deletions(-) diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 0a2a2c60e2..10f1082039 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -72,6 +72,15 @@ erts_driver_t fd_driver; static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *); static void terminate_port(Port *p); static void pdl_init(void); +#ifdef ERTS_SMP +static void driver_monitor_lock_pdl(Port *p); +static void driver_monitor_unlock_pdl(Port *p); +#define DRV_MONITOR_LOCK_PDL(Port) driver_monitor_lock_pdl(Port) +#define DRV_MONITOR_UNLOCK_PDL(Port) driver_monitor_unlock_pdl(Port) +#else +#define DRV_MONITOR_LOCK_PDL(Port) /* nothing */ +#define DRV_MONITOR_UNLOCK_PDL(Port) /* nothing */ +#endif static ERTS_INLINE ErlIOQueue* drvport2ioq(ErlDrvPort drvport) @@ -1998,12 +2007,13 @@ erts_do_exit_port(Port *p, Eterm from, Eterm reason) p->nlinks = NULL; erts_sweep_links(lnk, &sweep_one_link, &sc); } + DRV_MONITOR_LOCK_PDL(p); { ErtsMonitor *moni = p->monitors; p->monitors = NULL; erts_sweep_monitors(moni, &sweep_one_monitor, NULL); } - + DRV_MONITOR_UNLOCK_PDL(p); if ((p->status & ERTS_PORT_SFLG_DISTRIBUTION) && p->dist_entry) { erts_do_net_exits(p->dist_entry, rreason); @@ -3536,6 +3546,32 @@ static ERTS_INLINE void pdl_destroy(ErlDrvPDL pdl) erts_free(ERTS_ALC_T_PORT_DATA_LOCK, pdl); } +#ifdef ERTS_SMP + +static void driver_monitor_lock_pdl(Port *p) { + if (p->port_data_lock) { + driver_pdl_lock(p->port_data_lock); + } + /* Now we either have the port lock or the port_data_lock */ + ERTS_LC_ASSERT(!p->port_data_lock + || erts_lc_mtx_is_locked(&(p->port_data_lock->mtx))); + ERTS_SMP_LC_ASSERT(p->port_data_lock + || erts_lc_is_port_locked(p)); +} + +static void driver_monitor_unlock_pdl(Port *p) { + /* We should either have the port lock or the port_data_lock */ + ERTS_LC_ASSERT(!p->port_data_lock + || erts_lc_mtx_is_locked(&(p->port_data_lock->mtx))); + ERTS_SMP_LC_ASSERT(p->port_data_lock + || erts_lc_is_port_locked(p)); + if (p->port_data_lock) { + driver_pdl_unlock(p->port_data_lock); + } +} + +#endif + /* * exported driver_pdl_* functions ... */ @@ -4076,14 +4112,14 @@ static void ref_to_driver_monitor(Eterm ref, ErlDrvMonitor *mon) memcpy(mon,refp,sizeof(RefThing)); } -int driver_monitor_process(ErlDrvPort port, - ErlDrvTermData process, - ErlDrvMonitor *monitor) + +static int do_driver_monitor_process(Port *prt, + Eterm *buf, + ErlDrvTermData process, + ErlDrvMonitor *monitor) { - Port *prt = erts_drvport2port(port); Process *rp; Eterm ref; - DeclareTmpHeapNoproc(buf,REF_THING_SIZE); if (prt->drv_ptr->process_exit == NULL) { return -1; @@ -4094,29 +4130,79 @@ int driver_monitor_process(ErlDrvPort port, if (!rp) { return 1; } - UseTmpHeapNoproc(REF_THING_SIZE); + ref = erts_make_ref_in_buffer(buf); erts_add_monitor(&(prt->monitors), MON_ORIGIN, ref, rp->id, NIL); erts_add_monitor(&(rp->monitors), MON_TARGET, ref, prt->id, NIL); - + erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK); ref_to_driver_monitor(ref,monitor); - UnUseTmpHeapNoproc(REF_THING_SIZE); return 0; } -int driver_demonitor_process(ErlDrvPort port, - const ErlDrvMonitor *monitor) +/* + * This can be called from a non scheduler thread iff a port_data_lock exists + */ +int driver_monitor_process(ErlDrvPort port, + ErlDrvTermData process, + ErlDrvMonitor *monitor) +{ + Port *prt; + int ret; + Uint32 status; + ErtsSchedulerData *sched = erts_get_scheduler_data(); + int ix = (int) port; + if (ix < 0 || erts_max_ports <= ix) { + return -1; + } + prt = &erts_port[ix]; + + DRV_MONITOR_LOCK_PDL(prt); + + if (sched) { + status = erts_port[ix].status; + } else { + erts_smp_port_state_lock(prt); + status = erts_port[ix].status; + erts_smp_port_state_unlock(prt); + } + + if (status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) { + DRV_MONITOR_UNLOCK_PDL(prt); + return -1; + } + + /* Now (in SMP) we should have either the port lock (if we have a scheduler) or the port data lock + (if we're a driver thread) */ + ERTS_SMP_LC_ASSERT((sched != NULL || prt->port_data_lock)); + +#if !HEAP_ON_C_STACK + if (!sched) { + /* Need a separate allocation for the ref :( */ + Eterm *buf = erts_alloc(ERTS_ALC_T_TEMP_TERM, + sizeof(Eterm)*REF_THING_SIZE); + ret = do_driver_monitor_process(prt,buf,process,monitor); + erts_free(ERTS_ALC_T_TEMP_TERM,buf); + } else +#endif + { + DeclareTmpHeapNoproc(buf,REF_THING_SIZE); + UseTmpHeapNoproc(REF_THING_SIZE); + ret = do_driver_monitor_process(prt,buf,process,monitor); + UnUseTmpHeapNoproc(REF_THING_SIZE); + } + DRV_MONITOR_UNLOCK_PDL(prt); + return ret; +} + +static int do_driver_demonitor_process(Port *prt, Eterm *buf, + const ErlDrvMonitor *monitor) { - Port *prt = erts_drvport2port(port); Process *rp; Eterm ref; - DeclareTmpHeapNoproc(buf,REF_THING_SIZE); ErtsMonitor *mon; Eterm to; - - UseTmpHeapNoproc(REF_THING_SIZE); memcpy(buf,monitor,sizeof(Eterm)*REF_THING_SIZE); ref = make_internal_ref(buf); mon = erts_lookup_monitor(prt->monitors, ref); @@ -4143,20 +4229,66 @@ int driver_demonitor_process(ErlDrvPort port, erts_destroy_monitor(rmon); } } - UnUseTmpHeapNoproc(REF_THING_SIZE); return 0; } -ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, +int driver_demonitor_process(ErlDrvPort port, + const ErlDrvMonitor *monitor) +{ + Port *prt; + int ret; + Uint32 status; + ErtsSchedulerData *sched = erts_get_scheduler_data(); + int ix = (int) port; + if (ix < 0 || erts_max_ports <= ix) { + return -1; + } + prt = &erts_port[ix]; + + DRV_MONITOR_LOCK_PDL(prt); + + if (sched) { + status = erts_port[ix].status; + } else { + erts_smp_port_state_lock(prt); + status = erts_port[ix].status; + erts_smp_port_state_unlock(prt); + } + + if (status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) { + DRV_MONITOR_UNLOCK_PDL(prt); + return -1; + } + + /* Now we should have either the port lock (if we have a scheduler) or the port data lock + (if we're a driver thread) */ + ERTS_SMP_LC_ASSERT((sched != NULL || prt->port_data_lock)); +#if !HEAP_ON_C_STACK + if (!sched) { + /* Need a separate allocation for the ref :( */ + Eterm *buf = erts_alloc(ERTS_ALC_T_TEMP_TERM, + sizeof(Eterm)*REF_THING_SIZE); + ret = do_driver_demonitor_process(prt,buf,monitor); + erts_free(ERTS_ALC_T_TEMP_TERM,buf); + } else +#endif + { + DeclareTmpHeapNoproc(buf,REF_THING_SIZE); + UseTmpHeapNoproc(REF_THING_SIZE); + ret = do_driver_demonitor_process(prt,buf,monitor); + UnUseTmpHeapNoproc(REF_THING_SIZE); + } + DRV_MONITOR_UNLOCK_PDL(prt); + return ret; +} + +static ErlDrvTermData do_driver_get_monitored_process(Port *prt, Eterm *buf, const ErlDrvMonitor *monitor) { - Port *prt = erts_drvport2port(port); Eterm ref; - DeclareTmpHeapNoproc(buf,REF_THING_SIZE); ErtsMonitor *mon; Eterm to; - UseTmpHeapNoproc(REF_THING_SIZE); memcpy(buf,monitor,sizeof(Eterm)*REF_THING_SIZE); ref = make_internal_ref(buf); mon = erts_lookup_monitor(prt->monitors, ref); @@ -4166,10 +4298,62 @@ ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, ASSERT(mon->type == MON_ORIGIN); to = mon->pid; ASSERT(is_internal_pid(to)); - UnUseTmpHeapNoproc(REF_THING_SIZE); return (ErlDrvTermData) to; } + +ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, + const ErlDrvMonitor *monitor) +{ + Port *prt; + ErlDrvTermData ret; + Uint32 status; + ErtsSchedulerData *sched = erts_get_scheduler_data(); + int ix = (int) port; + if (ix < 0 || erts_max_ports <= ix) { + return driver_term_nil; + } + prt = &erts_port[ix]; + + DRV_MONITOR_LOCK_PDL(prt); + + if (sched) { + status = erts_port[ix].status; + } else { + erts_smp_port_state_lock(prt); + status = erts_port[ix].status; + erts_smp_port_state_unlock(prt); + } + + if (status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) { + DRV_MONITOR_UNLOCK_PDL(prt); + return driver_term_nil; + } + + /* Now we should have either the port lock (if we have a scheduler) or the port data lock + (if we're a driver thread) */ + ERTS_SMP_LC_ASSERT((sched != NULL || prt->port_data_lock)); + +#if !HEAP_ON_C_STACK + if (!sched) { + /* Need a separate allocation for the ref :( */ + Eterm *buf = erts_alloc(ERTS_ALC_T_TEMP_TERM, + sizeof(Eterm)*REF_THING_SIZE); + ret = do_driver_get_monitored_process(prt,buf,monitor); + erts_free(ERTS_ALC_T_TEMP_TERM,buf); + } else +#endif + { + DeclareTmpHeapNoproc(buf,REF_THING_SIZE); + UseTmpHeapNoproc(REF_THING_SIZE); + ret = do_driver_get_monitored_process(prt,buf,monitor); + UnUseTmpHeapNoproc(REF_THING_SIZE); + } + DRV_MONITOR_UNLOCK_PDL(prt); + return ret; +} + + int driver_compare_monitors(const ErlDrvMonitor *monitor1, const ErlDrvMonitor *monitor2) { @@ -4185,18 +4369,22 @@ void erts_fire_port_monitor(Port *prt, Eterm ref) ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt)); ASSERT(prt->drv_ptr != NULL); - + DRV_MONITOR_LOCK_PDL(prt); if (erts_lookup_monitor(prt->monitors,ref) == NULL) { + DRV_MONITOR_UNLOCK_PDL(prt); return; } callback = prt->drv_ptr->process_exit; ASSERT(callback != NULL); ref_to_driver_monitor(ref,&drv_monitor); + DRV_MONITOR_UNLOCK_PDL(prt); fpe_was_unmasked = erts_block_fpe(); (*callback)((ErlDrvData) (prt->drv_data), &drv_monitor); erts_unblock_fpe(fpe_was_unmasked); + DRV_MONITOR_LOCK_PDL(prt); /* remove monitor *after* callback */ rmon = erts_remove_monitor(&(prt->monitors),ref); + DRV_MONITOR_UNLOCK_PDL(prt); if (rmon) { erts_destroy_monitor(rmon); } -- cgit v1.2.3 From e2f78fbb4dabb19dd908821febc64acd843ad5b4 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Mon, 1 Mar 2010 15:43:48 +0100 Subject: Adopt the new (R13B04) Nif functionality to the halfword codebase Change erl_int_sizes_config to include HALFWORD_HEAP_EMULATOR, which make it possible for the NIFs to figure out the term size. --- erts/emulator/beam/erl_driver.h | 9 +++++++++ erts/emulator/beam/erl_nif.c | 4 ++-- erts/emulator/beam/erl_nif.h | 30 ++++++++++++++++++++++++++++++ erts/include/erl_int_sizes_config.h.in | 3 +++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index 316d0ef992..15a4f44a7d 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -48,6 +48,10 @@ # define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG # undef SIZEOF_LONG_LONG #endif +#ifdef HALFWORD_HEAP_EMULATOR +# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR +# undef HALFWORD_HEAP_EMULATOR +#endif #include "erl_int_sizes_config.h" #if defined(SIZEOF_CHAR_SAVED__) && SIZEOF_CHAR_SAVED__ != SIZEOF_CHAR # error SIZEOF_CHAR mismatch @@ -65,6 +69,11 @@ # error SIZEOF_LONG_LONG mismatch #endif +/* This is OK to override by the NIF/driver implementor */ +#if defined(HALFWORD_HEAP_EMULATOR_SAVED__) && !defined(HALFWORD_HEAP_EMULATOR) +#define HALFWORD_HEAP_EMULATOR HALFWORD_HEAP_EMULATOR_SAVED__ +#endif + #include "erl_drv_nif.h" #include diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index f0c4d81f0b..41a9e17c86 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -512,9 +512,9 @@ int enif_get_int(ErlNifEnv* env, Eterm term, int* ip) int enif_get_uint(ErlNifEnv* env, Eterm term, unsigned* ip) { -#if SIZEOF_LONG == ERTS_SIZEOF_ETERM +#if SIZEOF_INT == ERTS_SIZEOF_ETERM return term_to_Uint(term, (Uint*)ip); -#elif SIZEOF_INT == ERTS_SIZEOF_ETERM +#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM Uint i; if (!term_to_Uint(term, &i) || i > UINT_MAX) { return 0; diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index 1ccf00293e..d0f6424724 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -34,7 +34,37 @@ #include +#ifdef SIZEOF_CHAR +# define SIZEOF_CHAR_SAVED__ SIZEOF_CHAR +# undef SIZEOF_CHAR +#endif +#ifdef SIZEOF_SHORT +# define SIZEOF_SHORT_SAVED__ SIZEOF_SHORT +# undef SIZEOF_SHORT +#endif +#ifdef SIZEOF_INT +# define SIZEOF_INT_SAVED__ SIZEOF_INT +# undef SIZEOF_INT +#endif +#ifdef SIZEOF_LONG +# define SIZEOF_LONG_SAVED__ SIZEOF_LONG +# undef SIZEOF_LONG +#endif +#ifdef SIZEOF_LONG_LONG +# define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG +# undef SIZEOF_LONG_LONG +#endif +#ifdef HALFWORD_HEAP_EMULATOR +# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR +# undef HALFWORD_HEAP_EMULATOR +#endif +#include "erl_int_sizes_config.h" + +#ifdef HALFWORD_HEAP_EMULATOR +typedef unsigned int ERL_NIF_TERM; +#else typedef unsigned long ERL_NIF_TERM; +#endif struct enif_environment_t; typedef struct enif_environment_t ErlNifEnv; diff --git a/erts/include/erl_int_sizes_config.h.in b/erts/include/erl_int_sizes_config.h.in index ef49995732..a8a264686e 100644 --- a/erts/include/erl_int_sizes_config.h.in +++ b/erts/include/erl_int_sizes_config.h.in @@ -31,3 +31,6 @@ /* The number of bytes in a long long. */ #undef SIZEOF_LONG_LONG + +/* Define if building a halfword-heap 64bit emulator (needed for NIF's) */ +#undef HALFWORD_HEAP_EMULATOR -- cgit v1.2.3 From 58bf309625bb2fc99a7689d3ce2dcb6de2a3a04c Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 26 Feb 2010 16:23:27 +0100 Subject: wx: Correct usage of driver callbacks from wx thread --- lib/wx/c_src/wxe_driver.c | 3 ++- lib/wx/c_src/wxe_driver.h | 1 + lib/wx/c_src/wxe_impl.cpp | 16 +++++++++++++--- lib/wx/c_src/wxe_impl.h | 5 +++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c index 3b951bec57..c927deb0ef 100644 --- a/lib/wx/c_src/wxe_driver.c +++ b/lib/wx/c_src/wxe_driver.c @@ -113,6 +113,7 @@ wxe_driver_start(ErlDrvPort port, char *buff) data->driver_data = NULL; data->bin = NULL; data->port = port; + data->pdl = driver_pdl_create(port); if(WXE_DRV_PORT == 0) { for(; *buff != 32; buff++); buff++; @@ -124,7 +125,7 @@ wxe_driver_start(ErlDrvPort port, char *buff) if(!(start_native_gui(data) == 1)) return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */ } else { - meta_command(CREATE_PORT,data); + meta_command(CREATE_PORT,data); } return (ErlDrvData) data; } diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h index 8437b4eb36..47a2a86e31 100644 --- a/lib/wx/c_src/wxe_driver.h +++ b/lib/wx/c_src/wxe_driver.h @@ -45,6 +45,7 @@ typedef struct wxe_data_def { WXEBinRef * bin; /* Argument binaries */ ErlDrvPort port; int is_cbport; + ErlDrvPDL pdl; } wxe_data; diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 4486dff63b..528a08e654 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -101,7 +101,7 @@ int start_native_gui(wxe_data *sd) init_caller = driver_connected(sd->port); if((res = erl_drv_thread_create((char *)"wxwidgets", - &wxe_thread,wxe_main_loop,NULL,NULL)) == 0) { + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL)) == 0) { erl_drv_mutex_lock(wxe_status_m); for(;wxe_status == WXE_NOT_INITIATED;) { erl_drv_cond_wait(wxe_status_c, wxe_status_m); @@ -179,12 +179,15 @@ void meta_command(int what, wxe_data *sd) { * wxWidgets Thread * ************************************************************/ -void *wxe_main_loop(void * not_used) +void *wxe_main_loop(void *vpdl) { int result; int argc = 1; char * temp = (char *) "Erlang\0"; char ** argv = &temp; + ErlDrvPDL pdl = (ErlDrvPDL) vpdl; + + driver_pdl_inc_refc(pdl); // ErlDrvSysInfo einfo; // driver_system_info(&einfo, sizeof(ErlDrvSysInfo)); @@ -199,6 +202,7 @@ void *wxe_main_loop(void * not_used) if(result >= 0 && wxe_status == WXE_INITIATED) { /* We are done try to make a clean exit */ wxe_status = WXE_EXITED; + driver_pdl_dec_refc(pdl); erl_drv_thread_exit(NULL); return NULL; } else { @@ -206,6 +210,7 @@ void *wxe_main_loop(void * not_used) wxe_status = WXE_ERROR; erl_drv_cond_signal(wxe_status_c); erl_drv_mutex_unlock(wxe_status_m); + driver_pdl_dec_refc(pdl); return NULL; } } @@ -401,11 +406,12 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) node = batch->GetFirst()) { wxeCommand *event = (wxeCommand *)node->GetData(); + wxeMemEnv *memenv = getMemEnv(event->port); batch->Erase(node); if(event->caller == process || // Callbacks from CB process only event->op == WXE_CB_START || // Recursive event callback allow // Allow connect_cb during CB i.e. msg from wxe_server. - event->caller == driver_connected(event->port)) + event->caller == memenv->owner) { switch(event->op) { case WXE_BATCH_END: @@ -456,6 +462,9 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) { wxeMemEnv * memenv = new wxeMemEnv(); + + driver_pdl_inc_refc(Ecmd.pdl); + for(int i = 0; i < global_me->next; i++) { memenv->ref2ptr[i] = global_me->ref2ptr[i]; } @@ -576,6 +585,7 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { // } // fflush(stderr); delete memenv; + driver_pdl_dec_refc(Ecmd.pdl); refmap.erase((ErlDrvTermData) Ecmd.port); } diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h index 5e9d596633..e6d5169cbc 100644 --- a/lib/wx/c_src/wxe_impl.h +++ b/lib/wx/c_src/wxe_impl.h @@ -34,15 +34,16 @@ class wxeMetaCommand : public wxEvent public: wxeMetaCommand(wxe_data *sd, int EvId) : wxEvent(EvId, wxeEVT_META_COMMAND) - { caller = driver_caller(sd->port); port = sd->port; } ; + { caller = driver_caller(sd->port); port = sd->port; pdl = sd->pdl; } ; wxeMetaCommand(const wxeMetaCommand& event) : wxEvent(event) - { caller = event.caller; port = event.port; }; + { caller = event.caller; port = event.port; pdl = event.pdl; }; virtual ~wxeMetaCommand() {}; virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); } ErlDrvTermData caller; ErlDrvPort port; + ErlDrvPDL pdl; }; class wxeCommand : public wxObject -- cgit v1.2.3 From 24095d93fb28bdd60abe771a426e39c6ff0f72c7 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 12 Mar 2010 16:09:26 +0100 Subject: Teach testcase in driver_suite the new prototype for driver_async The testcase core dunmped. Also made sure the key could actually store long integers in driver_async (which is more of a cosmetic change). --- erts/emulator/beam/erl_async.c | 2 +- erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c index ef9644c3d1..05b7d6a4fa 100644 --- a/erts/emulator/beam/erl_async.c +++ b/erts/emulator/beam/erl_async.c @@ -397,7 +397,7 @@ long driver_async(ErlDrvPort ix, unsigned long* key, ErlAsync* a = (ErlAsync*) erts_alloc(ERTS_ALC_T_ASYNC, sizeof(ErlAsync)); Port* prt = erts_drvport2port(ix); long id; - unsigned int qix; + unsigned long qix; if (!prt) diff --git a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c index f429a5b51e..2ac86b1ec2 100644 --- a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c +++ b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c @@ -127,7 +127,7 @@ static int control(ErlDrvData drv_data, char **rbuf, int rlen) { PeekNonXQDrvData *dp = (PeekNonXQDrvData *) drv_data; - unsigned int key = 0; + unsigned long key = 0; char *res_str = "ok"; ErlDrvSysInfo si; driver_system_info(&si, sizeof(ErlDrvSysInfo)); -- cgit v1.2.3