diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index b01d187b01a1..73d15c33d723 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -798,6 +798,11 @@ Valid range is 4-8192 kilowords. The default stack size is OS dependent.

+ + + +

Set the maximum number of atoms the VM can handle. Default is 1048576.

+
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c index dfc3cde6a7a3..3a231206aec6 100644 --- a/erts/emulator/beam/atom.c +++ b/erts/emulator/beam/atom.c @@ -322,7 +322,7 @@ init_atom_table(void) text_list = NULL; erts_index_init(ERTS_ALC_T_ATOM_TABLE, &erts_atom_table, - "atom_tab", ATOM_SIZE, ATOM_LIMIT, f); + "atom_tab", ATOM_SIZE, erts_atom_table_size, f); more_atom_space(); /* Ordinary atoms */ diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h index e7e0dc440d95..c10218e43118 100644 --- a/erts/emulator/beam/atom.h +++ b/erts/emulator/beam/atom.h @@ -28,6 +28,17 @@ #define MAX_ATOM_LENGTH 255 #define ATOM_LIMIT (1024*1024) +#define MIN_ATOM_TABLE_SIZE 8192 + +#ifndef ARCH_32 +/* Internal atom cache needs MAX_ATOM_TABLE_SIZE to be less than an + unsigned 32 bit integer. See external.c(erts_encode_ext_dist_header_setup) + for more details. */ +#define MAX_ATOM_TABLE_SIZE ((MAX_ATOM_INDEX + 1 < (1UL << 32)) ? MAX_ATOM_INDEX + 1 : (1UL << 32)) +#else +#define MAX_ATOM_TABLE_SIZE (MAX_ATOM_INDEX + 1) +#endif + /* * Atom entry. diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index bdf888eaff25..17cf3b9597d0 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -119,6 +119,8 @@ int erts_disable_tolerant_timeofday; /* Time correction can be disabled it is * not and/or it is too slow. */ +int erts_atom_table_size = ATOM_LIMIT; /* Maximum number of atoms */ + int erts_modified_timing_level; int erts_no_crash_dump = 0; /* Use -d to suppress crash dump. */ @@ -569,6 +571,10 @@ void erts_usage(void) erts_fprintf(stderr, " schedulers online (n2), valid range for both\n"); erts_fprintf(stderr, " numbers are [1-%d]\n", ERTS_MAX_NO_OF_SCHEDULERS); + erts_fprintf(stderr, "-t size set the maximum number of atoms the " + "emulator can handle\n"); + erts_fprintf(stderr, " valid range is [%d-%d]\n", + MIN_ATOM_TABLE_SIZE, MAX_ATOM_TABLE_SIZE); erts_fprintf(stderr, "-T number set modified timing level,\n"); erts_fprintf(stderr, " valid range is [0-%d]\n", ERTS_MODIFIED_TIMING_LEVELS-1); @@ -1140,6 +1146,22 @@ erl_start(int argc, char **argv) } break; } + case 't': + /* set atom table size */ + arg = get_arg(argv[i]+2, argv[i+1], &i); + errno = 0; + erts_atom_table_size = strtol(arg, NULL, 10); + if (errno != 0 || + erts_atom_table_size < MIN_ATOM_TABLE_SIZE || + erts_atom_table_size > MAX_ATOM_TABLE_SIZE) { + erts_fprintf(stderr, "bad atom table size %s\n", arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, + ("setting maximum number of atoms to %d\n", + erts_atom_table_size)); + break; + case 'T' : arg = get_arg(argv[i]+2, argv[i+1], &i); errno = 0; diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h index 5b0d3c2bfa90..50b3e5b61c85 100644 --- a/erts/emulator/beam/erl_vm.h +++ b/erts/emulator/beam/erl_vm.h @@ -181,6 +181,8 @@ extern int num_instructions; /* Number of instruction in opc[]. */ extern int H_MIN_SIZE; /* minimum (heap + stack) */ extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */ +extern int erts_atom_table_size;/* Atom table size */ + #define ORIG_CREATION 0 /* macros for extracting bytes from uint16's */ diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 24887b3dea95..b011d4c0de1b 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -271,11 +271,8 @@ erts_encode_ext_dist_header_size(ErtsAtomCacheMap *acmp) byte *erts_encode_ext_dist_header_setup(byte *ctl_ext, ErtsAtomCacheMap *acmp) { -#ifndef ARCH_32 -#if ATOM_LIMIT >= (1UL << 32) -#error "ATOM_LIMIT too large for interal atom cache update instructions. New instructions needed." -#endif -#endif + /* Maximum number of atom must be less than the maximum of a 32 bits + unsigned integer. Check is done in erl_init.c, erl_start function. */ if (!acmp) return ctl_ext; else { diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 0ad26aeea7df..f79f5cc978fd 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -794,6 +794,7 @@ int main(int argc, char **argv) case 'i': case 'P': case 'S': + case 't': case 'T': case 'R': case 'W':