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/erl_process.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'erts/emulator/beam/erl_process.h') 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 */ -- 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. --- erts/emulator/beam/erl_process.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'erts/emulator/beam/erl_process.h') 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; } } -- 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/erl_process.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'erts/emulator/beam/erl_process.h') 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 */ /* -- 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/emulator/beam/erl_process.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'erts/emulator/beam/erl_process.h') 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)) -- cgit v1.2.3