diff options
author | John Högberg <john@erlang.org> | 2022-02-22 19:11:54 +0100 |
---|---|---|
committer | John Högberg <john@erlang.org> | 2022-02-23 11:59:00 +0100 |
commit | 4fcc888356136c457063f48255281fab43d57bbf (patch) | |
tree | 9fd502276c2c635b49255161669eb696c293a4cb | |
parent | a891d232053953284c8fbba5e8914f410fbd5389 (diff) | |
download | erlang-4fcc888356136c457063f48255281fab43d57bbf.tar.gz |
erts: Minor loader optimizations and cleanup
This commit moves some validation from being done once per
operation (in all builds) to being done once on startup in
debug mode.
We also take the opportunity to remove some ancient cruft like
special error handling on unicode character operands, which we
planned on having at some point but never added.
-rw-r--r-- | erts/emulator/beam/beam_file.c | 15 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.c | 31 |
2 files changed, 21 insertions, 25 deletions
diff --git a/erts/emulator/beam/beam_file.c b/erts/emulator/beam/beam_file.c index 3caece384a..2329b200ae 100644 --- a/erts/emulator/beam/beam_file.c +++ b/erts/emulator/beam/beam_file.c @@ -1485,8 +1485,7 @@ static int beamcodereader_read_next(BeamCodeReader *code_reader, BeamOp **out) { reader = &code_reader->reader; LoadAssert(beamreader_read_u8(reader, &opcode)); - LoadAssert(opcode <= MAX_GENERIC_OPCODE); - LoadAssert(gen_opc[opcode].name[0] != '\0'); + LoadAssert(opcode > 0 && opcode <= MAX_GENERIC_OPCODE); arity = gen_opc[opcode].arity; ASSERT(arity <= ERTS_BEAM_MAX_OPARGS); @@ -1526,12 +1525,6 @@ static int beamcodereader_read_next(BeamCodeReader *code_reader, BeamOp **out) { case TAG_i: LoadAssert(marshal_integer(code_reader, &raw_arg)); break; - case TAG_h: - /* Character, must be a valid unicode code point. */ - LoadAssert(raw_arg.word_value <= 0x10FFFF && - (raw_arg.word_value < 0xD800 || - raw_arg.word_value > 0xDFFFUL)); - break; case TAG_x: case TAG_y: LoadAssert(raw_arg.word_value < MAX_REG); @@ -1629,8 +1622,10 @@ static int beamcodereader_read_next(BeamCodeReader *code_reader, BeamOp **out) { LoadAssert(index.tag == TAG_u); types = &(code_reader->file)->types; - /* If we use the fallback, then there was not type chunk - and thus we should not load any type information */ + + /* We may land here without a table if it was stripped + * after compilation, in which case we want to treat these + * as ordinary registers. */ if (!types->fallback) { LoadAssert(index.word_value < types->count); diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index dd7422b6cd..9b7a229d1c 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -56,6 +56,20 @@ void init_load(void) erts_total_code_size = 0; beam_catches_init(); erts_init_ranges(); + +#ifdef DEBUG + { + int i; + + for (i = 1; i < num_instructions; i++) { + const GenOpEntry *op = &gen_opc[i]; + + ASSERT(op->name && op->name[0] != '\0'); + ASSERT(op->arity <= ERTS_BEAM_MAX_OPARGS); + ASSERT(op->num_specific <= 1 || op->arity <= 6); + } + } +#endif } Binary *erts_alloc_loader_state(void) { @@ -459,14 +473,10 @@ static int load_code(LoaderState* stp) * the possible specific instructions associated with this * specific instruction. */ - Uint32 mask[3] = {0, 0, 0}; - int specific, arity, arg, i; + Uint32 mask[3] = {0, 0, 0}; arity = gen_opc[tmp_op->op].arity; - if (arity > 6) { - BeamLoadError0(stp, "no specific operation found (arity > 6)"); - } for (arg = 0; arg < arity; arg++) { int type = tmp_op->a[arg].type; @@ -530,17 +540,8 @@ static int load_code(LoaderState* stp) /* * No specific operation found. */ - if (i == num_specific) { + if (ERTS_UNLIKELY(i == num_specific)) { stp->specific_op = -1; - for (arg = 0; arg < tmp_op->arity; arg++) { - /* - * We'll give the error message here (instead of earlier) - * to get a printout of the offending operation. - */ - if (tmp_op->a[arg].type == TAG_h) { - BeamLoadError0(stp, "the character data type is not supported"); - } - } /* * No specific operations and no transformations means that |